• 0

  • 0

Java三大特性之继承

1星期前

1. 继承的使用场景

  1. 共性抽取:父亲每天吃饭睡觉,生了两个儿子继承了父亲的这两点,也每天吃饭睡觉。

  2. 特性区分:父亲是个农民,每天的工作就是种地,两个儿子出人头地,一个当了老师,一个当了医生。

2. 继承的实现

通过extends关键字,即可实现两个类之间的继承关系

public class A {}
public class B extends A {}
复制代码

3. 继承中的成员变量访问

// 父类
public class Employee {
    int num = 10;
    int age = 100;
}

// 子类
public class Student extends Employee {
    int num = 20;
}

// 测试
public class FieldVarTest {
    public static void main(String[] args) {
        // 父类子类都有的同名成员变量
        Employee employee = new Student();
        Student student = new Student();
        System.out.println(employee.num); // 输出10
        System.out.println(student.num); // 输出20
        // 只有父类有的成员变量
        System.out.println(student.age); // 向父类取,输出100
    }
}
复制代码

当访问父类子类都有的同名成员变量时,取创建对象等号左边的类中定义的值;当通过子类对象访问的成员变量只存在于父类中时,向父类取值。

4. 继承中的构造方法访问

// 父类
public class Employee {

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

    public Employee(int num) {
        System.out.println("父类有参构造方法");
    }
}

// 子类构造方法
public class Student extends Employee {

    public Student() {
        // TO DO
        System.out.println("子类构造方法");
    }
}

// 测试
public class ExtendsConstructorTest(String[] args) {
    Student student = new Student();
    // TO DO处可能有三种情况
    // 1. 不写 -> 默认调用super()
    // 2. super() -> 调用super()
    // 3. super(10) -> 调用父类重载构造方法
}
复制代码

需要注意的是,父类构造方法必须是子类构造方法的第一句,如果未指定父类构造方法,则默认执行super(),如果指定了,则执行重载的父类构造方法,比如super(10)。

5. 继承中的成员方法重写

重写需要注意,子类中方法名和参数列表和父类相同;子类返回类型 <= 父类返回类型;子类权限 >= 父类权限。

// 父类
public class Employee {
    
    public void work() {
        System.out.println("我去上班了");
    }
}

// 子类
public class Student extends Employee {

    @Override
    public void work() {
        System.out.println("我去上学了");
    }
}

// 测试
public class SameNameVarTest {
    
    public static void main(String[] args) {
        Employee employee = new Student();
        employee.work(); // 输出"我去上学了"
    }
}
复制代码

上面是一个重写的示例,可以看出重写的目的是根据子类的特点,改变与父类同名方法的内容。当我们有多个子类时,则可以分别重写work方法,比如再新建一个子类Teacher,那么work的内容可以改变为System.out.println("我去上学了");。在本例中,还有一个值得注意的地方是Employee employee = new Student();,我们将父类变量指向子类对象,进行work方法调用的时候,调用的是子类的方法,而在前面将继承中变量访问的时候,访问的确实父类的变量。这其实就是Java的另一个特性,多态,这篇帖子生动的描述了什么是多态:https://www.zhihu.com/question/30082151/answer/120520568。

6. 继承中的super和this关键字

// 父类
public class Employee {
    
    int num = 10;

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

    public void work() {
        System.out.println("我去上班了");
    }
}

// 子类
public class Student extends Employee {

    int num = 20;

    public Student() {
        super(); // super用法一,在子类构造方法中通过super()访问父类构造方法
    }
    
    public Student(int id) {
        this(); // this用法一,在子类构造方法中通过this()访问重载构造方法
    }

    public void superTest() {
        System.out.println(super.num); // super用法二,在子类成员方法中通过super.num访问父类成员变量
		super.work(); // super用法三,在子类成员方法中通过super.work()访问父类成员方法
    }
    
    public void thisTest() {
        System.out.println(this.num); // this用法二,在子类成员方法中通过this.num访问子类成员变量
        this.work(); // this用法三,在子类成员方法中通过this.work()访问子类成员方法
    }
    
    public void work() {
        System.out.println("我去上学了");
    }
}

复制代码

在super和this关键字的使用时,需要注意子类构造方法中,super()this()都只能出现在构造方法的第一句,这也就意味着两者不能在一个构造方法中同时使用。

为了更清楚的解释super和this关键字,我们通过一段代码在运行时和内存的交互进行说明。

// 父类 (1)
public class Employee {
    
    int num = 10;
    
    public void work() {
        System.out.println("我去上班了");
    }
}

// 子类 (1)
public class Student extends Employee {

    int num = 20;
    
    public void getVariable() {
		System.out.println(super.num);
        System.out.println(this.num);

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

// 测试类 (1)
public class SuperThisTest {
    
    public static void main(String[] args) { // (2)
        Student stu = new Student(); // (3)
        stu.getVariable(); // (4)
        stu.work(); // (5)(6)
    }
}
复制代码

(1) 将父类,子类和测试类的.class文件保存到方法区,其中,子类中有一个super标志指向父类。

(2) 将main方法压栈,开始执行方法中的内容。

(3) 执行main方法中的创建Student对象的语句,将stu变量保存在栈中,然后先创建Employee对象,再在它的外部创建Student对象,对象中的方法指向方法区.class文件中的方法,栈中的stu变量指向堆中的new Student()对象。 (4) 执行main方法中的stu.getVariable();语句,将getVariable()方法压栈,执行方法中的内容,通过super.num找到Employee内容中的num,然后通过this.num找到Student内容中的num,getVariable()执行完毕,出栈。

(5) 执行main方法中的stu.work();语句,先找到Student对应的work()方法,并将其压栈,然后其中的语句super.work();,找到Employee对应的work()方法,并将其压栈。

(6) 执行Employee对应的work()方法中的语句System.out.println("我去上班了");,Employee对应的work()方法执行完毕,出栈;Student对应的work()方法执行完毕,出栈;main方法执行完毕,出栈。

7. 继承在Java中的特殊特性

(1) 一个类只可以有一个直接父类,也就是只支持单继承

(2) 父类也可以有自己的父类,也就是支持多级继承

(3) 一个父类可以有多个子类。

免责声明:文章版权归原作者所有,其内容与观点不代表Unitimes立场,亦不构成任何投资意见或建议。

java

0

相关文章推荐

未登录头像

暂无评论