继承
继承的简单介绍
继承可以解决代码复用,让我们的编程更加靠近人类思维。当多个类存在相同的属性(变量)和方法时,可以从这些类中抽象出父类,在父类中定义这些相同的属性和方法,所有的子类不需要重新定义这些属性和方法,只需要通过extends来声明继承父类即可
继承原理图:
继承的基本语法
使用细节
1.子类继承了所有的属性和方法,非私有的属性和方法可以在子类直接访问,但是私有属性和方法不能在子类直接访问,要通过公共的方法访问
2.子类必须调用父类的构造器,完成父类的初始化;
public class Sub extends Base{
//Sub()是子类构造器
public Sub(){
//super();默认调用父类的无参构造器,super();自动隐藏了
}
}
3.默认都是先去调用父类的构造器然后才回到子类调用子类构造器!
//父类Base
public class Base{
public int age;
public String name;
//无参构造器,隐藏的无参构造器被有参构造器给覆盖了,要写出来才不会报错
//public Base(){
//}
//有参构造器
public Base(String name, int age){
}
}
//子类Sub
public class Sub extends Base{
public Sub(){
//原本是默认调用父类的无参构造器,隐藏代码super();现在父类无参构造器被覆盖了,只能告诉编译器你调用的是哪个父类构造器,如下:
super("jason",20);
}
}
4.如果希望指定去调用父类的某个构造器,则显式的调用一下:super(参数列表)
//父类Base
public class Base{
public int age;
public String name;
//无参构造器,被有参构造器给覆盖了,要写出来才不会报错
public Base(){
}
//有参构造器1
public Base(String name, int age){
}
//有参构造器2
public Base(String name){
}
}
//子类Sub
public class Sub extends Base{
public Sub1(String name,int age){
//调用父类的无参构造器
super();//显式的调用一下,或者什么都不写
}
public Sub2(String name,int age){
super("jason",20); //调用有参构造器1
}
public Sub3(String name,int age){
super("jack");//调用有参构造器2
}
}
5.super在使用时,一定要写在子类构造器的第一行(super只能在构造器中使用)
6.super()和this()只能二选一,这两个方法不能共存在一个构造器,而且也都只能放在构造器的第一行
7.Java所有类都是Object类的子类,Object是所有类的基类(IDEA里面Ctrl+H可以看到继承树)
8.父类构造器的调用不限于直接父类!将一直往上追溯直到Object类(祖宗类)
9.子类最多只能继承一个父类(指直接继承),即Java中是单继承机制
10.不能滥用继承,子类和父类之间必须满足is-a(是一个)的逻辑关系
比如:
合理:学生是人,狗是动物
不合理:狗是音乐,王生是帅哥
继承的本质(重要)
public class ExtendsThehory {
//继承的本质
public static void main(String[] args) {
Son son = new Son();//内存的布局
System.out.println(son.name);
//输出哪个name? 要按照查找关系来返回信息
//(1)首先看子类是否有该属性
//(2)如果子类有这个属性,并且可以访问,则放回信息
//(3)如果子类没有这个属性,就看父类有没有这个属性(如果父类有该属性,并且可以访问,就放回信息..)
//(4)如果父类没有就按照(3)的规则,继续找上级父类,直到Object...
System.out.println(son.name);//返回的就是大头儿子
System.out.println(son.age);//返回的是父类里的age,也就是39
//System.out.println(son.getAge());
System.out.println(son.hobby);//返回的是爷类里的hobby,也就是"旅游"
}
}
class GrandPa{ //爷类
String name = "大头爷爷";
String hobby = "旅游";
//public int age; 就算爷爷这里有个公有的age,son.age也访问不到,因为查找到了父类遇到了private的age之后就停止查找了,不会再往上查找
}
class Father extends GrandPa{//父类
String name = "大头爸爸";
int age = 39;
//private int age = 39; 把age改成private后,在内存里son对象所在的堆区还是有age这个属性,只不过访问不了,可以写个get()方法去访问
/* public int getAge(){
return age;
}*/
}
class Son extends Father{ //子类
String name = "大头儿子";
}
如果Father里的age是private,即使GrandPa里也有age,是public,访问age的时候一样到Father就会停止,不会继续查看GrandPa里是否有age。
以上是看韩顺平老师的Java课程做的随笔笔记
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/289641.html