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

来源:互联网 发布:vba提取网页数据 编辑:程序博客网 时间:2024/04/28 20:57

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


多态存在的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执行到方法时,会根据这个方法所属变量类型标识符找到该方法的全限定名(包名+类名),这里所属变量类型是父类,但是只知道所属变量类型还不能够的,因为无法确定方法的具体位置(非静态方法肯定是在堆中),就无法压到栈中执行,因此必须根据父类变量创建的实际对象确定方法的具体位置(在堆中寻找),这种在程序执行过程中,通过动态创建的方法表来定位方法的方式,称为动态绑定

1 0
原创粉丝点击