Java 三大特性之继承

目录

一、为什么需要继承?

二、继承概念

三、继承的语法

四、子类访问父类成员

五、super关键字

六、继承关系下的构造方法

七、继承关系下的初始化

八、protected关键字

 九、继承的三种方式

十、final关键字 

十一、继承和组合


一、为什么需要继承?

比如狗和猫,他们都是一个动物,吃饭睡觉是他们的共性,如果你单独写狗类和猫类,会有大量的代码重复

//Cat.java
public class Cat{
    public String name;
    public void eat(){
        System.out.println(name + "正在吃饭"); 
    }
    public void sleep(){
        System.out.println(name + "正在睡觉");
    }
    void say(){
        System.out.println(name + "喵喵~");
    }
}

//Dog.java
public class Dog{
    public String name;
    public void eat(){
        System.out.println(name + "正在吃饭");
    }
    public void sleep(){
        System.out.println(name + "正在睡觉");
    }
    void say(){
        System.out.println(name + "汪汪~");
    }
}

那能否将这些共性抽取呢?

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


二、继承概念

继承(inheritance)机制:是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加新功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构, 体现了由简单到复杂的认知过程。继承主要解决的问题是:共性的抽取,实现代码复用

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


三、继承的语法

修饰词 class 子类 extends 父类 {
    //...
}   

重写上面那个例子 

//Animal.java
public class Animal {
    public String name;
    public void eat(){
        System.out.println(name + "正在吃饭");
    }
    public void sleep() {
        System.out.println(name + "正在睡觉");
    }
}

//Cat.java
public class Cat extends Animal{
    void say(){
        System.out.println(name + "喵喵~");
    }
}

//Dog.java
public class Dog extends Animal{
    void say(){
        System.out.println(name + "汪汪~");
    }
}

//Test.java 
public class Test {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.name = "小狗";
        //Dog类从Animal类继承下的成员变量
        System.out.println(dog.name);
        //Dog类从Animal类继承下的方法
        dog.eat();
        dog.sleep();
        //这是个性的方法
        dog.say();
    }
}

【注意】

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

四、子类访问父类成员

子类中访问父类的成员变量或者成员方法

(1)子类和父类 不存在 同名成员

先访问子类再访问父类,没有就报错!

(2)子类和父类 存在 同名成员

访问子类自己;

【注意】

  • 成员方法重名,但是参数列表不同(方法重载),根据调用方法时传递的参数选择合适的方法访问,如果没有则报错;

可以看到,如果子类和父类存在同名,怎么才能在子类中访问父类相同名称的成员呢?


五、super关键字

该关键字主要作用:在子类方法中访问父类的成员。

【注意】

  1. 只能在非静态方法中使用
  2. 在子类方法中,访问父类的成员变量和方法。
//A.java
public class A{
    int a ;
    void methodA(){
        //...
    }
    void methodB(int a){
        //...
    }
}

//B.java
public class B extends A{
    int a ;
    //与父类中methodA()构成重写
    void methodA(){
        //...
    }

    //与父类中methodB()构成重载(参数列表不同)
    void methodB(){
        //...
    }
    
    void methodC(){ //在子类方法中访问父类成员
        //通过super关键字访问父类成员
        super.a = 111;
        super.methodA();

        //直接可以通过参数列表区分清访问父类还是子类方法
        methodB();    //子类
        methodB(20);    //父类

    }
}

六、继承关系下的构造方法

子类对象构造时,需要先调用父类构造方法,然后执行子类的构造方法

//A.java
public class A{
    public A(){
        System.out.println("父类构造方法");
    }
}

//B.java
public class B extends A{
    public B(){
        System.out.println("子类构造方法");
    }
}

//Test.java
public class Test{
    public static void main(String[] args) {
        B b = new B();    //实例化对象,调用构造方法
    }
}

//输出
//父类构造方法
//子类构造方法

 【注意】

  1. 若父类显式定义无参或者默认的构造方法,在子类构造方法第一行默认有隐含的super()调用,即调用基类构造方法
  2. 如果父类构造方法是带有参数的,此时需要用户为子类显式定义构造方法,并在子类构造方法中选择合适的 父类构造方法调用,否则编译失败。
  3. 在子类构造方法中,super(...)调用父类构造时,必须是子类构造函数中第一条语句。
  4. super(...)只能在子类构造方法中出现一次,并且不能和this同时出现

七、继承关系下的初始化

没继承关系下的执行顺序:静态代码块 > 实例代码块 > 构造方法 

有继承关系下的执行顺序:

//A.java
public class A{
    public A(){
        System.out.println("父类构造方法");
    }
    {
        System.out.println("父类实例代码块");
    }
    static{
        System.out.println("父类静态代码块");
    }

}

