10.1. Java中的继承

10.1.1. 调用父类的构造方法

代码示例

父类:Person.java

package com.a51work.cn;
import java.util.Date;

public class Person {
    // 名字
    private String name;
    // 年龄
    private int age;
    // 出生日期
    private Date birthDate;

    // 三个参数构造方法
    public Person(String name, int age, Date d) {
//  为了防止局部变量
//  与成员变量命名发生冲突,可以使用this调用成员变量
        this.name = name;
        this.age = age;
        birthDate = d;
        System.out.println(this.toString());
    }

    public Person(String name, int age) {
        // 调用三个参数构造方法
        this(name, age, null);
    }


    public String getinfo() {
        return "Person [name=" + name + ", age=" + age + ", birthDate=" + birthDate + "]";
    }

}

子类:Student.java

package com.a51work.cn;

import java.util.Date;

public class Student extends Person {
    //所在学校,私有的类变量
    private String school;

//    继承父类3个参数的构造函数
    public Student(String name, int age, Date d, String school) {
        super(name, age, d);
        this.school = school;
    }

//    继承父类2个参数的构造函数
    public Student(String name, int age, String school) {
        super(name, age);
        this.school = school;
    }

    public static void main(String[] args) {
        Student hu = new Student("胡建力",18,"西安电子科技大学");
        System.out.println(hu.getinfo());
        System.out.println("毕业学校: " + hu.school);
    }
}

关键知识点

当子类实例化时,不仅需要初始化子类成员变量,也需要初始化父类成员变量,初始化父类成员变量
需要调用父类构造方法,子类使用super关键字调用父类构造方法。



提示 一般情况下,一个子类只能继承一个父类,这称为“单继承”,但有的情况下一个子类可以
有多个不同的父类,这称为“多重继承”。在Java中,类的继承只能是单继承,而多重继承可以通
过实现多个接口实现。也就是说,在Java中,一个类只能继承一个父类,但是可以实现多个接口。

10.1.2. 成员变量隐藏和方法覆盖

成员变量隐藏

代码示例

Person.java

package com.a52work.cn;

public class Person {
    //    x成员变量
    int x = 5;

}

Student.java

package com.a52work.cn;

public class Student extends Person {
    // 屏蔽掉父类的x成员变量
    int x = 20;

    public void printX(){
//        访问子类的x成员
        System.out.println("x ==" + x);
//        访问父类的x成员
        System.out.println("super.x = " + super.x);
    }

    public static void main(String[] args) {
//        实例化类对象
        Student hu = new Student();
//        调用类成员方法
        hu.printX();
    }
}

/*
x ==20
super.x = 5
* */

方法的覆盖(Override)

代码示例 ParentClass.java

package FangfaOver01;

public class ParentClass {
 // x成员变量
 int x;

 protected void setValue() {
  x = 10;
 }
}

SubClass.java

package FangfaOver01;

public class SubClass extends ParentClass {
// 屏蔽父类x成员变量
 int x;

 @Override
 public void setValue() {
  // 覆盖父类的方法
  // 访问子类对象x成员变量
  x = 20;
  // 调用父类setValue()方法
  super.setValue();
 }

 public void print() {
//  访问子类成员变量
  System.out.println("x = "+ x);
//  访问父类成员变量
  System.out.println("super.x = " + super.x);

 }

 public static void main(String[] args) {
//  实例化SubClass子类
  SubClass p = new SubClass();
//  调用setValue方法
  p.setValue();
//  调用子类print方法
  p.print();
 }
}

/*
x = 20
super.x = 10
 *
 */

添加@Override注解有两个好处:

  1. 提高程序的可读性。
  2. 编译器检查@Override注解的方法在父类中是否存在,如果不存在则报错

注意 方法覆盖时应遵循的原则:

* 1. 覆盖后的方法不能比原方法有更严格的访问控制(可以相同)。例如访问控制public修改private,那么会发生编译错误,因为父类原方法是protected。


* 2. 覆盖后的方法不能比原方法产生更多的异常。