社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
序言:
不知道大家是否有这样的思考:在java面向对象的语言的开发过程中,子类是如何继承调用到父类的方法的?
1.示例
Animal 动物父类
@author 李娜
@version 0.0.1
@since 0.0.1 2019-09-19
*/
public abstract class Animal{
protected String firstName;
protected String lastName;
protected Integer count=1;
private String name;
public void setCount(Integer count) {
this.count = count;
if(count<3){
this.count=3;
}
if(count>5){
this.count=5;
}
}
public Integer getCount() {
return count;
}
public Animal() {
}
public Animal(String name) {
this.name = name;
System.out.println(this.name);
}
public Animal(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public void animalShout(){
for (Integer i = 0; i < count; i++) {
System.out.println("我的名字叫:"+firstName+lastName+ shout());
}
}
public abstract String shout();
}
Bird子类
package animal;
/**
@author 李娜
@version 0.0.1
@s extends Animalince 0.0.1 2019-09-20
*/
public class Bird extends Animal {
public Bird() {
super();
}
public Bird(String name) {
super(name);
}
@Override
public String shout() {
return "布谷布谷";
}
public Bird(String firstName, String lastName) {
super(firstName, lastName);
}
}
Test 测试类
/**
@author 李娜
@version 0.0.1
@since 0.0.1 2019-09-18
*/
public class Test {
public static void main(String[] args) {
Animal animal=new Bird();
animal.animalShout();
animal.shout();
}
}
具体想知道类的继承原理,我们需要从类的加载开始。
2.类加载
类加载过程包括:
加载:根据类名称获取二进制字节流,转化成方法区数据结构,并在堆中生成类class对象
验证:验证是否安全
准备:为静态变量在方法区分配内存
解析:把符号引用转化成直接引用
初始化:一般在new对象的时候会触发初始化,并为静态变量附上真实的值。
上面也说明了:类加载后会在方法区存放该类的信息,创建对象时,创建出一个对象存放到方法区,并在栈中有指向该对象的引用,堆中每个对象除了保存类的实例变量之外,还保存着实际类信息的引用,如下图所示:
3.方法调用
我们先来看animal.animalShout();这句代码的执行过程是:
查看animal的对象类型,找到Cat类型,在Cat类型中找animalShout方法,发现没有,到父类中寻找
在父类Base中找到了方法animalShout,开始执行animalShout方法
在animalShout方法中发现调用了shout方法,就从Cat类型开始寻找shout方法
在Child类型中找到了shout()方法,执行Cat中的shout()方法,执行完后返回animalShout方法
继续执行action方法,输出打印信息
寻找要执行的实例方法的时候,是从对象的实际类型信息开始查找的,找不到的时候,再查找父类类型信息。
如果继承的层次比较深,那么如果调用的存在最底层的父类,则调用的效率是比较低的,所以系统使用一种称为虚方法表的方法来优化调动的效率。
所谓虚方法表,就是在类加载的时候,为每个类创建一个表,这个表包括该类的对象所有动态绑定的方法及其地址,包括父类的方法,但一个方法只有一条记录,子类重写了父类方法后只会保留子类的。
参考:
继承实现的基本原理
java类的加载机制
这些都离不开Jvm原理哦!
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!