【Java】还不理解继承?一篇文章看懂继承|继承入门

前言

在前面的文章中,对什么是类,什么是对象已经有清晰的理解了(【JavaSE】保姆级教程|1万字+10张图入门到学会类与对象(建议收藏))。我们脑海里目前有一下几个印象:

  • 类是由现实生活的事物抽象而来
  • 类更多是表示一种自定义类型(记住&体会这点,在后面讲到接口的时候还会提到这句话)
  • 类之间有一定的关系相对独立依赖(uses-a)

但是现实生活中,事物之间(类型之间)的关系并不是这么单纯。比如:动物、小狗、小猫、兔兔…动物类和其他这些类之间存在关系是–(is-a)

Java中将这种类与类之间的包含/分类关系描述为

继承–

is-a

这篇文章带大家入门Java第二大重要特性

文章目录

📍Part1:继承的介绍&语法

Java中是以什么样的语法来表示类与类之间这种继承关系呢?

首先要明白两个概念:

  • 父类/基类
  • 子类/派生类

父类和子类的关系是:子类 is-a 父类.即子类是包含于父类的。

下面就以“前言”中提到的动物例子举例:

"extends"的英文意思是“扩展”,就是指,子类继承了父类(继承父类非private属性&方法),自己也可以定义属性&方法&重写方法。本质上子类的确可以看作是父类的一种扩展

  • 父类:class Animal
public class Animal {
    private int age;
    private String name;

    public void eat() {
        System.out.println("吃东西ing");
    }

    //下面是两个属性的构造器
    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

1234567891011121314151617181920212223242526
  • 子类1:汪星人:class Dog
public class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println("啃骨头ing");
    }
}
123456
  • 子类2:喵星人:class Cat
public class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("吃小鱼儿ing");
    }
    public void climb(){
    	System.out.println("猫咪爬树");
}
12345678
  • Java是单继承机制,即:每个类有且仅有一个父类。(C++是多继承)
  • 继承可以是多层的,即:在没有final限制的情况下,子类可以向下派生子类:

📍Part2:继承的特性

通过上面,可能还是有点懵。难道说继承的存在,仅仅是表示类之间的关系?不。

我们来深入学习一些,子类继承了父类,给我们带来了什么,以及我们怎么样去使用继承。

继承时父类和子类产生关联,带来主要以下特性:

也正是这几点,也带来了继承的好处:

  • 把公共的属性、方法定义在父类中,子类由于继承(只能继承非private修饰)了父类的属性、方法,无需重复声明&定义,提高代码复用性。子类只需要关心自己的特有属性和方法(单独声明定义of重写父类方法)
  • 是基于多态&动态绑定的,(我们下文中细讲)

当然,经过上文,我们对继承有了一个大概的初印象。但是继承的使用和一些细节还有很多学问。咱们接下来打起精神。逐个攻破!

📍Part3:继承细节

📌3.1:super关键字

【Java】还不懂this关键字?一分钟彻底弄懂this关键字我们对this关键字有了一个很透彻的认识:this关键字是对象的隐藏属性,代表此对象的引用,通过this.属性this.方法我们指定可以调用本类的属性和方法。

与this关键字作用很相似的一个关键字是

super

:

指向当前对象的父类。

和this用法类似,只不过super是**在本类中访问父类的属性/方法/构造器:

super.父类属性

/

super.父类方法

/

super()

(不可调用父类中被private修饰的属性or方法!)

  • 在子类构造器中使用super()来调用父类构造器,来完成对父类属性的初始化。
  • 区分子类中定义的和父类中同名的属性/方法

本质

this的本质是一个实实在在存在的

参数

,在对象调用实例方法时,会被作为隐藏参数传入实例方法中。

super的本质仅仅就是

关键字

,编译后会被翻译成一条指令:

invokespecial

 

,用于调用一些需要特殊处理的实例方法,包括实例初始化方法、私有方法和父类方法。

this/super.属性

(访问属性)

访问本类的属性。若本类没有,逐级向上查找

访问其直接父类的属性,若没有,逐级向上查找

this/super.方法

同访问属性的查找规则规则

同访问属性的查找规则

📌3.2:子类构造器

关于构造器,推荐大家先去阅读这篇文章:【Java】一文看懂构造器/构造方法(Cunstructor)。文章很短,方便你更好的理解下面知识。

在之前讲构造器的时候,没有讲到继承。

其实构造器中行首隐含了一条默认语句:

super()

:

 

调用父类构造器,完成对父类属性初始化

public class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println("啃骨头ing");
    }

    public Dog() {
        //super();
    }
}

1234567891011
  • 若父类无参构造器不存在,必须显示调用父类存在的构造器
  • super调用父类构造器和this调用本类构造器,有且只能有一条,且必须位于行首(即使用this()来调用本类构造器,最终肯定调用到某个构造器中还会调用super()的,这个不用担心父类没有被初始化)

📌3.3:protected关键字

关于访问修饰符在【Java】一文彻底弄懂访问修饰符(public/protected/默认/private)–建议收藏已经全面介绍过。这里单独谈谈protected关键字在继承中的作用。

上文已经提到过,子类是无法继承父类被private修饰的属性,但是我们在封装那一篇文章中讲到,由于种种原因,类中的属性最好为private。那怎么办呢?

有一个两全其美的办法—protected关键字:只有子类&同包中其他类可以访问。

📌3.4:final关键字

时刻牢记:我们写的类是现实中的抽象

真正进入公司,项目中的业务往往比我们举例要复杂很多。意味着,我们写的类会很多,同时类与类之间的关系也会很复杂。

所以,我们并不希望类与类之间继承的层次过深,一般不希望超过三层的继承关系。否则,将对代码进行重构

那如何进行这样的一种限制呢?

可以使用关键字final对类进行修饰:让类不可被继承(若被继承,将在编译时期报错)

举例:我们平时经常使用的String类,就是被final修饰的:


全部评论
看懂了hhh 好家伙我直呼好家伙
点赞 回复 分享
发布于 2023-03-23 12:57 湖北
狠狠学到了(阿猫阿狗真可爱x
点赞 回复 分享
发布于 2023-03-23 12:30 黑龙江

相关推荐

05-20 13:59
门头沟学院 Java
米黑子米黑子:你这个成绩不争取下保研?
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务