JAVA基础学习——Day13(多态)

本文回顾了面向对象编程的三大特性:封装保护数据,继承提升代码复用,多态实现行为多样性。通过实例解析了继承原则、访问权限、构造方法调用顺序,以及多态的实现条件。还探讨了包访问、继承权限、final关键字的应用和类间关系。
摘要由CSDN通过智能技术生成

一、day12复习部分

1. 面向对象的三大特征:封装,继承,多态

(1)封装:保护性和易用性

(2)继承:提高代码的复用性,方便进行子类,子功能的拓展,将所有共性的内容放在父类,子类只需要关注子类独有的属性和方法

A. 要使用继承,必须满足is a 原则

例如:Dog is an animal

           Cat is an animal

B. 使用extends关键字表示继承父类

C. 继承分为显示继承和隐式继承

a. 隐式继承:父类中的private域,子类实际上也继承下来了,属于隐式继承,无法直接使用

b. 显示继承:父类中的public, protected等域,属于显示继承,子类中可以直接使用

D. super关键字

a. super修饰属性:表示直接从父类中寻找同名属性

b. super修饰方法:

<1>super修饰构造方法

在实例化子类对象的时候,先调用父类的构造方法产生父类对象,而后使用子类构造方法产生子类对象

若父类中只有无参构造,则子类构造方法中可以省略super();

若父类中只有有参构造,则子类构造方法首行必须显示调用super(参数);表示调用父类的构造方法(注:一般在继承关系的子类中只保留super的首行调用,不会出现this修饰构造方法)

<2>super修饰成员方法:表示直接从父类中寻找同名方法

c. this可以表示当前对象的引用,但是super不能直接指代父类对象

2. 包访问权限 default

(1)权限修饰符不写,默认是包权限。

(2)当前包的内部且同级目录下可见,子包都不可见

(3)JDK中常用的包

java.lang         java.util         java.sql          java.net        java.io

二、封装和包作业

1. 例题1

解析:答案为C。name属性在父类中是private权限,因此属于隐式继承,子类中无法直接使用

 2. 例题2

解析:

答案选c。

a. 包是一组类的集合没错

b. 不同包之间类可以同名

c. import的导入的是一个类而并不是一个包。

d. import static是静态导入,静态导入能导入方法也能导入类

3. 例题3

解析:生成子类对象的时候要先生成父类对象,也就是先调用父类的构造方法,再调用子类的构造方法 。因此答案为B

4. 例题4

 解析:答案选D。父类中没有无参构造,因此子类中的构造方法中必须用super(参数)显示的调用父类中的有参构造,此题目中没有,因此编译错误

 5. 例题5

 解析:答案选C。

new z();要产生子类对象z必须产生父类对象x。在父类对象中Y y = new y(); 这一步实在x的构造方法中执行且优先于打印方法,因此答案为YXYZ.

注意:类属性的就地初始化实际上也在构造方法中执行,且优先于构造方法中的打印部分。

 6. 例题6

 解析:

答案选A

A: super是从父类中寻找同名属性和同名方法

B: this表示对当前对象的引用,super只能指代直接父类,不能指代父类的父类

CD: 子类可以通过super关键字调用父类的方法和父类的属性,因此CD都错

7. 一个额外的题目(非常重要!!!):已知下列代码,求执行顺序

(1)补充知识:

A. 什么时候加载类:用的时候加载类

B. 加载具有继承关系的子类:先加载起父类,再加载子

(2)解析

A. 主方法位于子类D中,要执行主方法首先要加载主类D,主类D继承于主类B中,因此需要先加载父类再加载子类。

加载类就要执行静态块代码,因此

3 6

B. 主方法内第一句执行7

C. 之后产生对象:构造块优先于构造方法执行,父类对象创建优先于子类对象

因此顺序为

2154 2154

D. 主方法最后一句执行8

因此顺序为367215421548

二、继承收尾

1. 关于继承访问权限protected关键字:不同包的具有继承关系的类之间可见

2. 不同包的具有继承关系的类之间可见,下面是示例

(1)示例1

 

 

 (2)示例2:不同包下不具备继承关系类之间不可见

 3. 注意1(重中之重):

4. 在同一个包的毫无关系的不同类之间,protected修饰的属性和方法当然可见(default是同一个包内不同类之间都可见,protected权限大于default)

(1)原理

