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 + "正在喵喵叫~");
    }
}

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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 + "正在喵喵叫~");
    }
}

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

注意:

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

继承的语法

关键字 class 子类 extends 父类{
//      ......
}

父类成员访问

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
    }
}

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

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

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

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

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

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

成员方法名字相同

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

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();
    }
}

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

注意:

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

toString    ~~   方法使用类名访问

   ~~   
   ~~   

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

在这里插入图片描述

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

快捷做法2️⃣

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

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

class Animal {             //父类
    public Animal() {

    }
}

class Dog extends Animal {           //子类
    public Dog() {
        super();
    }
}

在这里插入图片描述

super关键字总结

Alt+回车键

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

先后顺序

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
原型链继承(Prototype Inheritance)在JavaScript中是通过创建一个新对象并让它引用另一个对象的原型来实现的。例如: ```javascript function Parent() {} Parent.prototype.method = function() { console.log('Parent method'); }; let child = new Parent(); child.method(); // 输出: "Parent method" ``` **借用构造函数继承**(Constructo r Chaining)利用已有构造函数作为父类,通过`new`关键字传递给子类实例化过程,间接实现了继承: ```javascript function Parent() { this.parentProp = 'parent'; } function Child() { Parent.call(this); // 借用父类构造函数 this.childProp = 'child'; } Child.prototype = Object.create(Parent.prototype); Child.prototype.constructor = Child; let childInstance = new Child(); console.log(childInstance.parentProp); // 输出: "parent" console.log(childInstance.childProp); // 输出: "child" ``` **组合式继承**(Mix-in or Prototype Mixing)结合原型链和构造函数继承,允许从多个源继承属性和方法: ```javascript function Mixin(target) { for (let prop in Mixin.prototype) { target[prop] = Mixin.prototype[prop]; } } function Parent() { this.parentProp = 'parent'; } Mixin(Parent.prototype); let child = new Parent(); console.log(child.parentProp); // 输出: "parent" ``` **ES6的class类继承**(Class-based Inheritance)使用`extends`关键字实现: ```javascript class Parent { constructor() { this.parentProp = 'parent'; } parentMethod() { console.log('Parent method'); } } class Child extends Parent { constructor() { super(); this.childProp = 'child'; } childMethod() { console.log('Child method'); } } let childInstance = new Child(); childInstance.parentMethod(); // 输出: "Parent method" childInstance.childMethod(); // 输出: "Child method" ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值