//B.java
public class B extends A{
    public B(){
        System.out.println("子类构造方法");
    }
    {
        System.out.println("子类实例代码块");
    }
    static{
        System.out.println("子类静态代码块");
    }
}

//Test.java
public class Test{
    public static void main(String[] args) {
        B b1 = new B();    //实例化第一个对象
        System.out.println("===========");
        B b2 = new B();    //实例化第二个对象
    }
}

【结论】

  1. 父类静态代码块优先于子类静态代码块执行,且是最早执行
  2. 父类实例代码块和父类构造方法紧接着执行
  3. 子类的实例代码块和子类构造方法紧接着再执行
  4. 第二次实例化子类对象时,父类和子类的静态代码块都将不会再执行

八、protected关键字

//A.java
package demo1;
public class A {
    public int x;
    protected int y;
}

//C.java
package demo2;
import demo1.A;
public class C extends A{
    public static void main(String[] args) {
        C c = new C();
        c.x = 20;
        c.y = 10;
    }
}

//B.java
package demo2;
public class B {
    public static void main(String[] args) {
        //因为B和A不是父子关系,得通过C这个A的子类来访问父类成员,建立关系
        //B的意义就是代表 不同包中的类
        C c = new C();    
        System.out.println(c.x);
        //protected 不能在不同包中的非子类直接访问
        //c.y = 100;
    }
}

 九、继承的三种方式


十、final关键字 

final关键可以用来修饰变量、成员方法以及类。

(1)修饰变量或字段,表示常量(即不能修改)

(2)修饰类:表示此类不能被继承

//A.java
public final class A{    //final 修饰
    //...
}

//B.java
public class B extends A{  //报错
   //...
}

 (3)修饰方法:表示该方法不能被重写(后序介绍)


十一、继承和组合

组合可以实现类似多继承的效果,但是和多继承是不一样的喔!

继承表示对象之间是 is-a 的关系,比如:狗是动物,猫是动物

组合表示对象之间是 has-a 的关系,比如:汽车

汽车和其轮胎、发动机、方向盘、车载系统等的关系就应该是组合,因为汽车是有这些部件组成的。

class Tire{ //轮胎
    //...
}
class Engine{   //发动机
    //...
}
//方向盘类...
class Car{  //将上面的类组合到一起
    private Tire tire;  //可以复用轮胎的成员
    private Engine engine;  //可以复用发动机的成员
    //...
}

//比亚迪是汽车
class BYD extends Car{
    //将汽车中包含的:轮胎、发送机等都继承下来
}

组合和继承都可以实现代码复用,应该使用继承还是组合,需要根据应用场景来选择,一般建议:能用组合尽量用组合。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/593302.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

五一玩狗“丧志”记

我天生喜欢狗狗。五一来到媳妇老家这几天,只要有机会我都要给一个只叫“瘦瘦”的狗狗多攒一些吃的。 它是一条看家狗,有大人膝盖那么高八十厘米那么长。通体毛色以黄黑为主,少许白色主要集中在爪子和下巴。两耳直挺挺尖尖的竖立着&#xff0c…

mac通过termius连接Linux服务器

mac上安装 linux系统 如果有 linux服务器账号密码,那么上一步可忽略; 比如:直接连接阿里云或腾讯云账号 1. 安装termius 链接: https://pan.baidu.com/s/1iYsZPZThPizxqtkLPT89-Q?pwdbw6j 提取码: bw6j 官网 Termius - SSH platform for …

CNN实现fashion_mnist数据集分类(tensorflow)

1、查看tensorflow版本 import tensorflow as tfprint(Tensorflow Version:{}.format(tf.__version__)) print(tf.config.list_physical_devices())2、加载fashion_mnist数据与预处理 import numpy as np (train_images,train_labels),(test_images,test_labels) tf.keras.d…

[数据结构]————排序总结——插入排序(直接排序和希尔排序)—选择排序(选择排序和堆排序)-交换排序(冒泡排序和快速排序)—归并排序(归并排序)

文章涉及具体代码gitee: 登录 - Gitee.com 目录 1.插入排序 1.直接插入排序 总结 2.希尔排序 总结 2.选择排序 1.选择排序 ​编辑 总结 2.堆排序 总结 3.交换排序 1.冒泡排序 总结 2.快速排序 总结 4.归并排序 总结 5.总的分析总结 1.插入排…

抖音小风车一键跳转企业微信如何实现

我们在做抖音直播时,都喜欢挂上小风车去做转化,有的直播间小风车可以直接跳转到微信,这是怎么做到的呢?现在把这个经验给大家分享下: 首先我们需要先理解抖音直播间小风车是什么? 抖音小风车实际是一张直播…

c语言:打印任意行数的菱形

例如&#xff1a;以下图片形式 #include <stdio.h> int main() {int line 0;scanf_s("%d", &line);int i 0;//打印上半部分for (i 0; i < line; i){//打印空格数int j 0;for (j 0; j < line - 1 - i; j){printf(" ");}//打印*数量for…

