继承是Java的面向对象特性之一,继承这一特性是我们能做到代码复用以及设计分离的重要原因之一。讲到继承,我们很容易想到父子关系,在Java中被继承的类叫做父类(基类),继承了父类的类叫做子类。在Java中Object类是所有类的基类。为什么要有一个类作为所有类的基类?这是因为万物皆有源头,就像说女娲造人一样。

在Java中继承使用的是extends关键字:

public class Demo1 extends Demo{
    
    public static void main(String[] args) {

    }
}

为什么声明Demo类的时候不用extends呢?不是说任何类都继承了Object类吗?

public class Demo {
    
}

其实在Java中是默认自动继承Object类的,写不写extends Object都可以。

使用extends就可以继承一个类了,那一个类可以继承多少个类呢?答案是一个,Java是单继承的。不是说所有类的基类都是Object吗?Demo1不应该是即继承了Demo也继承了Object吗?Demo1确实继承了Object类的方法,但是却不是直接通过Object类传下来的,而是通过Demo类获得的。就像你爷爷,你父亲和你一样,你身上确实有你爷爷的基因,但它实际上是从你父亲身上传下来的。Java是不支持多继承(通过接口实现),但Java是支持多重继承的(A继承B,B继承C,如祖孙三代)。

子类能够继承父类的属性和方法,那构造器呢?子类是无法继承父类构造器的,因为父类构造器是用来创建父类对象的,如果子类能够继承父类构造器,那不乱套了吗?那子类可以继承父类用private修饰的属性和方法吗?子类是能够继承到父类的private属性和方法的。

public class Demo {
    private int a;

    public Demo() {
        System.out.println("父类构造方法");
    }

    private void print() {
        System.out.println("a = " + a);
    }
}
public class Demo1 extends Demo {

    public static void main(String[] args) {
        Demo1 demo = new Demo1();//父类构造方法
    }
}

上例的程序打印"父类构造方法"。原来在子类对象创建的时候回先调用父类的构造器,这是比较容易理解的,毕竟先有父母才有孩子。实际上在子类对象创建的过程中它会先创建父类的对象,然后在父类对象外部放入子类独有的属性和方法,形成一个子类的对象。也就是说,子类是继承到了父类的private属性和方法的,只是无法访问而已。

public class Demo {
    public int a;

    public Demo() {
        System.out.println("父类构造方法");
    }

    public void print() {
        System.out.println("a = " + a);
    }
}
public class Demo1 extends Demo {
    public int a = 10;

    public Demo1() {
        System.out.println("子类构造方法");
    }

    public void print() {
        System.out.println("a = " + a);
        System.out.println("super.a = " + super.a);
    }

    public static void main(String[] args) {

        Demo1 demo = new Demo1();//父类构造方法  子类构造方法
        demo.print();//10 0
        new Demo().print();//0
    }
}

子类可以定义父类同名的属性和方法,当满足重写规范时会被覆盖。

子类可以通过super关键字调用父类的属性,方法以及构造器:

public class Demo1 extends Demo {
    public Demo1() {
        super();
    }

    public void print() {
        super.print();
    }

    public static void main(String[] args) {

        Demo1 demo = new Demo1();//父类构造方法
        demo.print();//0
        new Demo().print();//父类构造方法 0
    }
}

和this()一样,super()在构造器中也只能放在第一行的位置。super()和this()不能同时出现。