Java面向对象笔记 • 【第3章 继承与多态】
全部章节 >>>>
本章目录
3.1 包
生活工作中的包、文件夹
管理计算机程序和文件的目录结构
3.1.1 自定义包
如果在程序中没有声明包,类将被存放在default的包中,该方式不被提倡。
语法:
package 包名
包命名规范:
包的命名规范应当体现出项目资源良好的划分
自定义标签类所在包命名规范:公司名称.开发组名称.项目名称
例如:com.java.explorer
声明一个包的语句必须写在类中的第一行
3.1.2 包的导入
语法:
import 包名.类名
示例:
import java.util.*; //导入java.util包中所有的类
import java.util.ArrayList; //导入java.util包中的ArrayList类
示例:在Hero类中使用Tree类,Hero类与Tree类不在同一个包中
package com.java.oriented.dota.scene;
public class Tree {
public void clear(){
//具体业务逻辑
}
}
package com.java.oriented.dota.figure;
//由于Tree类与Hero类不在同一个包中,所以需要使用import关键字导入包
import com.java.oriented.dota.scene.Tree;
public class Hero {
public void eatTree(Tree tree){
//调用树对象的clear()方法,吃掉的树在地图中消失
tree.clear();
}
}
3.1.3 包的访问权限
一个包中具有缺省访问权限的成员只能在同一个包中被引用。
如果一个包中的成员的访问权限为 public,那么这些成员才能被其他包中的类所引用。
以上“成员”特指类、属性和方法。
public成员可以被其他包中的类访问,public类中的protected成员可以被由它派生的在其他包中的子类访问。
package com.java.oriented.dota.scene;
public class Tree {
void clear(){ //去掉public
//具体业务逻辑
}
}
package com.java.oriented.dota.figure;
//由于Tree类与Hero类不在同一个包中,所以需要使用import关键字导入包
import com.java.oriented.dota.scene.Tree;
public class Hero {
public void eatTree(Tree tree){
//调用树对象的clear()方法,吃掉的树在地图中消失
tree.clear();
}
}
3.1.4 实践练习
3.2 继承
继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例 域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
生活中的继承:
3.2.1 继承概述
- 继承是面向对象程序设计的一个重要特征,它是通过继承原有类派生出子类,进而构造出更为复杂的子类。
- 子类既有新定义的行为特征,又继承了原有类的行为特征。
- 父类与子类存在着包含与被包含的关系,是一种is-a的关系。
- 在Java中继承可以在现有类的基础上进行功能的扩展,这样能够更加快速地开发出新类,使新类不仅可以复用当前类的特征和行为,而且还可以定义自己的特征和行为。
- 通过继承可大幅度提高代码的复用性,减少代码量,便于程序的后期维护。
Java继承语法:
[修饰符] class 子类名 extends 父类名{
//类定义部分
}
父类也称作基类或超类
3.2.2 继承的实现
示例:定义父类武器,以及子类圣剑和长矛
public class Weapon { //父类 武器
String name;//武器名
int attackValue;//攻击值
//构造方法
public Weapon(String name, int attackValue) {
System.out.println("--执行武器父类Weapon的构造方法--");
this.name = name;
this.attackValue = attackValue;
}
//攻击方法
public void attack(){
System.out.println("武器名:"+name+"\t"+"攻击
值:"+attackValue);
}
}
public class Sword extends Weapon{ //圣剑 子类
public Sword(String name, int attackValue) {
super(name, attackValue);
}
}
public class Spear extends Weapon{ //圣剑 长矛
//构造方法
public Spear(String name,int attackValue) {
super(name, attackValue);
}
}
public class ExtendsTest { // 测试类
public static void main(String[] args){
Sword word = new Sword("圣剑",300);
word.attack();
Spear spear = new Spear("长矛",250);
spear.attack();
}
}
3.2.3 实践练习
3.3 重载和重写
3.3.1 重载
- 方法重载是让类以统一的方式处理不同类型数据的一种手段。
- Java的方法重载,就是在类中可以创建多个方法,它们具有相同的名字,但具有不同的参数和不同的定义。调用方法时通过传递给它们的不同参数个数和参数类型来决定具体使用哪个方法。
- 方法重载也是多态的一种体现。
方法重载的规则:
方法名称必须相同。
参数列表必须不同(个数不同、或类型不同、参数排列顺序不同等)。
方法的返回类型可以相同也可以不相同。
仅仅返回类型不同不足以成为方法重载。
注意:
参数列表不同包括:个数不同、类型不同和顺序不同。
仅仅参数变量名称不同是不可以的。
跟成员方法一样,构造方法(构造器)也可以重载。
声明为final的方法不能被重载。
声明为static的方法不能被重载,但是能够被再次声明。
示例:在Book类中定义3个互为重载的方法,它们分别计算不同情形下图书的价格。
public class Book {
//定义3个重载方法
public float getPrice(){
return 100;
}
public float getPrice(int page){
return (float)(page*0.1);
}
public float getPrice(int page ,float discount){
return (float) (page*discount);
}
public static void main(String[] args) {
Book book=new Book();//创建Book对象
System.out.println("default图书价格:"+book.getPrice());
System.out.println("根据页数计算图书价格:"+book.getPrice(268));
System.out.println("根据页数和折扣计算图书格:"+book.getPrice(360,0.2f));
}
}
3.3.2 重写
在子类中可以根据需要对从父类中继承来的方法进行重写。
重写的方法和被重写的方法必须具有相同方法名称、参数列表和返回类型。重写方法不能使用比被重写的方法更严格的访问权限。
重写方法不能声明抛出比被重写方法范围更大的异常类型。
重写是外壳不变,核心变。也就是说方法名不变,参数不变,具体实现可以改变。一般是在父类中声明方法,在子类中重写。重载是方法名不变,但参数一定要变。而且重载的方法一般都写在一个类中。
提醒:
重写是子类对所继承父类相同方法的一种更改,这个更改需要遵循格式按照父类的格式。
子类重写方法的访问权限,抛出异常等等,都需在父类方法的控制范围之内,但其内部的具体实现可以不同。
子类重写方法的返回值可以为父类中被重写方法返回值的子类型;如果方法参数若为子类类型,则它们是重载而不是重写。
示例:在子类鸵鸟中重写父类飞鸟的飞翔方法
public class Bird { // 父类 飞鸟
//Bird类的fly()方法
public void fly(){
System.out.println("我在蓝天白云间自由的飞翔...");
}
}
public class Ostrich extends Bird{// 子类 鸵鸟
public void fly(){ //重写父类方法
System.out.println("我只能在陆地上拍拍翅膀奔跑...");
}
public void prey(){ //捕食方法
fly();
System.out.println("执行捕食方法");
}
public static void main(String[] args) {
Ostrich ostrich=new Ostrich();
ostrich.prey(); //调用ostrich对象的prey()
}
}
3.3.3 重写覆盖问题
子类方法的覆盖使子类“隐藏”了父类中的方法。
如果需要访问被子类覆盖的方法,则可使用super关键字指明调用父类被覆盖的实例方法。
示例:子类鸵鸟捕食时将使用父类飞鸟的飞翔功能。
public class Ostrich extends Bird{
public void fly(){
System.out.println("我只能在陆地上拍拍翅膀奔跑...");
}
//捕食方法
public void prey(){
//在prey()方法中使用super关键调用父类的fly()方法
super.fly();
System.out.println("执行捕食方法");
}
public static void main(String[] args) {
//创建Ostrich对象
Ostrich ostrich=new Ostrich();
ostrich.prey();//调用ostrich对象的fly()
}
}
3.3.4 实践练习
3.4 多态
从一定角度来看,封装和继承几乎都是为多态而准备的。
多态是指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。
多态是指同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。
在编译时,可以通过父类的引用指向子类对象,而在运行时,则通过父类所指向的子类对象,调用子类中重写父类的方法。
3.4.1 多态应用
示例:指向子类的父类引用在执行重写方法时所体现的多态性
//父类 人物
public class Figure {
protected String name;
public void attack(){
//此处不进行具体的攻击操作,不同职业的英雄攻击方式不同
}
public void run(){
System.out.println("在奔跑");
}
}
//子类 战士
public class Warrior extends Figure{
//重写父类的attack()方法
public void attack(){
System.out.println(this.name+"正在物理攻击......");
}
}
//子类 法师
public class Master extends Figure {
//重写父类的attack()方法
public void attack(){
System.out.println(this.name+"正在魔法攻击......");
}
public static void main(String[] args) {
Figure master=new Master();
master.name="恶魔巫师";
Figure warrior=new Warrior();
warrior.name="撼地神牛";
master.attack();
warrior.attack();
}
}
3.4.2 引用变量的强制类型转换
示例:调用父类引用的方法没有在父类进行定义
//子类 法师
public class Master extends Figure {
//重写父类的attack()方法
public void attack(){
System.out.println(this.name+"正在魔法攻击......");
}
//子类特有的轰炸功能
public void bomb(){
System.out.println(this.name+“正在魔法轰炸......");
}
public static void main(String[] args) {
Figure figure=new Master();
figure.name="恶魔巫师";
figure.attack();
figure.bomb(); //此处编译出错
}
}
分析:
引用变量只能调用其编译时类型的方法,而不能调用运行时类型的方法,即 使实际所引用的对象确实包含该方法。
如果需要让引用变量调用运行时类型的方法,则必须将其强制类型转换为运 行时类型,强制类型转换需借助于类型转换运算符。
3.4.3 instance of 运算符
instance of 运算符用于判断一个实例是否为某个类的实例
语法:
a instanceof A
判断实例a是否为类A的实例,如果为真则返回true,否则返回false。
//子类 法师
public class Master extends Figure {
//重写父类的attack()方法
public void attack(){
System.out.println(this.name+"正在魔法攻击......");
}
//子类特有的轰炸功能
public void bomb(){
System.out.println(this.name+“正在魔法轰炸......");
}
public static void mafigurein(String[] args) {
Figure figure=new Master();
figure.name="恶魔巫师";
figure.attack();
if(figure instanceof Master )
Master master = (Master)figure; // 使用向下类型转换
master.bomb(); //成功调用Master类的bomb
}
}
3.4.4 实践练习
总结:
- 声明包的语句是“package 包名”,该语句必须放在第一行,导入类的语句是 “import 包名.类名”。
- 继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例 域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
- 子类继承父类的语法是:“[修饰符] class 子类名 extends 父类名”。
- 重载就是在类中可以创建多个方法,它们具有相同的名字,但具有不同的参数和不同的定义。
- 重写就是在子类方法重写父类方法,重写的方法和被重写的方法必须具有相同方法名称、参数
- 列表和返回类型。
- 多态是指同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。
- 在编译时,可以通过父类的引用指向子类对象,而在运行时,则通过父类所指向的子类对象,调用子类中重写父类的方法。
Java面向对象笔记 • 【第3章 继承与多态】的更多相关文章
- Java 学习笔记 ------第六章 继承与多态
本章学习目标: 了解继承的目的 了解继承与多态的关系 知道如何重新定义方法 认识java.lang.object 简介垃圾回收机制 一.继承 继承是java面向对象编程技术的一块基石,因为它允许创建分 ...
- Java面向对象编程:封装,继承,多态
Java面向对象的三大特征: 封装:通过Java的类来实现数据和操作方法的封装,对外界可以将每一个Java类都视为一个黑箱,只需调用该黑箱提供的方法即可完成你想要的操作. 继承:通过类的继承,将统一的 ...
- Java学习笔记 07 接口、继承与多态
一.类的继承 继承的好处 >>使整个程序架构具有一定的弹性,在程序中复用一些已经定义完善的类不仅可以减少软件开发周期,也可以提高软件的可维护性和可扩展性 继承的基本思想 >>基 ...
- java面向对象编程— —第七章 继承
7.1继承的起源 继承(Inheritance),即在面向对象编程中,可以通过扩展(extends)一个已有的类,并继承该类的属性的行为,来创建一个新的类. 已有的类称为父类(也可以称为基类,超类), ...
- 中国MOOC_面向对象程序设计——Java语言_第4章 继承与多态_第4周编程题_将MP3媒体类型存放进Database
本周我们介绍了以继承方式实现的媒体资料库,在课程代码实现的基础上,请实现一个表达MP3的媒体类型,能和CD.DVD一样存放进这个Database.请提交这个MP3类的代码.如果你认为为了能存放MP3, ...
- [core java学习笔记][第五章继承]
5.1 类.超类和子类 定义 class Manager extends Employee { 添加方法和域 } 权限 派生类不能使用基类的私有变量 派生类调用基类的方法 利用super这个关键词 s ...
- 《Java核心技术·卷Ⅰ:基础知识(原版10》学习笔记 第5章 继承
<Java核心技术·卷Ⅰ:基础知识(原版10>学习笔记 第5章 继承 目录 <Java核心技术·卷Ⅰ:基础知识(原版10>学习笔记 第5章 继承 5.1 类.超类和子类 5.1 ...
- Java学习笔记二十一:Java面向对象的三大特性之继承
Java面向对象的三大特性之继承 一:继承的概念: 继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类. 继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方 ...
- Java面向对象程序设计第9章1-9
Java面向对象程序设计第9章1-9 1. 线程和进程的联系和区别是什么? 联系: 一个进程可以包括多个线程. 区别: 进程: 进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动,它是系统 ...
- 20145330《Java学习笔记》第一章课后练习8知识总结以及IDEA初次尝试
20145330<Java学习笔记>第一章课后练习8知识总结以及IDEA初次尝试 题目: 如果C:\workspace\Hello\src中有Main.java如下: package cc ...
随机推荐
- 机器学习常用python包
(py37) ai@ai:~$ pip freeze |grep -v '@' astor==0.8.1 certifi==2021.5.30 chardet==4.0.0 cycler==0.10. ...
- 【Git项目管理】Git分支 - 远程分支
远程分支 远程引用是对远程仓库的引用(指针),包括分支.标签等等. 你可以通过 git ls-remote (remote) 来显式地获得远程引用的完整列表,或者通过 git remote show ...
- [学习总结]3、Android---Scroller类(左右滑动效果常用的类)
参考资料:http://blog.csdn.net/vipzjyno1/article/details/24592591 非常感谢这个兄弟! 在android学习中,动作交互是软件中重要的一部分,其中 ...
- Linux基础命令---mysqlshow显示数据库
mysqlshow mysqlshow是一个客户端的程序,它可以显示数据库的信息.表信息.字段信息. 此命令的适用范围:RedHat.RHEL.Ubuntu.CentOS.Fedora. 1.语法 ...
- 理解JMX之介绍和简单使用
JMX最常见的场景是监控Java程序的基本信息和运行情况,任何Java程序都可以开启JMX,然后使用JConsole或Visual VM进行预览.下图是使用Jconsle通过JMX查看Java程序的运 ...
- FastJson简介
FastJson简介 首先,介绍一下fastjson.fastjson是由alibaba开源的一套json处理器.与其他json处理器(如Gson,Jackson等)和其他的Java对象序列化反序列化 ...
- 1.RabbitMQ
1.RabbitMq是什么? MQ全称为Message Queue,即消息队列, RabbitMQ是由erlang语言开发,基于AMQP(Advanced Message Queue 高级消息队 ...
- Apache Log4j 2 报高危漏洞,CODING 联手腾讯安全护卫软件安全
导语 12 月 9 日晚间,Apache Log4j 2 发现了远程代码执行漏洞,恶意使用者可以通过该漏洞在目标服务器上执行任意代码,危害极大. 腾讯安全第一时间将该漏洞收录至腾讯安全漏洞特征库中,C ...
- 资源日历关联(Project)
<Project2016 企业项目管理实践>张会斌 董方好 编著 其实,[日历]并不是[任务]的唯一,他还有另一个老相好:[资源]. 是啊,就像张同学给的例子那样,得为一个专门的外聘专家这 ...
- CF803B Distances to Zero 题解
Content 有一个长度为 \(n\) 的序列 \(a_1,a_2,a_3,...,a_n\),求每个数与它最近的 \(0\) 的距离(\(0\) 的距离为 \(0\)). 数据范围:\(1\leq ...