为什么多态的情况下,子父类存在同名的非静态函数的时候,默认是调用子类的成员函数.

fengxuanyuan2 2015-09-06 11:26:20
是怎么得到以下结论的
多态的情况下,子父类存在同名的成员变量时,默认访问的是父类的成员变量数据.
2.多态的情况下,子父类存在同名的非静态函数的时候,默认是调用子类的成员函数.
3.多态的情况下,子父类存在同名的静态函数时,默认是调用父类的成员函数.
.
...全文
642 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
detzero 2017-12-15
  • 打赏
  • 举报
回复
引用 1 楼 sxiaobei 的回复:
这其实就是java多态的实现,首先说成员变量,因为在java中,一个对象实例是存储在堆中的,而这个对象包含的内容有对象头,对象体以及对其字节,首先对象头存放的是对象运行时的数据,像是hashcode,锁标识,类型指针,那么对象体中存放的是对象的成员变量,成员变量包括从父类继承过的成员变量和本类的成员变量,那么如果父类和子类有重名的变量,那么这个时候就要看对象的静态类型是什么了,静态类型就是声明类型,如果声明类型是父类那么就直接选取父类的成员变量,如果声明类型是自己的类那么就选取本身类的成员变量,所以选取同名的成员变量的时候是根据静态类型来的。下面再看下成员方法的选取,方法其实是在方法区存放着一张虚表,虚表中存放着是方法的实际入口地址,在实际对象调用的时候虚表会做动态的改变,如果一个方法在子类中被重写了,而这时静态类型又是父类,那么就把虚表中被重写方法的实际入口地址,替换成被重写的方法的入口地址,所以在调用的时候是访问不到被重写的旧方法的。而静态方法直接就不能被重写,更别说调用被重写之后的方法,而且静态方法是属于类的,所以在调用的时候,直接调用的是本类的方法,与运行时对象是没关系的,希望我讲清楚了,也希望对你有帮助谢谢!
我去 比我们老师讲的还详细 受教了!
fengxuanyuan2 2015-09-27
  • 打赏
  • 举报
回复
,静态类型就是声明类型,如果声明类型是父类那么就直接选取父类的成员变量,如果声明类型是自己的类那么就选取本身类的成员变量[这话听 得不懂.]比如说 abstract class Animal { String name; static String color="动物颜色"; public Animal(String name){ this.name=name; } public static void sleep(){ System.out.println("动物在睡觉"); } public abstract void run(); } class Mouse extends Animal { static String color="老鼠颜色"; public Mouse(String name){ super(name); } public static void sleep(){ System.out.println("老鼠在睡觉"); } public void run(){ System.out.println(name+"四条腿走路"); } public void dig(){ System.out.println(name+"老鼠在挖洞"); } } 子类那个public static void sleep()的静态类型什么是什么?
ilmlife 2015-09-27
  • 打赏
  • 举报
回复
引用 楼主 fengxuanyuan2 的回复:
是怎么得到以下结论的 多态的情况下,子父类存在同名的成员变量时,默认访问的是父类的成员变量数据. 2.多态的情况下,子父类存在同名的非静态函数的时候,默认是调用子类的成员函数. 3.多态的情况下,子父类存在同名的静态函数时,默认是调用父类的成员函数. .
差不多是这么个意思,专业名次啥的不熟,你看着理解吧: 1.成员变量的由声明决定 A a = new B();都有属性x,x的值由声明的类型A决定 2.非静态函数由实例决定 A a = new B();都有方法test(),test的执行结果由真实实例B决定 3.静态方法属于类 不属于实例 静态方法调用属于class就是这么个意思
Yohhan_go 2015-09-27
  • 打赏
  • 举报
回复
多态就记住几个关键点吧: 编译时期,向上转型; 方法调用时,动态绑定; 由于静态字段和方法是随着类加载的,也就是静态加载,要早于对象。所以多态不成立
sxiaobei 2015-09-07
  • 打赏
  • 举报
回复
这其实就是java多态的实现,首先说成员变量,因为在java中,一个对象实例是存储在堆中的,而这个对象包含的内容有对象头,对象体以及对其字节,首先对象头存放的是对象运行时的数据,像是hashcode,锁标识,类型指针,那么对象体中存放的是对象的成员变量,成员变量包括从父类继承过的成员变量和本类的成员变量,那么如果父类和子类有重名的变量,那么这个时候就要看对象的静态类型是什么了,静态类型就是声明类型,如果声明类型是父类那么就直接选取父类的成员变量,如果声明类型是自己的类那么就选取本身类的成员变量,所以选取同名的成员变量的时候是根据静态类型来的。下面再看下成员方法的选取,方法其实是在方法区存放着一张虚表,虚表中存放着是方法的实际入口地址,在实际对象调用的时候虚表会做动态的改变,如果一个方法在子类中被重写了,而这时静态类型又是父类,那么就把虚表中被重写方法的实际入口地址,替换成被重写的方法的入口地址,所以在调用的时候是访问不到被重写的旧方法的。而静态方法直接就不能被重写,更别说调用被重写之后的方法,而且静态方法是属于类的,所以在调用的时候,直接调用的是本类的方法,与运行时对象是没关系的,希望我讲清楚了,也希望对你有帮助谢谢!

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