继承的理解 超级详细

初始继承

首先我们来看一段代码:

class dog{
    private String name;
    private int age;
    public void eat(){
        System.out.println(this.name+"正在吃饭!!!");
    }
    public void bark(){
        System.out.println(this.name+"汪汪汪!!!");
    }
}
class Cat{
    private String name;
    private int age;
    public void eat(){
        System.out.println(this.name+"正在吃饭!!!");
    }
    public void bark(){
        System.out.println(this.name+"喵喵喵!!!");
    }
}

我们可以发现 dog 和 cat类中具有很多的公共部分,那么如何简单化代码呢 ?这时候我们就需要提到一个新概念:继承

继承机制:是面向对象程序设计的使代码可以重复利用的手段,它允许程序员在保持原有类的特性的基础上进行扩展,增加新功能,这样产生的类称之为派生类。

继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程,继承主要解决的问题是:共性的提取,实现代码复用。

所以上述代码 我们可以进行修改:

class Animal {
    private String name;
    private int age;

    public Animal(String name, int age) {
        this.name = name;
        ;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void eat() {
        System.out.println(this.name + "正在吃饭!!!");
    }
}

class Dog extends Animal {
    public Dog(String name, int age) {
        super(name, age);
    }

    public void bark() {
        System.out.println(super.getName() + "汪汪汪!!!");
    }
}

class Cat extends Animal {
    public Cat(String name, int age) {
        super(name, age);
    }
    public void bark() {
        System.out.println(super.getName() + "喵喵喵!!!");
    }
}

public class Test {
    public static void main(String[] args) {
        Dog dog=new Dog("huahua",11);
        Cat cat=new Cat("qiqi",12);
        dog.bark();
        dog.eat();
        cat.bark();
        cat.eat();
    }
}

运行结果:

这段代码 中所涉及的super是个关键字 我们可以向下继续阅读 来了解什么是super!

子类构造方法

上诉代码中 我调用了 两次构造方法 这是为什么呢 这里我们就要提到有一句话;现有父再有子!即:在子类对象的构造时,需要先调用父类构造方法,然后才能执行子类的构造方法!

注意:

1.若父类显式定义无参或者默认构造方法,在子类构造方法种隐含着super()调用父类构造方法!

2.如果父类的构造方法是带参数的,此时需要用户为子类显式定义构造方法,并在子类构造方法中选择合适的父类构造方法调用,否则编译失败!(可参考 最上面代码)

3.在子类构造方法中 super()调用父类构造时,必须是子类第一条语句!

4.super()只能在子类构造方法中出现一次,并且不能与this同时出现!(防止重复构造)

super和this

由于设计的问题 或是因为场景需要,子类和父类具有相同的名字的成员,如果在子类中想要访问父类的同名成员,我们就需要用到super关键字,类似this关键字,作用:在子类中访问父类 成员

super和this都可以调用成员变量和方法,那么他们的区别是什么?

相同点:

1.都是java中的关键字

2.只能在类的静态方法中使用,用来访问非静态成员方法和字段

3.在构造方法调用时,必须是构造方法的第一句,并且不能同时是存在

不同点:

1.this是当前对象的引用,当前对象即调用实例化方法的对象,super相当于是子类对象中从父类继承下来的部分成员的引用

2.在非静态成员方法中,this用来访问本类的方法和属性,super用来访问父类继承下来的方法和属性

3.在构造方法中:this()用于调用本类的构造方法,super()用于调用父类的构造方法,两种不能同时在构造方法中出现

4.构造方法中一定会存在super()的调用,用户不写会自动生成,但是this()不会。

代码块执行顺序

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: ilook
 * Date: 2023-05-22
 * Time: 12:29
 */

class People{
    private String name;
    private int age;
    public People(String name,int age){
        this.name=name;
        this.age=age;
        System.out.println("父类构造方法!");
    }
    {
        System.out.println("父类实例化代码块!");
    }
    static{
        System.out.println("父类静态代码块!");
    }
}
class Student extends People{
    public Student(String name,int age){
        super(name,age);
        System.out.println("子类构造方法!");
    }
    {
        System.out.println("子类实例化代码!");
    }
    static{
        System.out.println("子类静态代码!");
    }
}
public class Test1 {
    public static void main(String[] args) {
        Student s1=new Student("huahua",11);
        System.out.println("========================");
        Student s2=new Student("qiqi",12);
    }
}

运行结果:

通过分析 我们可以得出以下结论:

1.父类静态代码块优先于子类静态代码块,并且静态代码块 执行最早

2.父类实例化代码优先于父类的构造方法

3.子类的实例化代码优先于子类构造方法

4.static静态代码块 只能执行一次

protected 关键字

为了实现封装的特性,java中引用了访问限定符,这次 我们来研究一下 在继承中 访问限定符的作用域问题:

 

class B{
    private int a;
    protected int b;
    public int c;
    int d;//不给访问限定符 默认认为是default
}
//在同一个包内
class C extends B{
    public void method(){
        super.a=10;//报错 父类private在相同的包内子类不可见
        super.b=11;
        super.c=13;
        super.d=14;
    }
}
//不同的包内
class C extends B{
    public void method(){
        super.a=10;//报错 父类private 在不同的包内子类不可见
        super.b=11;
        super.c=13;
        super.d=14;//报错 默认访问修饰限定符在不同的包内不能访问
    }
}

注意:父类中的private成员变量虽然在子类中不能直接访问,到那时也继承到子类中

继承方式

下面 是java中只支持以下几种继承方式:

注意:Java不同于C++ java不支持多继承。

一般的情况 我们的继承最多不会超过三层,如果太多我们就可以考虑代码的重构,如果想要终止继承,就需要使用一个关键字,final

final关键字

我们可以将final关键字 类比成 C++中的const,它可以修饰变量,成员方法,以及类。

1.修饰变量

final int a=10;
a=100;//报错

2.修饰类 

 3.修饰方法:表示该方法不能重写,后续会详细介绍。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lose_rose777

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值