您的位置:首页 > 其它

多态的成员(变量、方法)访问特点【非静态】

2016-07-16 23:42 411 查看
多态的定义:指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就是函数调用)

多态存在的3个必要条件

1.要有继承;

2.要有方法的重写;

3.父类引用指向子类对象;

示例代码:

class  Polymorphic_Demo{
public static void main(String[] args) {
Cat c = new Cat();    //*********(1)
System.out.println(c.leg);
c.eat();

Animal a = new Cat(); //*********(2)
System.out.println(a.leg);
a.eat();

}
}

class Animal {
int leg = 2;
public void eat(){
System.out.println("动物吃东西");
}
}

class Cat extends Animal {
int leg = 4;
public void eat(){
System.out.println("猫吃鱼");
}
}


Cat c = new Cat()————这句代码仅仅是继承关系,不存在多态特性;

Animal a = new Cat()——-这句代码就展示了一种多态特性,猫是动物的一种表现形态;

输出结果:



分析一下:

变量输出:对象(1)输出leg为:4;对象(2)输出leg为:2;

方法输出:对象(1)输出leg为:猫吃鱼;对象(2)输出leg为:猫吃鱼;

这里就会疑惑了,为什么变量输出和方法输出的方式不太一样呢?

看一下main方法

public static void main(String[] args) {
Cat c = new Cat();    //*********(1)
System.out.println(c.leg);
c.eat();

Animal a = new Cat(); //*********(2)
System.out.println(a.leg);
a.eat();

}


解释下类中main方法的执行过程:

Polymorphic_Demo.class加载->main方法进栈->Animal.class加载->Cat.class加载-> 声明一个Cat类型变量c->创建Cat对象->输出c.leg变量4->执行Cat对象中的eat()方法->输出“猫吃鱼”—>创建Animal类变量a->创建Cat对象(且变量a指向此对象)->输出a.leg变量2

对象是Cat类变量,为什么输出leg却是Cat的父类Animal中的leg值呢?

因为在堆中创建子类对象时,其内部是这样的



在子类对象中有一块区域是super区域,存放继承父类的变量和方法,容易理解,变量a的类型是Animal类型,因此a.leg可以看做是super.leg,所以输出就是Animal.leg变量,即2。

下面接着执行->执行Cat对象中的eat()方法->输出“猫吃鱼”

这里又出现疑问了,按照上面对变量的讲解,不是应该输出父类方法中的内容吗?为什么这里输出子类方法中的内容呢?

下面就出现了一个名词:动态绑定(Dynamic Binding)

什么是动态绑定?在JVM执行到方法时,会根据这个方法所属变量类型标识符找到该方法的全限定名(包名+类名),这里所属变量类型是父类,但是只知道所属变量类型还不能够的,因为无法确定方法的具体位置(非静态方法肯定是在堆中),就无法压到栈中执行,因此必须根据父类变量创建的实际对象确定方法的具体位置(在堆中寻找),这种在程序执行过程中,通过动态创建的方法表来定位方法的方式,称为动态绑定
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: