Java继承和多态(1)

news2024/11/18 21:46:40

🐵本主题将分为篇文章,本篇文章将主要对继承进行讲解


一、介绍继承

1.1 什么是继承

假如有两个类:A类和B类,A类在保持原有成员变量和方法的基础上可以使用B类的成员变量和方法,此时就称A类继承了B类,A类为子类,B类为父类

继承是通过extends关键字来实现的:

class 父类 {
}

class 子类 extends 父类 {
}

举一个实例:

class Base {
    public int a = 10;
}

//Derived为子类,Base为父类
class Derived extends Base {
    public void method() {
        System.out.println(a);
    }
}
public class Test1{
    public static void main(String[] args) {
        Derived derived = new Derived();
        derived.method();
    }
}

1.2 为什么要有继承

假如有A、B两个类,这两个类中的成员变量和成员方法相似,这时可以再创建一个C类,C类的内容就是A类和B类相同的成员变量和方法,让A和B去继承C类,这样就可以避免代码的冗杂,从而实现代码的复用

二、子类访问父类成员

2.1 访问父类成员变量

当子类成员变量与父类成员变量相同时,优先访问子类成员变量

class Base {
    public int a = 10;
}
class Derived extends Base {
    public int a = 20;

    public void method() {
        System.out.println(a);
    }
}

2.2 访问父类成员方法

当子类成员方法名和父类成员方法名且参数列表相同时,优先访问子类成员方法;当方法名相同但参数列表不同时,访问合适的方法

class Base {
    public int a = 10;    
    public void method() {
        System.out.println("父类成员方法");
    }
    public void A() {
        System.out.println("父类A");
    }
}
class Derived extends Base {
    public int a = 20;
    public void method() {
        System.out.println("子类成员方法");
    }
    public void A (int a){
        this.a = a;
        System.out.println(a);
    }

}
public class Test1{
    public static void main(String[] args) {
        Derived derived = new Derived();
        derived.method(); //打印出 子类成员方法
        derived.A(30); //打印出30
        derived.A(); //打印出 父类A
    }
}

那么当子类成员和父类成员名字相同而我们想要访问父类成员时该如何做,下面介绍super关键字

三、super关键字

super实际上就是从父类继承过来数据的引用,其主要作用就是在子类方法中访问父类成员,super不能出现在静态方法中,以下时super的用法:

1. super.父类成员变量--->访问父类成员变量

2.super.父类成员方法--->访问父类成员方法

3.super() --->访问父类构造方法 (下面介绍)

3.1 super访问父类成员变量

class Parent {
    public int a = 10;
}
class Child extends Parent{
    public int a = 20;
    public void method() {
        System.out.println(super.a);//子类与父类成员变量名字都为a,使用super关键字后就会访问父类的a
    }
}
public class Test2 {
    public static void main(String[] args) {
        Child child = new Child();
        child.method();
    }
}

3.2 super访问父类成员方法

class Parent {
    public void method() {
        System.out.println("父类成员方法");
    }
}
class Child extends Parent{
    public void method() {
        System.out.println("子类成员方法");
    }
    public void func() {
        super.method();
    }
}
public class Test2 {
    public static void main(String[] args) {
        Child child = new Child();
        child.func();
    }
}

四、子类和父类构造方法

在创建对象时,会调用构造方法,如果没有写构造方法,就调用默认的构造方法,在子类和父类的构造方法如下

class Parent {
    public Parent() {

    }
}

class Child extends Parent {
    public Child() {
        super(); //该语句必须出现在子类构造方法的第一行
                //创建对象时先调用父类构造方法再调用子类构造方法
    }
}

以下是错误写法

class Parent {
    public int a;
    public Parent(int a) { 
        this.a = a;
    }
}
class Child extends Parent { 
    
    public void method() {
        System.out.println(a);
    }
}
public class Test2 {
    public static void main(String[] args) {
        Child child = new Child();
        child.method();
    }
}

上述代码写了构造方法,且有一个参数,而没有写子类的构造方法,那创建对象时就会调用子类的默认构造方法,默认方法中super();没有参数,所以会报错。那么应该自己去写子类的构造方法,并在super()中写上对应的参数,切记super()要写再子类构造方法的第一行

注意:如果子类和父类的构造方法都写了,但在子类的构造方法中没有写super()调用,编译器也会自动加上

五、继承关系下的执行顺序

下面来看继承关系下,静态代码块、构造代码块和构造方法的执行顺序

class Parent {
    static {
        System.out.println("父类静态代码块");
    }

    {
        System.out.println("父类构造代码块");
    }

