• 4. 继承


    为什么要继承?

    Java中使用使用类区队现实世界中的东西进行描述,但是现实世界错综复杂,事物与事物之间都会存在着一些关联,那在设计程序就是需要考虑。

    比如:猫和狗,它们都是动物

    而我们在学过类与对象以后就可以设计出:

    class Dog {
        public String name;
        public int age;
        public double weight;
    
        public void eat() {
            System.out.println(name+"在吃饭!");
        }
    
        public void bark() {
            System.out.println(name+"正在汪汪叫!");
        }
    }
    
    class Cat {
        public String name;
        public int age;
    
        public void eat() {
            System.out.println(name+"在吃饭!");
        }
    
        public void miaomiao() {
            System.out.println(name + "正在喵喵叫~");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    然而我们通过对比不难发现,其中有些代码是一样的

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LxdjTX3n-1658132188795)(C:\Users\飞逝恋\AppData\Roaming\Typora\typora-user-images\image-20220718112459757.png)]

    那么我们可以简化一下代码么?答案:是可以的!!

    面向对象思想中提出了继承的概念,专门用来进行共性抽取,实现代码复用

    接下来就是我们要讲的继承了

    //创建一个Animal类
    //将Dog类与Cat类中共有的属性放入Animal类中
    //再使用extends关键字,将父类Animal对子类Dog、Cat进行继承
    
    class Animal {             //父类
        public String name;
        public int age;
    
        public void eat() {
            System.out.println(name+"在吃饭!");
        }
    }
    
    class Dog extends Animal{           //子类
        public double weight;
    
        public void bark() {
            System.out.println(name+"正在汪汪叫!");
        }
    }
    
    class Cat extends Animal{       //子类
        public void miaomiao() {
            System.out.println(name + "正在喵喵叫~");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    上述代码中,Dog和Cat都继承了Animal类,其中:Animal类称为父类/基类或超类,Dog和Cat可以称为Animal的 子类/派生类,继承之后,子类可以复用父类中成员,子类在实现时只需关心自己新增加的成员即可。

    注意:

    1. 子类会将父类中的成员变量或者成员方法继承到子类中了
    1. 子类继承父类之后,必须要新添加自己特有的成员,体现出与基类的不同,否则就没有必要继承了

    继承的语法

    关键字 class 子类 extends 父类{
    //      ......
    }
    
    • 1
    • 2
    • 3

    父类成员访问

    public class Base {
        int a;
        int b;
        int c;
    }
    //============================
    public class Derived extends Base{
        int a; // 与父类中成员a同名,且类型相同
        char b; // 与父类中成员b同名,但类型不同
        public void method(){
            a = 100; // 访问父类继承的a,还是子类自己新增的a?
            b = 101; // 访问父类继承的b,还是子类自己新增的b?
            c = 102; // 子类没有c,访问的肯定是从父类继承下来的c
    // d = 103; // 编译失败,因为父类和子类都没有定义成员变量b
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    在子类方法中 或者 通过子类对象访问成员时:

    如果访问的成员变量子类中有,优先访问自己的成员变量。

    如果访问的成员变量子类中无,则访问父类继承下来的,如果父类也没有定义,则编译报错。

    如果访问的成员变量与父类中成员变量同名,则优先访问自己的。

    成员变量访问遵循就近原则,自己有优先自己的,如果没有则向父类中找。

    子类中访问父类的成员方法

    成员方法名字相同

    public class Base {
        public void methodA(){
            System.out.println("Base中的methodA()");
        }
        public void methodB(){
            System.out.println("Base中的methodB()");
        }
    }
    public class Derived extends Base{
        public void methodA(int a) {
            System.out.println("Derived中的method(int)方法");
        }
        public void methodB(){
            System.out.println("Derived中的methodB()方法");
        }
        public void methodC(){
            methodA(); // 没有传参,访问父类中的methodA()
            methodA(20); // 传递int参数,访问子类中的methodA(int)
            methodB(); // 直接访问,则永远访问到的都是子类中的methodB(),基类的无法访问到
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    注意

    1. 通过子类对象访问父类与子类中不同名方法时,优先在子类中找,找到则访问,否则在父类中找,找到 则访问,否则编译报错。

    2. 通过派生类对象访问父类与子类同名方法时,如果父类和子类同名方法的参数列表不同(重载),根据调用 方法适传递的参数选择合适的方法访问,如果没有则报错;

    super关键字

    class Classes {
        public String student = "小明";
        public int number;
    
        public void goClass (){
            System.out.println("做操!!");
        }
    }
    
    class One extends Classes{
        public String student = "李华";;
        public String teacher;
    
        public void goClass() {
            System.out.println("子类goClass:"+"上课");
            System.out.print("父类goClass:" );
            super.goClass();
        }
    
        public void printStudent() {
            System.out.println("子类student:" + student);
            System.out.println("父类student:" + super.student);
        }
    }
    
    public class Test2 {
        public static void main(String[] args) {
            One one = new One();
            one.printStudent();
            one.goClass();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    简单来说,在子类方法中,如果想要明确访问父类中成员时,借助super关键字即可。

    注意:

    1. 只能在非静态方法中使用
    2. 在子类方法中,访问父类的成员变量和方法。

    toString    ~~   方法使用类名访问

       ~~   
       ~~   

    当在父类中提供了构造方法,那么在子类中也应当提供构造方法

    在这里插入图片描述

    快捷做法1️⃣
       ~~   
       ~~   
    按Alt+Ins键
       ~~   
    在这里插入图片描述
    在这里插入图片描述

    快捷做法2️⃣

    鼠标光标放置红色波浪出,按住     ~~~    Alt+回车键    ~~   ,即可

    不写时编译器会默认提供空的构造方法

    class Animal {             //父类
        public Animal() {
    
        }
    }
    
    class Dog extends Animal {           //子类
        public Dog() {
            super();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在这里插入图片描述

    super关键字总结

    Alt+回车键

    1. super.data;访问父类成员变量
         ~~   
    2. super.func;访问父类的成员方法
         ~~   
    3. super();访问父类的构造方法

    先后顺序

  • 相关阅读:
    毛胚房需要验收吗
    什么是关系选择器
    MapReduce计算流程
    Prometheus服务发现之kubernetes_sd_config
    java计算机毕业设计基于安卓Android的禁毒宣传APP(源码+系统+mysql数据库+Lw文档)
    MATLAB画图分辨率、图像大小研究
    Vue3最佳实践 第六章 Pinia,Vuex与axios,VueUse 4(axios)
    实现常规厂家&品牌&型号业务对接物联网平台(snack3加json赋能)
    Acrel-3000WEB电能管理系统在都巴高速的应用
    【kafka专栏】生产者客户端自定义序列化器
  • 原文地址:https://blog.csdn.net/youstory/article/details/125853754