面向对象-----继承

前面向大家介绍了面向对象中的封装性,今天再来向大家介绍面向对象的继承和多态的两大特性。

1.继承

1.1 为什么需要继承?

在java语言中,我们用类来描述世间万物,虽然万物非常复杂,但总有一些共同点,如果将这些共同点抽取出来,便能更好的提高我们写代码的效率。所以在面向对象的语言中提出了继承的概念,用来抽取事物的共性,实现代码的复用。

1.2 继承的概念

继承机制:在面向对象程序设计中,继承可以让程序员实现代码的复用,也可以让程序员在原有类(父类、基类、超累)的基础上进行属性和供能的扩增,从而产生出新的类,这些新的类被称为派生类,同时也被称为子类。继承实现的主要功能为抽取共性,实现代码的复用。

1.3 继承的语法

在Java中如果要用到继承来表示类之间的继承关系,我们要用到extend关键字。

语法格式:

修饰符 class 子类名 extends 父类名{}

 接下来我们来举一个例子。

以猫和狗为例

我们知道猫和狗有一些共同点,如名字,年龄,颜色,这些都是动物的共性。我们就可以将这些共同点抽取出来,放在一个类中,这个类就是父类。

接着我们分别将猫和狗分别设置为两个类,分别继承父类。然后分别在猫和狗的类中各自实现自己的功能与属性,如猫要吃猫粮,狗要吃狗粮。

代码实现

父类

public class Animal {//共性的抽取public String name;public int age;public String color;
}

狗类

public class Dog extends Animal{public void eat(){System.out.println(this.name+"在吃狗粮");}
}

猫类

public class Cat extends Animal{public void eat(){System.out.println(this.name+"在吃猫粮");}
}

测试类

public class Test {public static void main(String[] args) {Dog dog=new Dog();System.out.println(dog.name = "旺财");System.out.println(dog.age = 6);System.out.println(dog.color = "black");dog.eat();Cat cat=new Cat();System.out.println(cat.name = "咪咪");System.out.println(cat.age = 7);System.out.println(cat.color = "white");cat.eat();}
}

通过测试类我们发现,即使我们没有在Dog类和Cat类中定义了name、age和color的成员变量,但由于都继承了Animal这个父类,所以我们通过Dog类和Cat类创建的对象也可以使用name、age和color这三个成员变量。

运行代码

4dab512e52dd48eb8c92f8518866813e.png

小总结

父类的成员方法和成员变量会被继承到子类中。

 2. 访问成员变量和成员方法

在继承这个机制中,成员变量和成员的方法遵循就近原则。在子类的方法中或者通过子类的对象去访问成员方法或者成员变量时,优先在子类中寻找使用。如果在子类当中没有找到对应的成员变量或者成员方法,在去父类中寻找使用,如果父类和子类中都没有找到,则编译会报错。

2.1 访问成员变量

父类的成员变量和子类成员变量不同名

优先到子类中找对应的成员变量,如果在子类中没找到,再去父类中找,都没找到,就会报错。

class Base{public int a=10;
}
class Derive extends Base{public int b=9;
}
public class Test {public static void main(String[] args) {Derive derive=new Derive();System.out.println(derive.b);}
}

83ed31219520476486a7ca0580e27134.png

 父类的成员变量和子类的的成员变量同名

一样遵循就近原则

class Base{public int a=10;
}
class Derive extends Base{public int a=9;
}
public class Test {public static void main(String[] args) {Derive derive=new Derive();System.out.println(derive.a);System.out.println(derive.a);}
}

2737b9573e3147d387f0de4a86590eb3.png

2.2 访问成员方法

父类的成员方法与子类的成员方法不同名字

遵循就近原则

class Base{public int a=10;public void Base(){System.out.println("Base()被调用......");}
}
class Derive extends Base{public int a=9;public void Derive(){System.out.println("Derive()被调用。。。。。。");}
}
public class Test {public static void main(String[] args) {Derive derive=new Derive();derive.Derive();derive.Base();}
}

1c0a8e522f694391abdad49a8e203791.png

 父类的成员方法与子类的成员方法同名

这里涉及到了方法的重写和动态绑定,后面讲解多态的时候会介绍,这里也先理解为就近原则

class Base{public void Test(){System.out.println("父类的Test()......被调用");}
}
class Derive extends Base{public void Test(){System.out.println("子类的Test()......被调用");}
}
public class Test {public static void main(String[] args) {Derive derive=new Derive();derive.Test();}
}

