Java之继承性
为什么要有继承
多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那一个类即可。其中,多个类可以称为子类,单独那一个类称为父类、超类或者基类。
继承的概念
继承:就是子类继承父类的属性和行为,使得子类对象具有与父类相同的属性、相同的行为。子类可以直接访问父类中的非私有的属性和行为。继承描述的是事物之间的所属关系,这种关系是: is-a 的关系。继承的关系中,“子类就是一个父类”,也就是说子类可以被当做父类看待。例如,兔子属于食草动物,食草动物属于动物。可见,父类更通用,子类更具体。我们通过继承,可以使多种事物之间形成一种关系体系。继承主要解决的问题是共性抽取。
好处
- 提高代码的复用性。
- 类与类之间产生了关系,是多态的前提。
继承关系当中的特点
- 子类拥有父类中非私有的属性和行为
- 子类还可以拥有自己独有的属性和行为
继承的格式
通过 extends 关键字,可以声明一个子类继承另外一个父类,定义格式如下:
注意:父类只是一个普通的类
代码举例
定义父类
package MyCode.demo01; // 定义一个父类 public class MyFather { //父类中的成员变量 public int age = 18; //父类中的成员方法 public void method() { System.out.println("我是父类中的方法"); } }
定义子类
package MyCode.demo01; // 定义子类MySon继承MyFather public class MySon extends MyFather { }
定义测试类
package MyCode.demo01; public class MyTest { public static void main(String[] args) { //创建子类对象 MySon son = new MySon(); //子类里面什么代码都没有,但是继承了父类中非私有的方法和属性 son.method(); System.out.println(son.age); } }
代码执行后的结果
继承中成员变量的访问特点
创建父类对象
- 只能使用父类的成员变量,没有任何子类的成员变量
创建子类对象
- 子类对象可以使用本类中的成员变量或者使用父类中非私有的成员变量
- 如果子类父类中出现不重名的成员变量,这时子类对象可以根据不同的成员变量名来访问需要的成员变量。
- 如果子类父类中出现重名的成员变量,这时子类对象有2种访问方式
访问方式1:直接通过子类对象访问成员变量:等号左边是谁,就优先用谁,没有则向上(父类)找。
访问方式2:间接通过成员方法访问成员变量:该方法属于谁,就优先用谁,没有则向上(父类)找
继承中成员方法的访问特点
创建父类对象
- 只能使用父类的成员方法,没有任何子类的成员方法
创建子类对象
- 子类对象可以使用本类中的成员方法或者使用父类中非私有的成员方法
- 访问成员方法的规则:创建的对象是谁,就优先用谁,如果没有则向上(父类)找。
方法重写 (Override)
如果子类父类中出现重名的成员方法,这时的访问是一种特殊情况,叫做方法重写 (Override)。
- 方法重写 :子类中出现与父类一模一样的方法时(返回值类型,方法名和参数列表都相同),会出现覆盖效 果,也称为重写或者复写。简单理解:声明不变,重新实现。
方法重写的注意事项:
1. 必须保证父子类之间方法的名称相同,参数列表也相同。
- tips:@Override:写在方法前面,用来检测是不是有效的正确覆盖重写。这个注解就算不写,只要满足要求,也是正确的方法覆盖重写。
2. 子类方法的返回值必须【小于等于】父类方法的返回值范围。
- tips:java.lang.Object类是所有类的公共最高父类(祖宗类),java.lang.String就是Object的子类。
3. 子类方法的访问权限必须【大于等于】父类方法的权限修饰符。
- tips:public > protected > (default) > private 备注:(default)不是关键字default,而是什么都不写,留空。
重写的应用
子类可以根据需要,定义特定于自己的行为。既沿袭了父类的功能名称,又根据子类的需要重新实现父类方法,从 而进行扩展增强。设计原则:对于已经投入使用的类,尽量不要修改,推荐一个新的类,来重复利用其中共性内容,添加新的内容。
代码举例
定义老款手机
package MyCode.demo02; // 本来的老款手机 public class Phone { public void call() { System.out.println("打电话"); } public void send() { System.out.println("发短信"); } public void show() { System.out.println("显示号码"); } }
定义新款手机类,方法覆盖重写应用。
package MyCode.demo02; // 定义一个新手机,使用老手机作为父类 public class NewPhone extends Phone { //重写父类的来电显示号码功能,并增加自己的显示姓名和图片功能 @Override public void show() { //调用父类已经存在的功能使用super super.show(); //增加自己特有显示姓名和图片功System.out.println("显示来电姓名"); System.out.println("显示头像"); } }
定义测试类
package MyCode.demo02; public class Demo01Phone { public static void main(String[] args) { // 创建子类对象 NewPhone np = new NewPhone(); //调用继承下来的方法 np.call(); np.send(); // 调用子类重写的方法 np.show(); } }
代码执行后的结果
Java关键字this和super用法总结
this关键字含义
- this :代表当前对象的引用(谁调用就代表谁)。
super的含义
- super :代表父类的存储空间标识(可以理解为父亲的引用)。
super关键字用来访问父类内容,用法有三种:
- 在子类的成员方法中,访问父类的成员变量。格式:super.成员变量名
- 在子类的成员方法中,访问父类的成员方法。格式:super.成员方法名
- 在子类的构造方法中,访问父类的构造方法。格式:super(参数列表)
this关键字用来访问本类内容,用法也有三种:
- 在本类的成员方法中,访问本类的成员变量。 格式:this.成员变量名
- 在本类的成员方法中,访问本类的另一个成员方法。 格式:this.成员方法名()
- 在本类的构造方法中,访问本类的另一个构造方法。 格式:this(参数列表)
第三种用法当中要注意:
- this(...)调用也必须是构造方法的第一个语句,唯一一个。
- super和this两种构造调用,不能同时使用。
代码举例
package MyCode.demo03; class Animal { public void eat() { System.out.println("animal : eat"); } }
创建子类Cat
package MyCode.demo03; class Cat extends Animal { public void eat() { System.out.println("cat : eat"); } public void eatTest() { // this 调用本类的方法 this.eat(); // super 调用父类的方法 } super.eat(); } }
创建测试类
package MyCode.demo03; public class Test { public static void main(String[] args) { //创建父类对象Animal Animal a = new Animal(); a.eat(); //创建子类对象 Cat c = new Cat(); c.eatTest(); } }
代码执行后的结果
继承关系中父子类构造方法的访问特点
- 构造方法的名字是与类名一致的。所以子类是无法继承父类构造方法的。
- 子类构造方法当中有一个默认隐含的“super()”调用,所以一定是先调用的父类构造,后执行的子类构造方法
- 子类构造可以通过super关键字来调用父类重载构造。
- super的父类构造调用,必须是子类构造方法的第一个语句。不能一个子类构造调用多次super构造。
- 总结:子类构造方法必须调用父类构造方法,不写则赠送super();写了则用写的指定的super调用,super只能有一个,还必须是第一个。
父类空间优先于子类对象产生
在每次创建子类对象时,先初始化父类空间,再创建其子类对象本身。目的在于子类对象中包含了其对应的父类空间,便可以包含其父类的成员,如果父类成员非private修饰,则子类可以随意使用父类成员。代码体现在子类的构造方法调用时,一定先调用父类的构造方法。
继承的特点
Java只支持单继承,不支持多继承。
//一个类只能有一个父类,不可以有多个父类。 class C extends A{} //ok class C extends A,B... //error
Java支持多层继承(继承体系)。
class A{} class B extends A{} class C extends B{}
子类和父类是一种相对的概念。tips:顶层父类是Object类。所有的类默认继承Object,作为父类。
综合案例:群主发普通红包
- 群主的一笔金额,从群主余额中扣除,平均分成n等份,让成员领取。
- 成员领取红包后,保存到成员余额中。请根据描述,完成案例中所有类的定义以及指定类之间的继承关系,并完成发红包的操作。
案例分析
- 根据描述分析,得出如下继承体系:
代码实现
定义User类
package MyCode.demo05; public class User { private String name; // 姓名 private int money; // 余额,也就是当前用户拥有的钱数 public User() { } public User(String name, int money) { this.name = name; this.money = money; } // 展示一下当前用户有多少钱 public void show() { System.out.println("我叫:" + name + ",我有多少钱:" + money); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getMoney() { return money; } public void setMoney(int money) { this.money = money; } }
定义Manager类
package MyCode.demo05; import java.util.ArrayList; // 群主的类 public class Manager extends User { public Manager() { } public Manager(String name, int money) { super(name, money); } public ArrayList<Integer> send(int totalMoney, int count) { // 首先需要一个集合,用来存储若干个红包的金额 ArrayList<Integer> redList = new ArrayList<>(); // 首先看一下群主自己有多少钱 int leftMoney = super.getMoney(); // 群主当前余额 if (totalMoney > leftMoney) { System.out.println("余额不足"); return redList; // 返回空集合 } // 扣钱,其实就是重新设置余额 super.setMoney(leftMoney - totalMoney); // 发红包需要平均拆分成为count份 int avg = totalMoney / count; int mod = totalMoney % count; // 余数,也就是甩下的零头 // 除不开的零头,包在最后一个红包当中 // 下面把红包一个一个放到集合当中 for (int i = 0; i < count - 1; i++) { redList.add(avg); } // 最后一个红包 int last = avg + mod; redList.add(last); return redList; } }
定义Member类
package MyCode.demo05; import java.util.ArrayList; import java.util.Random; // 普通成员 public class Member extends User { public Member() { } public Member(String name, int money) { super(name, money); } public void receive(ArrayList<Integer> list) { // 从多个红包当中随便抽取一个,给我自己。 // 随机获取一个集合当中的索引编号 int index = new Random().nextInt(list.size()); // 根据索引,从集合当中删除,并且得到被删除的红包,给我自己 int delta = list.remove(index); // 当前成员自己本来有多少钱: int money = super.getMoney(); // 加法,并且重新设置回去 super.setMoney(money + delta); } }
定义测试类
package MyCode.demo05; import java.util.ArrayList; public class MainRedPacket { public static void main(String[] args) { Manager manager = new Manager("群主", 100); Member one = new Member("成员A", 0); Member two = new Member("成员B", 0); Member three = new Member("成员C", 0); manager.show(); one.show(); two.show(); three.show(); System.out.println("==============="); // 群主总共发20块钱,分成3个红包 ArrayList<Integer> redList = manager.send(20, 3); // 三个普通成员收红包 one.receive(redList); two.receive(redList); three.receive(redList); manager.show(); // 100-20=80 // 6、6、8,随机分给三个人 one.show(); two.show(); three.show(); } }
代码执行后的结果
Java之继承性的更多相关文章
- java的继承性
在java继承中,子类也称为派生类,父类也称为基类或者超类,基本语法 :子类 extends 父类{} 实现一个简单的继承类: class Person{ private String name; p ...
- java 面向对象(十二):面向对象的特征二:继承性 (一) 前言
1.为什么要有类的继承性?(继承性的好处) * ① 减少了代码的冗余,提高了代码的复用性 * ② 便于功能的扩展 * ③ 为之后多态性的使用,提供了前提图示: 2.继承性的格式:class A ext ...
- Java学习---基础知识学习
2016-07-23 周六 利用键盘输入的时候需要抛出异常 ,直接快捷键 ctrl + 1 ;定义数组 int score[] = new int[4] ; 只有4个数字BufferedRead ...
- 浅谈Java三大特性之继承
前言 简单用伪代码去介绍一些 父类与子类的构造函数问题 others 前言 类的继承性是面向对象语言的基本特性,多态性前提是继承性.Java 支持继承性和多态性.——Java从小白到大牛 继承:三大特 ...
- JAVASE(九)面向对象特性之 : 继承性、方法重写、关键字super、
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 1.继承性 1.1 为什么要类的继承性?(继承性的好处) ①减少了代码的冗余,提高了代码的复用性:②更好 ...
- java 面向对象(二十四):interface:接口
interface:接口1.使用说明: 1.接口使用interface来定义 * 2.Java中,接口和类是并列的两个结构 * 3.如何定义接口:定义接口中的成员 * * 3.1 JDK7及以前:只能 ...
- Java基础语法,常用知识复习
1.开发环境搭建 1.1JDK.JRE.JVM.的关系 JDK = JRE + 开发工具集(例如javac编译工具集等) JRE = JVM + Java SE 标准类库 2.基本语法 2.1.jav ...
- 尚硅谷Java——宋红康笔记【day11-day18】
day11 Eclipse中的快捷键: * 1.补全代码的声明:alt + / * 2.快速修复: ctrl + 1 * 3.批量导包:ctrl + shift + o * 4.使用单行注释:ctrl ...
- <Android Framework 之路>多线程
多线程编程 JAVA多线程方式 1. 继承Thread线程,实现run方法 2. 实现Runnable接口 JAVA单继承性,当我们想将一个已经继承了其他类的子类放到Thread中时,单继承的局限就体 ...
随机推荐
- 基于cyusb3014的usb3.0双目摄像头开发测试小结(使用mt9m001c12stm)
测试图像 摄像头分辨率为1280*1024,双目分辨率为2560*1024 ps:时钟频率太高,时序约束还得进一步细化,图像偶尔会出现部分雪花,下一步完善
- 【Webpack】373- 一看就懂之 webpack 高级配置与优化
本文原载于 SegmentFault 社区专栏 前海拾贝 作者:JS_Even_JS 一.打包多页面应用 所谓打包多页面,就是同时打包出多个 html 页面,打包多页面也是使用 html-webpac ...
- RT-Thread的位图调度算法分析(最新版)
RT-Thread的内核调度算法 rt-thread的调度算法为基于优先级调度和基于时间片轮转调度共存的策略.rt-thread内核中存在多个线程优先级,并且支持多个线程具有同样的线程优先级.线程级别 ...
- Matlab Robotics Toolbox 仿真计算:Kinematics, Dynamics, Trajectory Generation
1. 理论知识 理论知识请参考: 机器人学导论++(原书第3版)_(美)HLHN+J.CRAIG著++贠超等译 机器人学课程讲义(丁烨) 机器人学课程讲义(赵言正) 2. Matlab Robotic ...
- Elasticsearch系列---补充几个知识点
概要 bulk api有趣的json格式 前面<简单入门实战>一节中,有介绍bulk的使用示例,大家一定很奇怪,还有这么有趣的JSON格式,必须严格照他的换行来做,我想把JSON搞得美观可 ...
- python学习-def1
# 4.可变参数\return# 可变参数:参数个数不固定 .调用的时候来确定有几个参数.# 第一种:*args 在函数内部,是以元组的形式来表示.def my_args(*args): # 放在位置 ...
- windows10查看电脑已经保存的wifi密码
1,打开windows的命令窗口,输入 netsh wlan show profiles,如下图,这个命令仅仅只是查看一下电脑保存的所有的wifi名字 2,需要查看密码的话,则需要输入这个命令, ...
- go 1.13编译遇到xxx/go.mod malformed record data 问题
背景: 公司在做自己的发布平台,需要自动化编译go 工程,大部分开发使用的都是go 1.12 版本 由于go mod的机制,有很多包需要代理才能进行下载,而自动化编译频繁的进行代理切换就很麻烦. 所以 ...
- SpringBoot微服务电商项目开发实战 --- 分布式文件系统实现
SpringBoot分布式开发系列文章已经持续了一段时间了,每一篇都有核心内容讲给大家.比如:分环境部署配置及服务端口号统一配置,子模块版本号管理及第三方jar依赖管理,单点登录实现,接口安全(签名+ ...
- [ASP.NET Core 3框架揭秘] 跨平台开发体验: Windows [下篇]
由于ASP.NET Core框架在本质上就是由服务器和中间件构建的消息处理管道,所以在它上面构建的应用开发框架都是建立在某种类型的中间件上,整个ASP.NET Core MVC开发框架就是建立在用来实 ...