04.抽象类
1.抽象类和抽象方法的定义:
- 抽象类是一种特殊的父类,因为在其内部可以定义抽象方法.
- 抽象方法:子类共有的属性被抽取到父类中,但是在父类中无法明确的描述出该属性(不同子类属性特点不同,但是属于同一个属性)
- 抽象方法必须在抽象类中才能存在
2.抽象类和抽象方法的格式:
-
抽象类
public abstract void 类名 ();
-
抽象方法
public abstract class 方法名()3
3.抽象类和抽象方法的特点
- 抽象类不能实例化,因为内部的抽象方法没有逻辑,调用没有意义,所以通过不允许实例化来避免调用内部的抽象方法.
- 抽象方法强制要求子类重写.
- 抽象类除了内部有抽象方法且不可以实例化以外,和普通类一样
4.抽象类的成员特点
- 成员变量: 可以是常量,也可以是变量
- 成员方法:可以是抽象方法,也可以是普通方法(普通方法是为了子类可以直接继承使用)
- 构造方法:抽象类有构造方法,目的是交给子类通过super();进行访问
5.抽象方法(abstract修饰的方法)中关键字的冲突问题
- private : 抽象方法(abstract修饰的方法)强制要求子类重写,但是private修饰的私有化方法不允许子类重写,因此会产生冲突.
- final : 抽象方法(abstract修饰的方法)强制要求子类重写,但是final修饰的方法不允许子类重写,因此会产生冲突.
- static : 被static修饰的方法可以通过类名直接去调用,被abstract修饰的方法是抽象方法,抽象方法没有具体逻辑,但是直接调用一个没有具体逻辑的方法没有意义,因此产生冲突.
05.接口
1.接口的介绍
接口是对规则的声明,当一个类中的所有方法都是抽象方法时,就可以把这个类改写成一个接口
2.接口的各种格式
-
定义格式:
public interface 接口名 {}
-
实现格式:
public class 类名 implements 接口名 {}
-
接口的实现类(子类):
-
重写所有抽象方法(推荐)
-
将实现类变为抽象类(不推荐)
-
3.接口中的成员特点
- 成员变量 : 只能是常量,因为默认被 public static final 这三个关键字修饰(这三个关键字没有顺序关系)
- 成员方法:只能是抽象方法,因为默认被public abstract这两个关键字修饰
- 构造方法 : 接口中没有构造方法
4.接口和类之间的各种关系
- 类和类的关系 : 类与类之间只有继承关系,继承关系只能单继承或者多层继承,不能多继承
- 类和接口的关系 : 类和接口之间是实现关系,可以多实现,也可以单实现,也可以继承一个类的同时,实现一个或多个接口
- 接口和接口的和关系 : 接口和接口之间是继承关系,可以单继承也可以多继承
5.接口和抽象类的区别
设计理念 | 成员变量 | 成员方法 | 构造方法 | 子类(实现类) | |
---|---|---|---|---|---|
抽象类 | 主要是对事物做抽象,是对事物进行描述 | 可以是常量,也可以是变量 | 可以有抽象方法,也可以有普通方法 | 有构造方法,方便子类通过super();调用访问 | 可以重写所有的抽象方法(推荐) ,也可以将子类变成抽象类(不推荐) |
接口 | 主要是对行为做抽象,是在制定行为的规则 | 只能是常量,因为默认被public static final这三个关键字修饰 | 只能是抽象方法,因为默认被public和abstract这两个关键字修饰 | 没有构造方法 | 可以重写所有的抽象方法(推荐) ,也可以将实现类变成抽象类(不推荐) |
06.多态
1.多态的前提
- 要有继承或者实现的关系
- 要有方法重写
- 要有父类引用指向子类对象
2.多态的分类
-
对象多态 : 父类引用指向子类对象
将形参设为父类类型,就可以接收任意子类对象
Fu f = new Zi(); Animal a = new Dog(); OrderService order = new OrderServiceImpl();
-
行为多态 : 同一个行为(方法),在不同时刻有不同的表现形式
public static void useAnimal (Animal a){ a.eat(); } //调用的方法是 eat (); //传入的对象不同, eat方法就会有不同的表现 useAnimal(new Dog()); //狗吃肉 useAnimal(new Cat()); //猫吃鱼
3.多态的成员访问特点
- 成员变量 : 编译看父类,运行看父类,因为父类引用只能看见堆内存中子类空间中的super部分
- 成员方法 : 编译看父类,运行看子类,因为怕父类中的方法是一个抽象方法
- 静态成员 : 编译看父类,运行看父类只是现象 ,原因是静态对象通过类名调用,哪怕代码是通过对项目调用,在编译时也会自动转换成类名调用.
4.多态的好处和弊端
- 好处 : 提高代码扩展性:将形参设为父类类型,就可以接收任意子类对象
- 弊端 : 无法直接访问子类特有属性
5.多态转型
-
向上转型 : 从子类到父类,即父类引用指向子类对象,可以参考隐式转换理解
Fu f = new Zi();
-
向下转型 : 在多态中,无法直接访问子类特有的属性,如果要访问,就要通过向下转型,即从父类到子类,可以参考强制转换理解
Zi z = (Zi) f;
-
多态转型存在的安全隐患 : 如果被转的引用类型变量,对应的实际类型和目标类型不是同一种类型,那么在转换时,就会出现ClassCastException
public static void use(Person p) { Student s = (Student) p; s.study(); } use(new Student()); // 正确, 实际类型是Student,目标类型也是Student没有问题 use(new Teacher()); // 错误,实际类型是Teacher,目标类型是Teacher,类型不匹配,运行时就会出现错误