多态--Final--抽象类--接口
1 多态
多态: 多态是指一个实物同时可以具有多重身份, 是基于继承(extends), 实现(implements)的一种表达方式, 其中一定需要有方法重写.
1.1 格式
父类/接口 变量名 = new 子类();
1.2 特点
1.2.1 对象的多态
等号右边是可以切换子类的对象
1.2.2 行为的多态**
方法重写之后,执行的是子类的方法
多态就是为了使用子类的方法,实现解耦(在不改变方法调用的时候,直接使用子类的方法)
1.3 优点
1) 可以切换等号右边的对象,很方便就可以实现切换一种方案
2) 可以用父类/接口作为方法的参数,接收不同的子类对象。增加方法的通用性, 提高了代码的拓展性
1.4 应用场景
如果一个问题有多个实现方案,我们就可以使用多态来解决问题
1.5 缺陷
当使用多态的时候, 没有办法使用子类中的特有方法.此时需要用到强制类型转换. 转换之前,建议用instanceof 判断类型, 防止出现异常.
可以参考以下代码片段.
public class Animal {
private String name;
private String color;
public void eat(){
System.out.println("再吃放");
}
//省略构造器和getset
public class Dog extends Animal{
@Override
public void eat() {
System.out.println("吃骨头");
}
public void lookHouse(){
System.out.println("在看家");
}
public class test {
public static void main(String[] args) {
Animal dog = new Dog("kaka","R&B");
Animal cat = new Cat("C.R","White");
dog.eat();
dog.lookHouse() //此时报错,dog为Animal类,下并无lookhouse方法
if(dog instanceof Dog){
Dog d1 = (Dog) dog;//创建d1类型为Dog
d1.lookHouse();//现在一切正常
}
}
}
2 Final
2.1 概念
代表最终的意思
2.2 作用
2.2.1 修饰类
所修饰类代表最终的类,不能被继承 (一般都是底层或者源码的某一些类才会用到,实际开发用的比较少。 源码的类:String)
2.2.2 修饰方法
所修饰方法代表最终的方法,不能被重写(一般都是比较少用到。目前用到的是在模板方法设计模式)
2.2.3 修饰变量
1) 代表常量, 只能被赋值一次
2) 如果是修饰局部变量, 可以先定义, 后赋值
3) 如果是修饰成员变量, 可以直接赋值, 也可以通过构造器赋值【如果是用构造器赋值一定要确保每一个构造器里面都要赋值】
2.3 使用场景
2.3.1 模板方法
作用: 用于抽取多个方法中相同的代码
步骤: 1) 定义一个抽象类
2) 把多个方法中相同的代码抽取到一个实例方法中 , 这个实例方法要用final修饰
3) 定义一个抽象方法,不同的内容交给子类去实现
2.3.2 常量
概念: static final 修饰的变量
作用: 记录一些系统的信息,或者一些特殊的数据. 或者信息的配置, 例如:公司的名称,整数的最大值、最小值
优势: 可阅性好
命名规范: 每个单词的每个字母都需要大写,多个单词之间通过下划线隔开
例如:
public static final String COMPANY_NAME = "AKB48Team";
3 抽象类
3.1 定义格式
public abstract class 类{
public abstract 返回值类型 方法名(参数);
}
3.2 使用方法
抽象类不能创建对, 一定要用子类去继承抽象类, 重写抽象方法, 用多态的方式创建对象
3.3 特点
1) 抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
2) 抽象类可以写普通的所有内容,还多抽象方法
3) 抽象类不能创建对象
4) 抽象方法不能加上final(方法不能重写). static(类名. 方法名()) . private(私有)
3.4 优点
1) 强制让子类一定重写方法(多态)
2) 扩展性
3.5 模板方法设计模式
3.5.1 用处
常用于<多个类中> 而且方法高度重复的代码
3.5.2 如何设计
1) 先创建一个抽象类
2) 把相同的代码放在一个普通方法中, 该方法就成为模板方法, 要用final修饰. (可以防止被修改)
3) 定义一个抽象方法, 交给子类实现
如下部分程序使用了模板方法设计模式对一个金卡用户进行打折
import java.util.Scanner;
public abstract class Discount {
public void DiscountByMembership(){
Scanner sc = new Scanner(System.in);
System.out.println("您买了多少钱?");
double price = sc.nextDouble();
double payment = calcPrice(price);
System.out.println("您要交"+payment);
}
public abstract double calcPrice(double price);
}
public class GoldMember extends Discount{
@Override
public double calcPrice(double price) {
double pay = 0.85*price;
return pay;
}
}
public class test {
public static void main(String[] args) {
GoldMember gold1 = new GoldMember();
SilverMember silver1 = new SilverMember();
gold1.DiscountByMembership();
silver1.DiscountByMembership();
}
}
该方法可以减少代码冗余
4 接口
4.1 概念
通过Interface关键字创建的一种特殊结构. 是一个非常彻底的抽象类
一个类可以实现(implements)多个接口
一个接口可以继承多个接口
一个类只能继承另一个类,但是可以多层继承
4.2 格式
public interface 接口名{
常量;
抽象方法;
}
4.3 使用方式
1) 用子类去实现接口,可以实现多个接口
public class 子类 implements 接口A , 接口B...{
}
2) 使用多态,创建子类对象去使用里面方法
下例为一个利用接口设计的简单程序, 创建了三个接口, 利用接口进行数据打印处理
public interface Dance {
void danceQueen();
}
public interface Rap {
void rapKing();
}
public interface Sing {
void JiJiNiTaiMei();
}
public class Trainee implements Sing,Dance,Rap {
@Override
public void JiJiNiTaiMei() {
System.out.println("姬霓太美");
}
@Override
public void rapKing() {
System.out.println("如此蠢蠢欲动,这种感觉我从未有crash on you!");
}
@Override
public void danceQueen() {
System.out.println("背带裤肩带滑落");
}
}
public class test {
public static void main(String[] args) {
Sing s = new Trainee();
s.JiJiNiTaiMei();
Dance d = new Trainee();
d.danceQueen();
}
}
4.4 接口的优点
1) 可以多实现, 扩展性强, 可以让一个类具备更多的身份 (多态)
2) 接口比较纯粹, 一般都是定义抽象方法
4.5 抽象类VS接口
抽象类用于: 模版方法设计模式 或者 源码中
抽象类 = 普通类+抽象方法
其实等同于把抽象方法放在一个接口, 直接普通类+接口