java-day08-继承

8.5 继承-概述&特点

描述学生:
属性:姓名,年龄
行为:学习

public class Student {
    private String name;
    private int age;
    public void study(){
        System.out.println("study");
    }


    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}

描述工人:
属性:姓名,年龄
行为:工作

class Worker{
    private String name;
    private int age;
    public void work(){
        System.out.println("work");
    }
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}

测试代码:

class ExtendsDemo{
    public static void main(String[] args){
        Student s = new Student();
        s.setName("huanhuan"); 
        s.setAge(14);
        s.study();
    }
}

将学生和工人的共享代码抽取到一个共性的类型中,这个类型中包含学生和工人。

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

让学生和Person产生关系,就可以让学生使用Person中的共性的内容。通过一个关键字extends。

//Person类
class Person{
    private String name;
    private int age;

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

//Student类
public class Student extends Person{
    public void study(){
        System.out.println("study");
    }
}

//Worker类
class Worker extends Person{
    public void work(){
        System.out.println("work");
    }
}

class ExtendsDemo{
    public static void main(String[] args){
        Student s = new Student();
        s.setName("huanhuan");
        s.setAge(14);
        s.study();
    }
}

继承

  1. 提高代码的复用性。
  2. 让类与类之间产生了关系。为第三个特性多态提供了前提。

8.6 继承-单继承和多继承

Java支持单继承,不直接支持多继承。
单继承:一个类只有一个父类
多继承:一个类可以有多个父类。Java并不直接支持。优势:可以让子类具备更多的功能。弊端:会产生调用不确定性,因为方法的主体不同,Java对其进行改良。
多层次继承:继承体系。学习一个继承体系时,先看顶层,了解该体系中具备的功能。使用时,找体系最下面的对象。

8.7 继承-什么时候继承

什么时候继承?
当事物存在着所属(is-a)关系时,可以通过继承来体现这个关系。xxx是yyy中的一种,xxx extends yyy

8.8 继承-私有的访问

对于父类中私有的部分,子类对象是无法直接访问的。

8.9 继承-成员变量的特点

子父类出现后,代码上的一些特点:
1.成员变量。
2.成员函数。
3.构造函数。

成员变量,注意的是原理。
当本类中出现了成员变量和局部变量重名的时候,用this区分。
当子父类中出现了重复的成员变量,使用super来区分。

8.10 继承-super关键字

super和this的用法很相似。
this:代表的是本类的对象的引用。
super:代表示父类的那一片空间。

8.10 继承-成员函数的特点-覆盖

子父类中的方法的特点:
特殊情况:当子父类中出现一模一样的方法时,子类对象运行的是子类的方法。这种特殊的情况称之为覆盖(override,复写,重写)。
重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。
**覆盖(重写)**是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值、函数名和形参都一样。

class Fu{
    void show(){
        System.out.println("fu");
    }
}

class Zi{
    void show(){
        System.out.println("zi");
    }
}
class ExtendsDemo{
    public static void main(String[] args){
        Zi z = new Zi();
        z.show();  //输出zi
    }
}

8.11 继承-覆盖的应用

描述手机:来电显示,打电话,发短信。

class Phone{
    public void call(){}
    public void sendMsg(){}
    public void show(){
        System.out.println("number");
    }
}

class ExtendsDemo{
    public static void main(String[] args){
        Phone p = new Phone();
        p.show();
    }
}

手机出新了,来电功能更多了。
定义了来电显示功能,注意了,父类已经定义了来电显示功能,子类直接拿过来用就可以了。
但是子类对功能的内容要有自己的定义。保留父类功能的声明,建立子类功能特有的内容:覆盖的应用。

class Phone{
    public void call(){}
    public void sendMsg(){}
    public void show(){
        System.out.println("number");
    }
}

class NewPhone extends Phone{
    public void show(){
        System.out.println("number");  //还可以改成super.show();
        System.out.println("name");
        System.out.println("pic");
    }
}

class ExtendsDemo{
    public static void main(String[] args){
        NewPhone np = new NewPhone();
        np.show();
    }
}

输出:

number
name
pic

8.12 继承-覆盖的注意事项

  • 子类方法覆盖父类方法,必须保证访问权限大于等于父类权限。(private<默认<public)
  • 静态只能覆盖静态,或者被静态覆盖。
  • 成员变量不存在覆盖,覆盖只用于函数。

8.13 继承-子类的实例化过程

  • 子父类中的构造函数的特点。
    创建子类对象时,父类中的空参数构造函数也运行了,因为子类中的所有构造函数的第一行默认都有一个隐式的super();语句。
    调用本类中的构造函数中的this(实参列表)语句。调用父类中的构造函数用super(实参列表);

  • 为什么子类对象初始化都要访问父类中构造函数呢?
    因为子类继承了父类中的内容,所以创建对象时必须要先看父类是如何对内容进行初始化的。
    这就是子类的实例化过程。

8.14 继承-子类的实例化过程-注意事项

当父类中没有空参数构造函数时,子类需要通过显示定义super语句指定要访问的父类中的构造函数。

class Fu{
    Fu(int x){
        System.out.println("fu");
    }
}

class Zi extends Fu{
    Zi(){
        super(1); //显示指定super的方式来访问父类中的构造函数
        System.out.println("zi");
    }
}

注意:用来调用父类构造函数的super语句在子类的构造函数中必须定义在第一行,因为父类的初始化要先完成。

class Fu{
    Fu(int x){
        System.out.println("fu");
    }
}

class Zi extends Fu{
    Zi(){
        this(1);  //是可以的,有了this语句,就没有super语句
        System.out.println("zi");
    }
    Zi(int x){
        super(2);
        System.out.println("zi.....x");
    }
}

问题:

  • this和super用于调用构造函数,可以同时存在吗?
    不可以,因为它们只能定义在第一行。
  • 为什么要定义在第一行?
    因为初始化动作要先执行行。

8.15 继承-子类的实例化过程-练习

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
public class Student extends Person{
    
    Student(String name,int age){
        super(name,age); // 显示调用父类的构造函数
    }
    public void study(){
        System.out.println("study");
    }
}

class Worker extends Person{
    
    Worker(String name,int age){
        super(name,age);  // 显示调用父类的构造函数
    }
    public void work(){
        System.out.println("work");
    }
}

猜你喜欢

转载自blog.csdn.net/lwycc2333/article/details/83826858