面向对象-继承

image-20221118122819914

继承基本介绍和示意图

继承可以解决代码复用,让我们的编程更加靠近人类思维。当多个类存在相同的属性和方法时,可以从这些类中抽象出父类,在父类中定义这些相同的属性和方法,所有的自雷不需要重新定义这些属性和方法,只需要通过extends来声明和继承父类即可

image-20221118144907152

继承的基本语法

class 子类 extends 子类 {
}
  1. 子类就会自动拥有父类定义的属性和方法
  2. 父类又叫超类,基类
  3. 子类又叫派生类

快速入门案例

父类:Student.java

package com.hsp.extend._improve;
//父类: 是pupil和graduate的父类
public class Student {
    //共有属性
    public String name;
    public int age;
    private double score;
    //共有方法
    public void setScore(double score) {
        this.score = score;
    }
    public void showInfo(){
        System.out.println("学生名" + name + " 年龄 " + age + " 成绩 " + score);
    }
}

子类:

Pupil.java

package com.hsp.extend._improve;

public class Pupil extends Student{
    public void testing(){
        System.out.println("小学生" + name + "正在考试");

    }
}

Graduate.java

package com.hsp.extend._improve;

public class Graduate extends Student{
    public void testing(){
        System.out.println("大学生" + name + "正在考试");
    }
}

运行类:

Extends01.java

package com.hsp.extend._improve;

public class Extends01 {
    public static void main(String[] args) {
        com.hsp.extend._improve.Pupil pupil = new Pupil();
        pupil.name = "Hello";
        pupil.age = 10;
        pupil.testing();
        pupil.setScore(50);
        pupil.showInfo();

        System.out.println("=====");
        com.hsp.extend._improve.Graduate graduate= new Graduate();
        graduate.name = "mike";
        graduate.age = 20;
        graduate.testing();
        graduate.setScore(100);
        graduate.showInfo();

    }
}

继承给编程带来的便利

  1. 代码的复用性提高了
  2. 代码的扩展性和维护性提高了

继承的深入讨论和细节问题

  1. 子类继承了所有的属性和方法,非私有的属性和方法在同一个包下,父类的属性和方法都能在子类直接访问,但是私有的属性和方法不能直接在子类访问,要通过公共的方法去访问

  2. 子类必须调用父类的构造器,完成父类的初始化

  3. 当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参构造器,如果父类没有提供无参构造器,则必须在子类的构造器中使用super去指定使用父类的哪个构造器完成对父类的初始化工作,否则,编译不会通过。

  4. 如果希望指定去调用父类的某个构造器,则显式调用一下super(参数列表)

  5. super在使用时,需要放在构造器的第一行

  6. super()和this()都只能放在构造器的第一行,因此这两个方法不能共存在一个构造器

  7. java所有类都是Object类的子类,Object是说有类的基类

    image-20221119182327659

  8. 父类构造器的调用不限于直接父类,将一直往上追溯直到Object

  9. 子类最多只能继承一个父类,即java中是单继承机制

  10. 不能滥用继承,子类和父类之间必须满足 is-a的逻辑关系

继承的本质

jvm的内存布局

package com.hsp.extend.therory;

public class therory {
    public static void main(String[] args) {
        Son son = new Son();
        //首先看子类是否有该属性
        //如果子类有这个属性,并且可以访问,那么就返回信息
        //如果子类没有这个属性,就向上从父类里面找信息,然后返回信息
        //如果父类没有,就继续向上找,直到找到object,如果object中还没有,就报错
        System.out.println(son.name);//大头儿子
        System.out.println(son.age);//39
        System.out.println(son.hobby);//
    }
}
class Grandpa {
    String name = "大头爷爷";
    String hobby = "旅游";
}
class Father extends Grandpa{
    String name = "大头爸爸";
    int age = 39;
}
class Son extends  Father{
    String name = "大头儿子";
}

image-20221119191454988

继承课堂练习:

image-20221119203135689

Computer.java

package com.hsp.extend.computer;

public class Computer {
    String cpu;
    String memory;
    String disk;
    public Computer(String cpu, String memory, String disk) {
        this.cpu = cpu;
        this.memory = memory;
        this.disk = disk;
    }
    public String getCpu() {
        return cpu;
    }

    public void setCpu(String cpu) {
        this.cpu = cpu;
    }

    public String getMemory() {
        return memory;
    }

    public void setMemory(String memory) {
        this.memory = memory;
    }

    public String getDisk() {
        return disk;
    }

    public void setDisk(String disk) {
        this.disk = disk;
    }



    public String getDetails(){

    return "cpu:" + cpu + " " + "memory:" + memory + " " + "disk:" + disk ;
    }
}

PC.java

package com.hsp.extend.computer;

public class PC extends Computer {
    private String brand;


    public PC(String cpu, String memory, String disk, String brand) {
        super(cpu, memory, disk);
        this.brand = brand;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }
    public void printInfo() {
        System.out.println("PC信息:");
        System.out.println("brand:" + getBrand() + " " + getDetails());
    }
}

Notepad.java

package com.hsp.extend.computer;

public class NotePad extends Computer {
    String color;
    public NotePad(String cpu, String memory, String disk, String color) {
        super(cpu, memory, disk);
        this.color = color;
    }
    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }
    public void printInfo() {
        System.out.println("Notepad信息:");
        System.out.println("brand:" + getColor() + " " + getDetails());
    }
}