目录
目录
一、一个继承的代码案例
二、子类创建的内存布局
三、查找顺序
一、son.name的输出结果
二、son.age的输出结果
三、son.hobby的输出结果
package com.hspedu.entends_;/*** 讲解继承的本质*/
public class ExtendsTheory {public static void main(String[] args) {Son son = new Son();//内存的布局 }
}class GrandPa {//爷爷类String name = "大头爷爷";String hobby = "旅游";int age = 63;
}class Father extends GrandPa {//父类//父类和子类的属性name名字相同String name = "大头爸爸";int age = 39;}class Son extends Father {//子类String name = "大头儿子";}
上述代码的内存图
访问顺序:Son---->Father---->GrandPa---->Object
一个对象中可以有同名的属性,不会冲突
package com.hspedu.entends_;/*** 讲解继承的本质*/
public class ExtendsTheory {public static void main(String[] args) {Son son = new Son();//内存的布局System.out.println(son.name);//访问同包不同类的默认修饰符修饰的方法:√}
}class GrandPa {//爷爷类String name = "大头爷爷";String hobby = "旅游";
}class Father extends GrandPa {//父类//父类和子类的属性name名字相同String name = "大头爸爸";int age = 39;}class Son extends Father {//子类String name = "大头儿子";}
查找规则:
按照查找关系来返回信息
(1)首先看子类是否有该属性
(2)如果子类有这个属性,并且可以访问,则返回信息
(3)如果子类没有这个属性,就看父类有没有这个属性(如果父类有该属性,并且可以访问,就返回信息...,如果不能访问,就在父类里创建public方法,返回属性信息,然后调用该方法)
(4)如果父类没有就按照(3)的规则,继续找上级父类,知道Objcet
按照以上规则:输出“大头儿子”
package com.hspedu.entends_;/*** 讲解继承的本质*/
public class ExtendsTheory {public static void main(String[] args) {Son son = new Son();//内存的布局System.out.println(son.name);//访问同包不同类的默认修饰符修饰的方法:√System.out.println(son.age);//Son类没有age,向上查找,输出39}
}class GrandPa {//爷爷类String name = "大头爷爷";String hobby = "旅游";
}class Father extends GrandPa {//父类//父类和子类的属性name名字相同String name = "大头爸爸";int age = 39;}class Son extends Father {//子类String name = "大头儿子";}
分析:由于子类Son没有age这个属性,所以向上查找,在父类Father里面找到并输出“39”
假设:int age = 39;的属性改成private,就无法直接访问,
'age' has private access in 'com.hspedu.entends_.Father'
解决方法: 结合继承细节的第一条知识,在Father创建public方法,然后在main方法中调用该方法
package com.hspedu.entends_;/*** 讲解继承的本质*/
public class ExtendsTheory {public static void main(String[] args) {Son son = new Son();System.out.println(son.name);System.out.println(son.getAge());}
}class GrandPa {//爷爷类String name = "大头爷爷";String hobby = "旅游";int age = 63;
}class Father extends GrandPa {//父类//父类和子类的属性name名字相同String name = "大头爸爸";private int age = 39;public int getAge() {return age;}
}class Son extends Father {//子类String name = "大头儿子";}
运行结果
tips:如果GrandPa类和Father类中都有age这个属性,但是Father类中的属性是private, GrandPa类中的属性是默认,系统还是会报错,不会跳过Father去查找GrandPa
package com.hspedu.entends_;/*** 讲解继承的本质*/
public class ExtendsTheory {public static void main(String[] args) {Son son = new Son();//内存的布局System.out.println(son.name);//访问同包不同类的默认修饰符修饰的方法:√System.out.println(son.age);//Son类没有age,向上查找,输出39}
}class GrandPa {//爷爷类String name = "大头爷爷";String hobby = "旅游";int age = 63;
}class Father extends GrandPa {//父类//父类和子类的属性name名字相同String name = "大头爸爸";private int age = 39;}class Son extends Father {//子类String name = "大头儿子";}
IDEA提示:
还是要创建public方法,然后在main方法中调用
package com.hspedu.entends_;/*** 讲解继承的本质*/
public class ExtendsTheory {public static void main(String[] args) {Son son = new Son();//内存的布局System.out.println(son.name);//访问同包不同类的默认修饰符修饰的方法:√System.out.println(son.getAge());System.out.println(son.hobby);}
}class GrandPa {//爷爷类String name = "大头爷爷";String hobby = "旅游";int age = 63;
}class Father extends GrandPa {//父类//父类和子类的属性name名字相同String name = "大头爸爸";private int age = 39;public int getAge() {return age;}
}class Son extends Father {//子类String name = "大头儿子";}
Son类没有hobby,向上查找,Father类也没有,直到GrandPa,输出"旅游"