5b939fa4a5cd477485f7de54f44a097c.png

注意事项:

如果我们通过子类创建的对象去访问父类和子类同名的成员方法时,但是由于父类和子类同名的成员方法的参数列表不同(重载),会根据调用方法时的参数去子类和父类中去寻找合适的成员方法。

class Base{public void Test2(int a){System.out.println("父类Test2(int a)被调用......");}public void Test1(){System.out.println("父类的Test1()被调用......");}
}
class Derive extends Base{public void Test2(){System.out.println("子类的Test2()被调用......");}public void Test1(int a){System.out.println("子类的Test1(int a)被调用......");}
}
public class Test {public static void main(String[] args) {Derive derive=new Derive();int a=10;derive.Test1(a);  //调用子类的Test1(int a);derive.Test1();   //调用父类的Test1();derive.Test2(a);  //调用父类的Test2(int a);derive.Test2();   //调用子类的Test2();}
}

运行代码

220fdc06a2d243819d0733807a7cf771.png

3.super关键字

如果我们要想在子类中直接去访问父类的去访问符类的成员变量和成员方法,要如何操作呢?

答案就是super关键字。通过super关键字我们就能直接在子类中去访问父类的成员变量和成员方法。

class Base{int a=10;public void Test2(int a){System.out.println("父类Test2(int a)被调用......");}public void Test1(){System.out.println("父类的Test1()被调用......");}
}
class Derive extends Base{int a=9;public void Test2(){System.out.println("子类的Test2()被调用......");}public void Test1(int a){System.out.println("子类的Test1(int a)被调用......");}public void Test(){System.out.println(super.a);//调用父类的asuper.Test2(a);//调用父类的Test2(int a)super.Test1();//调用父类的Test1()}
}
public class Test {public static void main(String[] args) {Derive derive=new Derive();derive.Test();}
}

 

cca6a8b7aa174b738e5391e9dd238e06.png

注意事项:

super关键字只能在非静态的函数(不被static修饰的函数)中使用。

