17-面向对象编程-继承

面向对象编程有三大特征:封装、继承和多态

 

访问修饰符可以控制属性的访问范围

public:表示公共访问级别,可以被任何类访问。

protected:表示受保护访问级别,可以被类本身、子类和同一包中的类访问。

default(缺省):表示默认访问级别,即如果没有使用访问修饰符,默认是此级别,可以被同一包中的类访问。

private:表示私有访问级别,只能在类内部访问。

修饰符
子类
其他包
public
protected
×
default
×
×
private
×
×
×

 

继承介绍

继承可以解决代码复用问题,当多个类存在相同的属性和方法时,可以从这些类中抽象出父类,在父类中定义这些相同的属性和方法,所有的子类不需要重新定义这些属性和方法,只需要通过extends来声明继承父类即可。

换句话说,继承就是类与类之间产生关系(子父类关系),子类可以直接使用父类中非私有的成员属性和方法。

继承的好处

代码的复用性提高了,同时代码的扩展性和维护性也提高了。

继承的基本语法

修饰符 class 子类 extends 父类{

}

1) 子类会自动拥有父类定义的属性和方法

2) 父类又称超类、基类,子类又称派生类

3) 不能同时继承多个类,只能继承一个类

public class Extends01 {
    public static void main(String[] args) {
        Pupil pupil = new Pupil("马铃薯1",6,100);
        pupil.testing();  //小学生正在考小学数学...
        pupil.showInfo(); //学生名:马铃薯1    年龄:6    成绩:100.0

        Graduate graduate = new Graduate("马铃薯2",26,95);
        graduate.testing();  //大学生正在考高等数学...
        graduate.showInfo(); //学生名:马铃薯2    年龄:26    成绩:95.0
    }
}

//父类
class Student{
    //共有的属性
    public String name;
    public int age;
    private double score;

    //父类构造方法
    public Student(String name, int age, double score) {
        this.name = name;
        this.age = age;
        this.score = score;
        System.out.println("父类Student的构造方法");
    }

    //共有的方法
    public void setScore(double score){
        this.score = score;
    }

    public void showInfo(){
        System.out.println("学生名:" + name + "\t年龄:" + age + "\t成绩:" + score);
    }
}

//子类,小学生类
class Pupil extends Student{

    //子类构造方法
    public Pupil(String name, int age, double score) {
        super(name, age, score);
        System.out.println("子类Pupil的构造方法");
    }

    //子类特有的方法
    public void testing(){
        System.out.println("小学生正在考小学数学...");
    }

}

//子类,大学生类
class Graduate extends Student{

    //子类构造方法
    public Graduate(String name, int age, double score) {
        super(name, age, score);
        System.out.println("子类Graduate的构造方法");
    }

    //子类特有的方法
    public void testing(){
        System.out.println("大学生正在考高等数学...");
    }
}

 

继承的使用细节

1. 子类继承了父类所有的属性和方法,非私有的属性和方法可以在子类直接访问,但是私有的属性和方法不能在子类直接访问,要用通过父类提供的公共方法进行访问,例如 getXxx()方法。

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

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

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

5. super在使用时,必须放在构造器的第一行(super只能在构造器中使用)

6. Java所有类都是Object类的子类,也就是Object类是所有类的基类

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

8. 子类最多只能继承一个父类(指直接继承),即Java中的单继承机制

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

 

super() 和 this() 

super() 是调用父类的构造器,this() 是调用本类的构造器,这两个都只能放在构造器的第一行,因此不能同时出现在一个构造器。

is-a 关系

is-a关系,表示子类和父类之间的继承关系

比如:一个Student类,继承了父类Person类,我们就可以说一个学生就是一个人,也就是Student is a Person。

 

继承的内存示意图

 

注意:这里需要注意的是,如果子父类中出现了重名的成员变量,使用的时候根据就近原则,优先使用子类的(如果一定要使用父类的,可以通过super关键字)

public class ExtendsDemo1 {
    public static void main(String[] args){
        // 创建子类对象
        Zi z = new Zi();
        z.show();
    }
}

class Fu{
    int num = 10;
}

class Zi extends Fu{
    int num = 20;

    public void show(){
        int num = 30;
        System.out.println(num); // 30
        System.out.println(this.num); // 20
        System.out.println(super.num); // 10
    }
}

 

posted @ 2023-08-17 17:13  马铃薯1  阅读(6)  评论(0编辑  收藏  举报