内核中常用宏定义| container_of

文章目录 前言container_of函数介绍container_of函数实现container_of函数解析offsetof的使用container_of的使用结语 前言 前两篇我们写到内核中两种C语言高级语法__attribute__, __read_mostly。本篇写内核中另外一种常用宏定义之container_of container_of函数介绍 conta…

高级事件.

高级事件 1. 注册事件&#xff08;addEventListener)2.删除事件(removeEventListener&#xff09;3.DOM事件流4.事件对象及其方法&#xff08;当形参来看&#xff09;5.阻止默认事件/冒泡6.事件委托7.鼠标事件&#xff08;禁止右键/选中文字)8.鼠标事件对象8.常用键盘事件9.键盘…

【C++】模板初阶:泛型编程的起点

&#x1f49e;&#x1f49e; 前言 hello hello~ &#xff0c;这里是大耳朵土土垚~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;个人主页&#x…

大模型下的Agent、AIGC的商业案例集合

算是一份摘录 1 AIGC 对影楼的影响 https://mp.weixin.qq.com/s/3j-6FAxZEEvXUZ1q6by2uw 2 出海Talkie &#xff1a;情感智能体 https://mp.weixin.qq.com/s/KHPmfuVvywxxcI2rqoOghA Talkie 为每条消息提供 3 个免费灵感&#xff0c;如果用户需要更多 AI 生成的灵感选项&…

Delta lake with Java--在spark集群上运行程序

昨天写了第一篇入门&#xff0c;今天看见有人收藏&#xff0c;继续努力学习下去。今天要实现的内容是如何将昨天的HelloDetlaLake 在spark集群上运行&#xff0c;。具体步骤如下 1、安装spark,我使用的是 spark-3.5.1-bin-hadoop3-scala2.13&#xff0c;去官网下载&#xff0c…

无穷级数错题本

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 <

2024五一赛数学建模A题B题C题完整思路+数据代码+参考论文

A题 钢板最优切割路径问题 &#xff08;完整资料在文末获取&#xff09; 1. 建立坐标系和表示方法&#xff1a; 在建模之前&#xff0c;我们需要将切割布局转换为数学表示。首先&#xff0c;我们可以将布局中的每个点表示为二维坐标系中的一个点。例如&#xff0c;B1可以表示…

Ubuntu服务器创建新用户及解决新用户登录Access denied问题

目录 Ubuntu服务器创建新用户及解决新用户登录Access denied问题创建账号步骤创建用户只创建用户添加用户到sudo组 允许账号远程连接重启ssh服务 删除账号要删除用户而不删除用户文件如果要删除并且删除用户的家目录和邮件 查询指令查看所有用户查询特定用户账户信息查看用户组…

【Java基础】Maven的生命周期(clean+site+default)

1. 前言 在 Maven 出现之前&#xff0c;项目构建的生命周期就已经存在&#xff0c;开发人员每天都在对项目进行清理&#xff0c;编译&#xff0c;测试及部署&#xff0c;但由于没有统一的规范&#xff0c;不同公司甚至不同项目之间的构建的方式都不尽相同。 Maven 从大量项目…

[C++基础学习-07]----C++结构体详解

前言 结构体&#xff08;Struct&#xff09;是C中一种用户定义的复合数据类型&#xff0c;用于存储不同类型的数据项。结构体可以包含不同类型的数据成员&#xff0c;这些数据成员可以是基本类型&#xff08;如int、float、char等&#xff09;&#xff0c;也可以是数组、指针、…

Linux编辑器——vim的基础使用

文章目录 1.vim的基本概念2.vim的基本操作3.vim命令模式命令集3.1移动光标3.2删除文字3.3复制3.4替换3.5撤销3.6更改3.7跳到指定的行 1.vim的基本概念 本文将介绍vim的三种模式&#xff0c;分别位&#xff1a;命令模式、插入模式、低行模式。他们的功能区分如下&#xff1a; 正…

2. 深度学习笔记--损失函数

在机器学习中&#xff0c;损失函数是代价函数的一部分&#xff0c;而代价函数则是目标函数的一种类型。 Loss function&#xff0c;即损失函数&#xff1a;用于定义单个训练样本与真实值之间的误差&#xff1b; Cost function&#xff0c;即代价函数&#xff1a;用于定义单个批…

学习和“劳动”相关的谚语,柯桥俄语培训

1. Бог труды́ лю́бит. 天道酬勤。 2. В ми́ре нет тру́дных дел, ну́жно лишь усе́рдие. 世上无难事,只怕有心人。 3. У́тро вечера мудренее. 一日之计在于晨。 4. Что посе́ешь,…

车载电子电器架构 —— 关于bus off汇总

车载电子电器架构 —— 关于bus off汇总 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明…