    public Parent() {
        System.out.println("父类构造方法");
    }

}
class Child extends Parent{
    static {
        System.out.println("子类静态代码块");
    }

    {
        System.out.println("子类构造代码块");
    }

    public Child() {
        super();
        System.out.println("子类构造方法");
    }
}
public class Test {
   
    Child child = new Child();
}

结论:在继承关系下,也是静态代码块先执行,只不过要先执行父类在执行子类,之后也是先执行父类的构造代码块和构造方法,在执行子类的构造代码块和构造方法

六、protected关键字

访问范围publicprivate没有修饰符protected

同一包中的同一类

✔️✔️✔️✔️
同一包中的不同类✔️✔️✔️
不同包中的子类✔️✔️
不同包中的非子类✔️

着重讲解protected的第三项

package demo1; //demo1包
public class Code {
    protected int x = 10; //x被protected修饰
}


package demo2; //demo2包
import demo1.Code;

public class Derived extends Code {
    public void func() {
        System.out.println(super.x); //编译通过
        Code code = new Code();
        //System.out.println(code.x); //编译报错,在不同包的子类中,不能通过对象的引用访问,而是通过super引用访问
    }
    public static void main(String[] args) {
        Derived derived = new Derived();
        derived.func();
    }
}

七、继承的方式

下面来介绍几种继承的方式:

1.单继承:

2.多层继承:

3. 多继承一:

Java不支持多继承,如下图:

在多层继承中最好不要出现三层继承,为了限制继承的层次,引入final关键字

7.1 final关键字

7.1.1 final修饰变量

当一个变量被final修饰时,它就变成了常量,即不能改变它的值

7.1.2 final修饰类

当一个类被final修饰时,就被称为密封类,该类不能被其它类继承

public final class Test {...}
class Child extends Test {...} //编译报错

八、组合

组合简单来说,就是将一个类的实例作为另一个类的字段

class A { }
class B { }
class C { }

public class Test {
    private A a;
    private B b;
    private C c;
}

组合和继承一样都可以实现代码的复用


🙉本篇文章到此结束,下篇文章将会对多态相关知识进行讲解

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

4.1每日一题(多元函数微分:偏导数判定(链导法、定义、先代后求))

链导法:如果每一层复合都可导(即在判断点要可导),则复合函数一定可导;如果中间层有不可导,就不方便使用链导法了(在(0,0)点不可导) 当链导法不好用时应该直接…

微信支付平台C#SDK_微信支付.net SDK

一、微信支付平台C# SDK V3 https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat/blob/main/docs/WechatTenpayV3 接口对应整理: https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat/blob/main/docs/WechatTenpayV3/Basic_Mod…

vue3响应式api

响应式api——compositon api setup: 不要再想this问题执行是在beforeCreated之前 beforeCreated:也就是创建了一个实例 created:挂载了数据 通过形参props接收,只读 以后所有代码都写到setup中 判断是否只读:isReadon…

大数据可视化数据大屏可视化模板【可视化项目案例-05】

🎉🎊🎉 你的技术旅程将在这里启航! 🚀🚀 本文选自专栏:可视化技术专栏100例 可视化技术专栏100例,包括但不限于大屏可视化、图表可视化等等。订阅专栏用户在文章底部可下载对应案例源码以供大家深入的学习研究。 🎓 每一个案例都会提供完整代码和详细的讲解,不…

数据结构:AVLTree的插入和删除的实现

