Java学习笔记——继承

为什么需要继承extends

编写两个类,一个是pupil,一个是graduate,两个类有许多相似的属性,怎么办?

使用继承(代码复用)

示意图

在这里插入图片描述

细节

  • 子类继承了所有的属性和方法,私有属性不能在子类直接访问,要通过公共的方法去访问

父类

public class Base {
    private int n1 = 100;
    protected int n2 = 200;
    int n3 = 300;
    public int n4 = 400;
}

子类(无法访问n1)
在这里插入图片描述
子类只能通过父类提供的公共方法来访问

public class Base {
    private int n1 = 100;
    protected int n2 = 200;
    int n3 = 300;
    public int n4 = 400;

    public int getN1() {
        return n1;
    }
}
public class Sub extends Base{
    public int getn1(){
        return this.getN1();
        //return this.n1;
    }

    public int getn2(){
        return this.n2;
    }
}
  • 子类必须调用父类的构造器,完成父类的初始化
public class Base {
    private int n1 = 100;
    protected int n2 = 200;
    int n3 = 300;
    public int n4 = 400;

    public Base() {
        System.out.println("调用了父类构造器");
    }

    public int getN1() {
        return n1;
    }
}

public class Sub extends Base{
    public int getn1(){
        return this.getN1();
        //return this.n1;
    }

    public Sub() {
        System.out.println("调用了子类构造器");
    }

    public int getn2(){
        return this.n2;
    }
}
public class Test {
    public static void main(String[] args) {

        Sub sub = new Sub();
    }
}

结果

调用了父类构造器
调用了子类构造器

先调用的是父类,后调用的是子类,因为在子类的构造器中默认调用super(),即默认调用父类的构造器

  • 当创建子类对象的时候,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参构造器

子类

package extendsDemo;

public class Sub extends Base{
    public int getn1(){
        return this.getN1();
        //return this.n1;
    }

    public Sub() {
        System.out.println("调用了子类无参构造器");
    }

    public Sub(int n2,int n3,int n4){
        this.n2 = n2;
        this.n3 = n3;
        this.n4 = n4;
        System.out.println("调用了子类构造器,带有参数n2,n3,n4");
    }

    public Sub(int n2,int n3){
        this.n2 = n2;
        this.n3 = n3;
        System.out.println("调用了子类构造器,带有参数n2,n3");
    }

    public int getn2(){
        return this.n2;
    }
}

测试

public class Test {
    public static void main(String[] args) {

        Sub sub = new Sub(100,300,900);
    }
}

结果

调用了父类构造器
调用了子类构造器,带有参数n2,n3,n4

默认调用了父类构造器

  • 若父类没有提供无参构造器,则必须在子类的构造器中用super去指定使用父类的哪个构造器完成对父类的初始化工作,否则编译不通过
package extendsDemo;

public class Base {
    private int n1;
    protected int n2;
    int n3;
    public int n4;

//    public Base() {
//        System.out.println("调用了父类构造器");
//    }


    public Base(int n2, int n3, int n4) {
        this.n2 = n2;
        this.n3 = n3;
        this.n4 = n4;
    }

    public Base(int n2, int n3) {
        this.n2 = n2;
        this.n3 = n3;
    }

    public int getN1() {
        return n1;
    }
}

将父类改成不带无参构造器,则子类会报错
在这里插入图片描述
必须用super()指定用父类的哪个构造器
在这里插入图片描述

  • 如果希望指定去调用父类的某个构造器,则显示的调用一下
  • super()必须放在子类构造器的第一行,super只能在构造器中使用
  • super和this都只能放在构造器的第一行,因此这两个方法不能共存在一个构造器
  • Java所有的类都是object类的子类
    在这里插入图片描述
  • 父类构造器的调用不限于直接父类,可以一直往上追溯到Object类(顶级父类)

将继承关系改成如下图所示
在这里插入图片描述

public class Top {
    public Top() {
        System.out.println("调用了Top构造器");
    }
}
public class Base extends Top {
    private int n1;
    protected int n2;
    int n3;
    public int n4;

    public Base() {
        System.out.println("调用了父类构造器");
    }
}
public class Sub extends Base{
    public int getn1(){
        return this.getN1();
        //return this.n1;
    }

    public Sub() {
        System.out.println("调用了子类无参构造器");
    }
}
public class Test {
    public static void main(String[] args) {

        Sub sub = new Sub();
    }
}

结果

调用了Top构造器
调用了父类构造器
调用了子类无参构造器

  • 子类最多只能继承一个父类(直接继承),即单继承机制
  • 继承不可滥用,子类和父类之间必须满足is-a的逻辑关系
    student is a person
    teacher is a person

继承的本质

在这里插入图片描述

  1. 加载类,object,grandpa,father,son
  2. Son son = new Son();
    在这里插入图片描述
    System.out.println(son.name);
    a. 首先看子类是否有该属性
    b. 有,并且可以访问,则返回该信息
    c. 没有,则看其父类有没有这个属性,有,并且可以访问,则返回该信息,没有,则继续按照c的步骤继续
    所以 System.out.println(son.name);打印的是大头儿子
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值