(2)示例: 

 5. 继承关系(注意:Java的单继承局限:一个类只能使用extends直接继承一个父类,不允许多继承,但是允许多层继承

 

 6. final关键字:终结器-到此为止

(1)final 修饰的属性称为常量,一旦被final修饰,则变量成为常量,一旦初始化后,数值不能修改

A. final修饰基本数据类型

 B. final修饰引用数据类型

 C. 总结:

 D. final修饰的变量使用前必须赋值

(2)final修饰方法=>被final修饰的方法无法被重写/覆写

(3)final修饰类=>被final修饰的类不能有子类 (JDK中的String类就是final类)

7. 类和类之间的关系

(1)继承:继承表示的是类之间的is a 关系

(2)组合:组合表示的是类之间的has a关系 

例如:School has a Student; School has a Teacher

(3)二者的联系:组合和继承都可以实现代码复用,到底使用继承还是组合要用上述的is a 还是 has a来判断

组合关系也可以实现代码的复用,组合类的内部包含了其他类,直接调用其他类对象的属性和方法实现代码复用

 三、多态

1. 多态含义:同样一个方法/行为,经过不同的对象,表现出不同的行为,这样的现象称为多态。

两不同一相同:不同的对象调用相同的方法表现出不同的行为,称为多态性

例如:

 2. java中要想实现多态,必须同时满足一下三个条件

(1)多态的实现必须依赖于继承,在继承体系下才有多态。只有在继承关系的类之间才有多态

(2)子类必须要覆写父类中的方法

(3)通过父类的引用调用子类重写的方法 

以下是多态实例

 

 3. 方法重写(override)

(1)定义:

A. 在有继承关系的类之间,

B. 子类定义了和父类除了权限不同以外,(权限:子类重写方法的权限>=父类方法,父类方法权限>private)

C. 其他(方法名称,参数列表,返回值类型(向上转型类除外))全部相同的方法,称为子类重写了父类的方法。

(2)对比方法重载(overload):在同一个类中,定义了一组方法名称相同,参数列表(个数和类型)不同的,与返回值无关的一组方法,称为重载方法。(重载不需要考虑权限,因为都在一个类中,即便最小的private权限也是当前类内部可见)

(3)方法重写的权限问题,以实例说明

A. 例子:子类Teddy覆写了父类Dog中的bark方法。若父类是public,则子类也必须是public

 B. 若父类是deafult,在子类可以是deafult,proctected, public

 

 

 (4)方法重写不包含私有方法的重写!私有继承,子类根本不知道父类存在这个私有方法。所谓的重写,即为在父类现有方法上进行覆盖,因此能够方法重写的前提是子类能够看得见父类中需要重写的方法

父类中用private

子类中用其他

(5)static方法不能重写

原理:重写是为了多态服务的,多态是不同的对象调用相同的方法呈现出不同的行为,也就是重写方法和具体对象有关。而static方法和类强相关和具体对象无关,因此不存在重写

(6)构造方法不能被重写

重写相当于在子类中,改变了父类的方法行为,以当前子类的方法行为为准

构造方法是初始化对象的属性的,假设构造方法能够被重写,相当于在子类中改变了父类构造方法的行为,相当于在子类中决定了父类对象的产生

(7)重写的作用

(8)一组概念

A. 动态绑定——方法重写:编译时无法确定到底调用的是哪个对象的方法,只有在运行时,根据具体传入fun的对象,才能知道到底调用的是哪个对象的方法,这就叫做动态绑定。即运行时明确调用的是哪个方法

B. 静态绑定——方法重载:编译时,编译器根据用户传参的不同决定到底调用哪个方法

(9)向上转型(天然发生,也是产生对象的主要使用方式)

A. 语法

父类名称 父类引用 = new 子类构造方法(参数);

例如:Animal animal = new Dog("66", 6);

B. 如何确定是不是向上转型,代码从右往左读,如果满足继承关系的is a 原则,即为天然的向上转型

例如:Animal animal = new Dog("66", 6); //dog is an animal,因此是天然的向上转型

C. 原理

D.  向上转型的调用规则:

a. 父类引用决定能调用什么:到底通过这个父类引用能够调用哪些属性和方法,看父类中有哪些属性和方法

b. 子类决定方法表现的具体行为:调用的方法到底表现出什么行为,看到底new的是哪个子类对象。若该子类对象覆写了父类的方法,则调用的是子类覆写后的方法,否则调用的是父类中的方法

实例如下

 

 

 E. 向上转型带来的程序上的优势:参数统一化

例子:

 a. 若不存在向上转型,引用只能指向当前类型的对象

则需要定义N个重载fun方法,参数的类型不同,用于接收不同类型的对象,如下图代码

 缺点:每当产生一个新的子类都需要重载一个对应的fun方法。出现大量的代码冗余;不方便子类的拓展。

b. 存在向上转型好处,

 如下面代码所示

 (10)向下转型(大类型转换为小类型,需要强制类型转换,要发生向下转型,一定先发生向上转型)

A. 向上转型的存在的问题引出向下转型

问题:向上转型只能调用父类中存在的方法,子类中独有的方法无法通过向上转型的父类引用调用。这个问题需要通过向下转型来解决。

 B. 语法:

注意: 向下转型当且仅当存在继承关系的类之间才能转换成功,否则会转换失败

子类名称 子类引用 = (子类名称和前面一致) 父类引用(向上转型后的父类引用)

例如:Dog dog = (Dog) animal; //

C. 实例

 D. 实例2:转换失败,编译时不会报错,运行时会报类型转换异常

 (11)instanceof关键字:用来判断一个引用是否指向一个子类实例,返回值为布尔类型

A. 语法:

引用名称 instanceof 子类

B. 应用:可以用来判断一个父类引用是否指向一个子类实例,来判断是否能进行向下转型

C.示例 

 

  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值