个人主页 : 个人主页 个人专栏 : 《数据结构》 《C语言》《C》 文章目录 前言一、AVLTree二、AVLTree的插入插入新增节点调整平衡因子旋转左单旋(新增节点位于较高右子树的右侧)右单旋(新增节点位于较高左子树的左侧)右左双旋(新增节点在较高右子树的左子…

多数据源切换

多数据源切换 1.jdbcTemplate2.使用切面3.mybatis层次的多数据源4.spring的dynamic自动注入 项目中经常会有多个数据源,那么如何处理呢 有4种方法 准备: 创建两个数据库 CREATE SCHEMA test DEFAULT CHARACTER SET utf8mb4 ; CREATE SCHEMA school DEFA…

pandas笔记:读写excel

1 读excel read_excel函数能够读取的格式包含:xls, xlsx, xlsm, xlsb, odf, ods 和 odt 文件扩展名。 支持读取单一sheet或几个sheet。 1.0 使用的数据 1.1 主要使用方法 pandas.read_excel(io, sheet_name0, header0, namesNone, index_colNone, usecolsNon…

Nginx:如何实现一个域名访问多个项目

1. 背景介绍 最近在多个项目部署中遇到这样一个问题,一个域名如何实现多个项目的访问。因为不想自己单独去申请域名证书和域名配置,便想到了这个方案,结合Nginx的location功能实现了自己的需求,便记录下来。示例中是以项目演示&a…

基于Springboot菜谱美食饮食健康管理系统设计与实现

博主介绍:✌Csdn特邀作者、博客专家、博客云专家、B站程序阿龙带小白做毕设系列,项目讲解、B站粉丝排行榜前列、专注于Java技术领域和毕业项目实战✌ 有设计项目或者是研究参考的可以加微信:Script-Liu 或者是QQ:1339941174 使用的软件开发环…

KubeSphere 社区双周报 | KubeSphere 3.4.1 发布 | 2023.10.27-11.09

KubeSphere 社区双周报主要整理展示新增的贡献者名单和证书、新增的讲师证书以及两周内提交过 commit 的贡献者,并对近期重要的 PR 进行解析,同时还包含了线上/线下活动和布道推广等一系列社区动态。 本次双周报涵盖时间为:2023.10.27-2023.…

游戏制作:猜数字(1~100),不会也可以先试着玩玩

目录 1 2代码如下:可以试着先玩玩 3运行结果:嘿嘿嘿 4程序分析:想学的看 5总结: 1 猜数范围为1~100,猜大输出猜大了,猜小输出猜小了,游戏可以无限玩。 首先先做一个简单的菜单界面&#xf…

Java入门篇 之 补 类与对象

本篇碎碎念:每个人的想法都不一样,不要强求,顺其自然,要相信,一切都在向好的方面前进!!!! 今日份励志文案:山海的浩瀚,宇宙的浪漫,都在我内心翻腾…

【Python】Matplotlib-多张图像的显示

一,情景描述 大家在写论文或者实验报告的时候,经常会放多张图片或数据图像在一起形成对比。比如,我现在有一张经过椒盐噪声处理的图像,现在进行三种滤波,分别是均值,高斯,中值滤波,…

计算机网络技术(一)

深入浅出计算机网络 微课视频_哔哩哔哩_bilibili 第一章概述 1.1 信息时代的计算机网络 1. 计算机网络各类应用 2. 计算机网络带来的负面问题 3. 我国互联网发展情况 1.2 因特网概述 1. 网络、互连网(互联网)与因特网的区别与关系 如图所示&#xff0…

计算机组成原理之处理器(流水线)

引言 为什么不采用单周期实现,硬件比较简单? 主要是因为效率太低,处理器中最长的路径(一般是ld指令)决定了时钟周期 流水线概述 流水线是一种能使多条指令重叠执行的技术。 流水线更快的原因是所有的工作都在并行执行,所以单位…

Adversarial Training Methods for Deep Learning: A Systematic Review

Adversarial Training Methods for Deep Learning: A Systematic Review----《面向深度学习的对抗训练方法:系统回顾》 摘要 通过快速梯度符号法(FGSM)、投影梯度下降法(PGD)和其他攻击算法,深度神经网络暴露在对抗攻击的风险下。对抗性训练是用来防御对抗性攻击威…

【86 backtrader实现crypto交易策略】backtrader和ccxt对接实现中低频自动化交易-01

最近有点空闲,尝试把backtrader和一些实盘交易的接口对接一下,方便大家进行中低频交易,主要目标包括:股票(qmt),期货(ctpbee), crypto(ccxt),外盘交易(ib,已实现,但是版本比较旧,后期会继续更新). 这个周末尝试实现了backtrader和ccxt的对接,主要是参考了下面的开源代…

使用74HC165扩展uno的输入管脚

74HC165管脚定义: 使用3个管脚扩展接入个独立开关 const int dataPin 2; /* Q7 */ const int clockPin 3; /* CP */ const int latchPin 4; /* PL */ const int numBits 8; /* Set to 8 * number of shift registers */ void setup() { Serial.begin…

暴力递归转动态规划(十五)

题目 给定一个正数n,求n的裂开方法数, 规定:后面的数不能比前面的数小 比如4的裂开方法有: 1111、112、13、22、04 。 5种,所以返回5 暴力递归 用暴力递归方法进行尝试,整体思路是这样: 暴力递…

Java --- 直接内存

一、直接内存 1、不是虚拟机运行时数据区的一部分,也不是《Java虚拟机规范》中定义的内存区域。 2、直接内存是在Java堆外的,直接向系统申请的内存区间。 3、来源于NIO,通过存在堆中的DirectByteBuffer操作Native内存。 4、访问直接内存的…