一、 继承的概述
什么是继承?
继承指的是让类与类之间产生关系, 子父类关系, 子类可以使用父类中非私有的成员!
如何实现继承关系?
父类: 基类 超类
子类: 派生类
格式:
class 子类类名 extends 父类类名{}
1. 需要产生一种is..a的关系. --> 分析
2. 发现了两个类之间具有共同的(属性,方法) --> 考虑
继承的好处是什么?
A. 提高了代码的复用性
B. 提高了代码的维护性
C. 是多态的前提.
继承的弊端是什么?
类的耦合性增强了.
开发讲究: 高内聚, 低耦合.耦合: 类与类之间的关系太过紧密
内聚: 自己完成事情的能力.
一个子类是否可以拥有两个父类?
Java中只支持单继承, 不支持多继承, 但是可以多层继承为什么不支持多继承?
如果支持多继承的话, 两个父类中要是有相同的方法, 但是方法的功能主体不同.这时候再创建对象调用方法, 就不知道该走那一段逻辑了.
二、Java继承中成员变量的特点
如果子父类中出现了相同的成员变量, 那么创建子类对象的时候, 用的是谁的成员变量?
如果子父类中出现了相同的成员变量, 那么使用的时候, 优先使用子类的.
就近原则.
三、super关键字的概述和使用
super关键字代表什么?
代表父类的存储空间(代表父类对象的引用)
this和super的区别又是什么?
this:代表当前对象的引用super:代表父类对象的引用
调用成员方向分类:
1. 成员变量
this. : 调用本类的成员变量也可以调用父类的成员变量(前提: 子父类中的成员变量, 不存在相同的.)
super. : 调用父类的成员变量
2. 成员方法
this. : 调用本类的成员方法
也可以调用父类的成员方法(前提: 子父类中的成员方法, 不存在相同的.)
super. : 调用父类的成员方法
3. 构造方法this() : 调用本类构造方法
super() : 调用父类的构造方法
四、Java继承中构造方法的特点
需要搞清楚的是子父类谁先完成初始化的问题子类完成初始化之前, 一定要先完成父类的初始化.
初始化一个类, 我们是通过构造方法进行的.
那就意味着, 子类在创建对象的时候肯定是有一定手段去访问父类的构造方法
重点:
子类的每一个构造方法中都默认含有super()这个语句, 目的就是为了访问父类的空参构造!!!
如果父类没有空参构造子类怎么办?
父类中没有空参, 那么肯定有带参构造.
解决:直接通过super()访问父类的带参构造 !!!推荐!!!
通过this()间接访问:
this先访问本类有参, 本类有参再访问父类有参. !!!不推荐!!!
注意:
建议今后编写代码的时候, 空参有参都手动给出!!
五、Java继承中成员方法的特点
子父类中如果出现了相同的方法, 那么调用的时候将会采用???
如果出现了相同的成员方法, 调用的时候, 执行的是子类的成员方法
(虽然是就近原则的效果, 但是我们一般称之为方法的重写)
重写 : 复写, 覆盖.
成员方法访问特点:
如果子父类中没有出现相同的方法, 那么在调用的时候, 会看子类有没有这个方法.
没有的话, 就调用父类的方法六、方法重写的概述和使用
什么是方法的重写?Overload(重载):
在同一个类中, 方法名相同, 参数列表不同, 与返回值无关.
Override(重写):
在子父类中, 出现了方法声明一模一样的方法.
方法声明一模一样:
指的是参数列表也必须一样.
什么情况下需要使用重写?
当子类需要父类的功能, 而子类又有自己特有的功能主体, 这时候就可以去重写父类的方法.这样做既沿袭了父类的功能, 又定义了子类特有的内容.
简单记: 子类觉得父类的方法不好, 或者说是过于老旧, 那么就可以去重写父类方法.
重写有哪些注意事项?
1. 子类不能重写父类中私有的方法, 继承不到, 就重写不了.2. 子类重写父类方法的时候, 访问权限必须大于等于父类.(最好就一致)
七、多态的概述和代码体现
什么是多态?
事物存在的多种形态.
多态的前提是什么?
A. 要有继承关系B. 要有方法的重写
C. 要有父类引用指向子类对象
八、多态中的成员访问特点
多态调用成员变量
编译看左边(父类), 运行看左边(父类)
解释: 因为是父类的引用, 所以只能看到的是堆内存当中super的一小块区域.多态调用成员方法
编译看左边(父类), 运行看右边(子类)
解释: 动态绑定机制, 在编译的过程中, 会检查父类中没有没有此方法.有: 编译通过, 但是运行的时候走的是子类的方法
没有: 编译失败.
多态调用静态方法
编译看左边, 运行看左边.
多态的好处和弊端好处:
1. 提高了代码的复用性
2. 提高了代码的维护性
-----因为有继承关系, 所以继承的好处也就挪用过来了----
3. 提高了代码的扩展性 !
弊端:
不能调用子类特有的属性和行为.
如何解决?
↓ 向下转型
九、多态中的转型问题
隐式转换:概念: 将小的数据类型直接赋值给大的数据类型
// 向上转型(多态创建对象)
强制类型转换:概念: 将大的数据类型赋值给小的数据类型
// 向下转型
为什么要学习向下转型呢?目的就是为了在多态创建对象之后, 有办法能够调用子类特有的属性和行为!!
注意: 向下转型的强转, 必须发生在子父类的关系当中, 而且必须先转上去, 才能转下来.
ClassCastException : 类型转换异常, 原因: 出现了错误的强转.关键字: instanceOf
判断左边的引用, 是否是右边的数据类型
练习:
分析以下需求,并用代码实现:
1.定义员工类:
属性:
工号,姓名
行为:
工作方法(用简单的输出语句模拟)
2.定义经理类:
属性:
工号,姓名,奖金
行为:
工作方法(管理员工,简单输出语句模拟)
3.定义服务员类:
属性:
工号,姓名
行为:
工作方法(为客户服务,简单输出语句模拟)
4.定义测试类:
分别创建经理类对象和服务员类对象
调用各自的工作方法
要求:
分析各个事物之间的继承关系,抽取出相关的类
public class Ex04 {
public static void main(String[] args) {
howToWork(new E04_Manager());
howToWork(new E04_Waiter());
}
private static void howToWork(E04_Employee e){
e.work();
}
}
class E04_Employee{
private String id;
private String name;
public void work(){
System.out.println("员工工作");
}
public E04_Employee() {
super();
}
public E04_Employee(String id, String name) {
super();
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class E04_Manager extends E04_Employee{
private double bonus;
@Override
public void work() {
System.out.println("经理工作");
}
public E04_Manager() {
super();
}
public E04_Manager(String id, String name,double bonus) {
super(id, name);
this.bonus = bonus;
}
public double getBonus() {
return bonus;
}
public void setBonus(double bonus) {
this.bonus = bonus;
}
}
class E04_Waiter extends E04_Employee{
@Override
public void work() {
System.out.println("服务员工作");
}
public E04_Waiter() {
super();
}
public E04_Waiter(String id, String name) {
super(id, name);
}
}