返回顶部
扩大
缩小

Yeap

继承

这里我们定义一个Person的类:

class Person {
    private String name;
    private int age;

    public String getName() {...}
    public void setName(String name) {...}
    public int getAge() {...}
    public void setAge(int age) {...}
}

在定义一个Student类:

class Student {
    private String name;
    private int age;
    private int score;

    public String getName() {...}
    public void setName(String name) {...}
    public int getAge() {...}
    public void setAge(int age) {...}
    public int getScore() { … }
    public void setScore(int score) { … }
}

可以发现,这两个类中,有很多相同的字段和方法,那么我们可不可以在Sutdent类中不用再写相同的字段和方法,只写其特有的属性和方法呢?

当然可以! 但是,要用到java的 extends关键字,他表示继承。

class Person {
    private String name;
    private int age;

    public String getName() {...}
    public void setName(String name) {...}
    public int getAge() {...}
    public void setAge(int age) {...}
}

class Student extends Person {
    // 不要重复name和age字段/方法,
    // 只需要定义新增score字段/方法:
    private int score;

    public int getScore() { … }
    public void setScore(int score) { … }
}

这样我们就可以自写需要新增的代码。

注意:子类自动获得了父类的所有字段,严禁定义与父类重名的字段!

在OOP的术语中,我们把Person称为超类(super class)、父类(parent class)、基类(base class),把Student称为子类(subclass),扩展类(extended class)。

继承树

在编写父类,person的时候我们并没有,给person写extends。它同样会有一个继承关系,不过这个关系是java的机制中的默认继承关系,Java中默认Obect类为所有类的父类。

继承关系如下:

image-20201122170221575

java只允许一个class继承一个父类。也就是说在java中的所有继承关系都是单继承。一个类有且只有一个父类。object类是特例,它没有父类。

我们再定义一个别的类时,继承树如下:

image-20201122170529897

一个类可以被多个类继承,但是它只能继承一个父类。

继承中的字段修饰关系和普通的一样,有 private ,默认,protect和public。但是,继承中有个特点,就是子类无法访问父类的private字符或者private方法,

class Person {
    private String name; //私有化字段
    private int age; //私有化字段,不能被访问
}

class Student extends Person {
    public String hello() {
        return "Hello, " + name; // 编译错误:无法访问name字段
    }
}

这样一来 ,继承的作用就削弱了,如果要访问字段,我们可以将private,改成protect。被这个关键字修饰的字段可以被子类访问。

class Person {
    protected String name;
    protected int age;
}

class Student extends Person {
    public String hello() {
        return "Hello, " + name; // OK!
    }
}

super关键字

super关键字表示父类(超类)。子类引用父类的字段时,可以使用super.filedNama。

class Student extends Person {
    public String hello() {
        return "Hello, " + super.name;//这里可以不用spuer,用this.name 或则 name 也可以,编译器会自动定位到父类字段
    }
}

但是,以下的这个时候就必须要用 super关键字。

class Person {
    protected String name;
    protected int age;
	//定义个无参的构造方法
     //public Person() { }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

class Student extends Person {
    protected int score;
	//直接运行会报错,因为编译器会自动给子类添加一个  sper();  
    //  super();//但是父类并没有无参的构造方法,解决办法可以给父类添加一个无参的构造方法 或者 有suer(name,age);指定调用有参构造方法
    public Student(String name, int age, int score) {
        this.score = score;
    }
}
public class Main {
    public static void main(String[] args) {
        Student s = new Student("Xiao Ming", 12, 89);
    }
}
    

可以得出一个结论:如果父类没有默认的狗杂方法,子类就必须显示的调用super()并且给出参数以便让编译器定位到父类的一个合适的构造方法。

这里也可以看出,子类不会继承父类的任何狗杂方法,子类默认的构造方法是编译器自己生成的,不是继承的。

区分继承和组合

在使用继承时,我们要注意逻辑一致性。

class Book {
    protected String name;
    public String getName() {...}
    public void setName(String name) {...}
}

再写一个继承类、我们能不能让子类继承父类的 nama字段:

class Student extends Book {
    protected int score;
}

显然,从逻辑上讲,这是不合理的,Student不应该从Book继承,而应该从Person继承。

究其原因,是因为StudentPerson的一种,它们是is关系,而Student并不是Book。实际上StudentBook的关系是has关系。

具有has关系不应该使用继承,而是使用组合,即Student可以持有一个Book实例:

class Student extends Person {
    protected Book book;
    protected int score;
}

因此,继承是is关系,组合是has关系。

posted on 2020-11-22 17:42  YP泡泡  阅读(68)  评论(0)    收藏  举报

导航