 4.子类构造方法

常言道,先有爸爸再有儿子,所以在调用子类的构造方法时,我们要在子类的构造方法中用super关键字去调用父类的构造方法,否则编译器会报错

class Base{public Base(){System.out.println("调用了父类的构造方法");}
}
class Derive extends Base{public Derive(){super();System.out.println("子类的构造方法");}
}
public class Test {public static void main(String[] args) {Derive derive=new Derive();}
}

 

b563b39f124546719b9f77dd88214bae.png

如果父类和子类的构造方法都构成重载,我们会跟据创建对象时传的参数列表,进入子类中对应的构造函数,然后根据子类的构造函数中的super(......) 括号里的参数列表去调用父类中合适的构造方法。

class Base{public int a;public int b;public Base(){System.out.println("调用了父类的构造方法");}public Base(int a,int b){this.a=a;this.b=b;System.out.println("调用了父类中的有参构造方法");}
}
class Derive extends Base{public Derive(){super();System.out.println("调用了子类的构造方法");}public Derive(int a,int b){super(a,b);System.out.println("调用了子类的有参构造方法");}
}
public class Test {public static void main(String[] args) {Derive derive=new Derive(10,20);System.out.println("==================");Derive derive1=new Derive();}
}

5deaf4e6fbe34a8aa417946f2823dbaa.png

 

运行代码

 

9872a3eff9ee4a57ad8bfd8e2e6d61c9.png

注意事项:

1.如果我们没有在子类的构造方法中去调用父类的构造函数,编译器会自动默认子类的构造方法中调用了super()。

class Base{public int a;public int b;public Base(){System.out.println("调用了父类的构造方法");}
}
class Derive extends Base{public Derive(){//super();  没有写,但会默认有System.out.println("调用了子类的构造方法");}
}
public class Test {public static void main(String[] args) {Derive derive1=new Derive();}
}

d297ffb55c134e73869ca1316ec991a4.png

2.super(......)关键字必须位于子类的构造函数的第一行。

3.super(......)只能在子类的构造函数中出现一次,并且不能和this(......)同时出现。 

小总结----super与this的异同点

相同点:

1.super和this都是Java中的关键字。

2.都只能再非静态方法中使用,只能用来访问非静态成员变量和成员方法。

3.在构造方法中使用this和super关键字调用构造方法时,只能位于第一行,并且this(...)和super(...)不能同时存在

不同点:

1.this关键字当前对象的引用,当前对象即本类实例化的对象,super关键字是子类从父类继承的属性和方法的引用。

如下图:

11cfdef2f2c546abb6e382b0ec9ea959.jpeg

2.this关键字使用来调用本类的成员方法和成员变量,super关键字是用来调用父类的成员变量和成员方法。

3.在继承机制的构造方法中,一定存在super调用的构造方法,如果没写,编译器也会默认有。但是如果this(...)没写,那就没有。

5.再谈初始化

在Java中,代码块运行的顺序为静态代码块到实例化代码块再到构造代码块。

那父类和子类这3种代码块的运行先后是怎么样的呢?

我们直接来看代码

class Father{public int age;public Father(){System.out.println("父类的构造代码块");}{System.out.println("父类实例化代码块");}static {System.out.println("父类的静态代码块");}
}
class Son extends Father{public Son(){super();System.out.println("子类的构造代码块");}{System.out.println("子类的实例化代码块");}static {System.out.println("子类的静态代码块");}
}
public class Test {public static void main(String[] args) {Son son1=new Son();System.out.println("=======");Son Son2=new Son();}
}

运行代码

b053bcedb7c34b3fb5fb0ba4de683f73.png

得出结论:

1.先执行父类的静态代码块,再执行子类的静态代码块,并且只执行一次,因为静态代码块是再类的加载成功时运行的,而类的加载只进行一次。

2.执行完静态代码块,再先后执行父类的实例化代码块,父类的构造代码块,最后再分别先后执行子类的实例化代码块和构造代码块。

6.继承方式

再Java中,我们支持单继承,多层继承和不同的多个类继同时承一个类。但是不能一个类同时继承多个类。

如图

45941c1441fc4d8ab16a377b7ce8bf55.jpeg

7.final关键字

1.final修饰的成员变量无法被修改

2.final修饰的类无法被继承

3.final修饰的方法无法被重写 

 

 

 

 

 

 

 

 

 

 

 

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

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

相关文章

CAD2023 2024 2025以上版本出现无法运行 AutoCAD,原因可能如下1) 此版本的 AutoCAD 安装不正确

错误提示如下 此版本的 AutoCAD 安装不正确 缺少依赖组件Microsoft Edge webview2 Runtime 缺少依赖组件 Microsoft.NET跟You must install .NET Desktop Runtime 打开autoremove,点击扩展,输入 无法运行,点击搜索 你的软件属于什么版本…

fork 与 vfork 的区别

关键区别一: vfork 直接使用父进程存储空间,不拷贝。 关键区别二: vfork保证子进程先运行,当子进程调用exit退出后,父进程才执行。 我们可以定义一个cnt,在子进程中让它变成3, 如果使用fork,那…

PHP 7.4开始 调用方法success()可根据参数名称来指定参数值uccess(data: $list, count: $count)

定义了方法: static function success(int $code200,string $msgok,array $data[],int $count0,int $pages1){return [code>$code,msg>$msg,data>$data,count>$count,pages >$pages]; } 引用:(不用按顺序) return self::success(data:…

【LeetCode】【1】两数之和(1141字)

文章目录 [toc]题目描述样例输入输出与解释样例1样例2样例3 提示进阶Python实现哈希表 个人主页:丷从心 系列专栏:LeetCode 刷题指南:LeetCode刷题指南 题目描述 给定一个整数数组nums和一个整数目标值target,请在该数组中找出…

【Vue3进阶】- Vite 配置

视频 Vite 配置 基础配置项 server 选项 本地运行时,开发环境服务器的配置。 host 默认 localhost,设置为 true 或 0.0.0.0 时会监听所有地址,让局域网内的设备进行访问,否则只有本机能访问项目。 open 默认 false&#x…

C#如何通过反射获取外部dll的函数

在C#中,你可以使用反射(Reflection)来加载外部的DLL(动态链接库)并获取其中的函数(在C#中通常称为方法)。但是,请注意,反射主要用于访问类型信息,并且对于非托…

Apache 平滑升级:逐步指南与示例

在维护Web服务器时,Apache的平滑升级是一项重要的操作,它可以确保服务在升级过程中继续对外提供服务,最小化或无需停机时间。本文将详细介绍如何在Linux系统中平滑升级Apache HTTP服务器,提供一个完整的操作示例,并说明…

Typora+PicGo+Gitee设置图床,解决CSDN上传markdown文件图片加载不出来的问题(超级实用)

注: 由于gitee现在已经加上了防盗链,并且只支持1M的图片,我觉得不是很好用(可以买腾讯云或阿里云等),之后找到比较好点的图床工具也会持续更新的。(sm.ms好像还好,github网速不太稳定…

计算机网络 3.5局域网

第五节 局域网 一、认识局域网 1.定义: ①功能性:一组在地理位置上相隔不远的计算机及其设备按照一定的连接方式组织起来的,以实现用户间相互通信的资源共享的网络系统。 ②技术性:由特定类型的传输媒体和网络适配器互联在一起…

基于Vue和uni-app的增强型单选ccRadioView组件开发

标题:基于Vue和uni-app的增强单选组件ccRadioView的设计与实现 摘要:本文将详细介绍如何使用Vue和uni-app构建一个简单、好用且通用的单选框组件ccRadioView。该组件提供了单选列表的功能,并支持反向传值,方便开发者快速实现单选…

太速科技-基于5VLX110T FPGA FMC接口功能验证6U CPCI平台

基于5VLX110T FPGA FMC接口功能验证6U CPCI平台 一、板卡概述   本板卡是Xilinx公司芯片V5系列芯片设计信号处理板卡。由一片Xilinx公司的XC5VLX110T-1FF1136 / XC5VSX95T-1FF1136 / XC5VFX70T-1FF1136芯片组成。FPGA接1片DDR2内存条 2GB,32MB Nor flash存储器&a…

【Java基础】IO流(4) —— 转换流、打印流

【Java基础】IO流(1) —— 简介 【Java基础】IO流(2) —— 字符流 【Java基础】IO流(3) —— 字节流 【Java基础】IO流(4) —— 转换流、打印流 【Java基础】IO流(5) —— 序列流、内存流 【Java基础】IO流(6) —— 随机访问文件流、数据流 转换流 InputStreamReader 是字节输…

【Linux】在Linux中使用date命令

路过了学校花店 荒野到海边 有一种浪漫的爱 是浪费时间 徘徊到繁华世界 才发现你背影 平凡得特别 绕过了城外边界 还是没告别 爱错过了太久 反而错得完美无缺 幸福兜了一个圈 想去的终点 就在原点 🎵 林宥嘉《兜圈》 前言 date命令是Linux系统…

【制作100个unity游戏之28】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版4(附带项目源码)

最终效果 系列导航 文章目录 最终效果系列导航前言僵尸配置僵尸动画移动断头攻击死亡 源码完结 前言 本节主要实现配置僵尸动画,移动,断头,攻击,死亡功能。 僵尸 配置僵尸动画 普通动画 无头动画,新增覆盖图层 …

java实现环形链表带哨兵

双向环形链表带哨兵,这时哨兵既作为头,也作为尾。 package com.tfq.arithmetic.linkedlist;import java.util.Iterator;/*** author: fqtang* date: 2024/05/22/8:40* description: 环形链表*/ public class DoublyLinkedListSentinel implements Iterab…

嵌入式学习——3——IO分类模型

1、阻塞IO和非阻塞IO 1.1 阻塞IO - 在阻塞IO模型中,当一个IO操作(如读取或写入)开始时,如果数据没有准备好,程序会被挂起(即阻塞),直到数据准备好并且IO操作完成。 - 在数据准备阶段…

浏览器API与协议

现代浏览器是一个囊括了数百个组件的操作系统,包括进程管理、安全沙箱、分层的优化缓存、JavaScript虚拟机、图形渲染和GPU管道、存储系统、传感器、音频和视频,网络机制等等。 在浏览器上运行的应用的性能。,取决于多个组件:解析…

SSH反向代理是什麼?有什麼用?

SSH反向代理,也被稱為SSH隧道,是一種利用SSH協議的端口轉發功能,將網路數據通過加密的SSH連接進行傳輸的技術。它的工作原理是,通過SSH連接將本地的一個端口與遠程伺服器的一個端口進行綁定,所有發往本地端口的數據都會…

notepad++ 批量转所有文件编码格式为UTF-8

1、安装notepad及PythonScript_3.0.18.0插件 建议两者都保持默认路径安装x64版本: 阿里云盘分享https://www.alipan.com/s/xVUDpY8v5QL安装好后如下图: 2、new Script,新建脚本,文件名为ConvertEncoding 3、自动打开脚本&#xff…