继承

java中的继承,最通俗的来说是为了使用父类中的属性或者是方法,来作为公用的API。

子类需要什么就来重写什么方法。

我觉得从两个方向来解释继承。第一个是属性,第二点是方法。

public class Animal {
    private Integer id;
    private String name;

    public Animal() {
        System.out.println("Animal需要先被初始化");
    }

    public Animal(Integer id, String name) {
        this.id = id;
        this.name = name;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Animal{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

子类继承父类:

public class Cat extends Animal{
    private String address;

    public Cat(String address) {
        this.address = address;
    }
}    

不过从这里也可以看到,子类继承父类之后,如果子类中还有对应的属性,那么在声明构造函数的时候,只有两个选择,要么使用当前类的属性作为参数,要么使用父类中的全参+子类参数作为构造,即如下所示:

public class Cat extends Animal{
    private String address;

    public Cat() {
        System.out.println("父类初始化完成之后,我Cat再进行初始化...............");
    }

    public Cat(String address) {
        this.address = address;
    }

    public Cat(Integer id, String name, String address) {
        super(id, name);
        this.address = address;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "Cat{" +
                "address='" + address + '\'' +
                '}';
    }
}

为什么?因为子类在创建对象的时候,肯定会先去初始化父类,初始化父类的什么?当前是一些必要的属性信息。比如说上面的第二个有参构造方法,首先去初始化父类的id和name属性,然后再去初始化当前类中的address。那么当前cat对象就相当于可以使用三个属性:id,name和address。而作为子类共有的属性:id和name,这里我们通常在创建对象的时候会指定对应的值。

那么为什么子类有了一个有参构造之后(也就是第一个),没有无参构造方法呢?

因为如果是无参构造方法存在,那么就意味着无参构造方法第一行的super()会去访问到父类中的无参构造方法。那么也就意味着需要父类中需要提供对应的无参构造方法来对父类中的属性进行初始化操作。

初始化父类的作用为了让子类去使用父类中的属性

构造初始化:一定要记住存在super();我们也可以在super(参数)中指定去访问哪个构造方法

如上面演示的:

// 访问父类无参构造
super();
// 访问父类有参构造
super(id,name);

首先去访问父类的构造,父类的访问完成之后,再去访问子类的。这里是一种递归方式。抽象类也需要去访问子类

演示一下:

public abstract class AbstractAnimal {
    public AbstractAnimal(){
        System.out.println("AbstractAnimal需要被初始化............");
    }
}

然后让Animal来进行继承:

public class Animal extends AbstractAnimal{}

查看控制台输出语句即可。

其实super的使用方式不止这一种方式,还可以用来访问父类中的方法和属性,当然是有前提的,不能够是私有的。

关于this和super的使用:this代表的是当前对象的引用,谁来调用,this就代表的是谁;super是父类空间的引用,不可以理解成对象。

为什么?因为对象可以被单独打印,而super不可以。因为不是对象

再有一点比较注重的就是方法重写:

重写有几点需要注意的:

0、前提:要有继承或者是实现关系;不过在继承体系中,所有类都继承于Object类,所以可以重写Object类中的方法。

1、方法名称、方法参数一定要保持一致;(与返回值类型无关)

2、返回值类型子类可以比父类大;(多态)

3、声明示异常不可以比父类的要大;(不管是编译型还是运行时,抓不住这个异常)

4、权限修饰符可以大于等于父类权限修饰符;(如果比父类中的要小,可能去访问父类中的去了)

posted @ 2022-01-13 00:27  雩娄的木子  阅读(35)  评论(0编辑  收藏  举报