一、抽象类
1.概述
在java中abstract是抽象的意思,可以修饰类、成员方法;
/**
* 抽象类:
*/
public abstract class Animal {
/**
* 抽象方法,不能有具体实现
*/
public abstract void run();
}
2.注意
-
抽象方法只有方法签名,不能声明方法体(具体实现)
-
类中定义了抽象方法,类必须声明为抽象类,否则报错
-
子类继承父类,必须重写父类所有抽象方法,否则这个类必须定义为抽象类
3.抽象使用场景
-
抽象类是不完整的设计图,作为父类,由子类继承实现;
-
父类知道子类要完成某行为,但每个子类实现过程不一样,于是父类将其定义为抽象,具体交由子类完成
4.抽象类案例
/**
* 两种卡:
* 白金卡:原价八折
* 银卡:原价八折五
*/
public abstract class Card {
private String name;
private double money;
/**
* 定义一个支付的抽象方法:
*/
public abstract void pay(double money);
}
/*
金卡具体实现
*/
public class GoldCard extends Card{
@Override
public void pay(double money) {
System.out.println("当前消费:"+money);
System.out.println("余额:"+getMoney());
double rs = money*0.8;
System.out.println("实际消费:"+rs);
}
}
5.抽象类特征和注意事项
-
抽象类中不一定有抽象方法;有抽象方法一定是抽象类;
-
一个类继承抽象类,必须重写全部抽象方法,否则这个类必须定义抽象类;
-
不能用abstract修饰变量,代码块,构造器
-
最重要特征:
-
得到了抽象方法,失去了创建对象的能力(有得有失);抽象类不应该实例化
-
5.1 final和abstract是什么关系?
-
互斥关系:
-
final修饰类,不能继承;
-
abstract修饰类,作为父类需要被子类继承
-
抽象方法需要子类重写;final定义的方法不能重写;
-
6.抽象类应用:模板方法模式
6.1使用场景说明
当系统中同一功能多处在开发,该功能中大部分代码一致,只有其中部分功能不一样;
6.2 模板方法实现步骤
功能定义成一个所谓模板,放在抽象类,模板方法中只放入通用且能确定的代码;
模板方法中不能决定的功能定义成抽象方法,让具体子类实现;
public abstract class Student {
public final void write(){
System.out.println("开头");
writeMain();
System.out.println("结尾");
}
public abstract void writeMain();
}
public class StudentMiddle extends Student{
@Override
public void writeMain() {
System.out.println("这是中学生写的!");
}
}
6.3 模板方法建议final修饰,为什么?
模板方法是直接给子类使用的,不是让子类重写的
6.4 模板方法解决的问题
-
提高代码的复用性;
-
模板方法定义了通用结构,不能确定的地方定义成抽象方法,由子类实现,使用者只需要实现自己的部分功能
七、接口
1.接口概述
-
JDK8之前,接口中只能是抽象方法和常量,没有其他成分;
-
接口是一种规范,规范一定是公开的;
-
接口格式:
public interface 接口名{
//常量
//抽象方法
}
2.接口的用法
-
接口是用来被实现(implements)的,实现接口的类称为实现类
-
接口可以被类单实现,也可以被多实现
3.接口实现的注意事项
类实现接口,必须重写完接口的全部抽象方法,否则类需定义为抽象类
4.关系总结
-
类和类:单继承
-
类和接口:多实现
-
接口和接口:多继承,一个接口可以同时继承多个接口
5.接口多继承作用
规范合并,整合多个接口为同一个接口,便于子类实现;
6.JDK8开始接口新增方法
-
第一种:默认方法
-
实例方法,必须用default修饰
-
默认会public修饰,需要接口的实现类对象调用
-
-
第二种:静态方法
-
默认public修饰,必须static修饰
-
注意:接口静态方法,必须用接口名来调用
-
-
第三种:私有方法
-
私有实例方法,从jdk1.9开始
-
只能在本类(接口)中被其他默认方法或私有方法访问
-
7.接口注意事项
-
接口不能创建对象();
-
接口更加彻底的抽象
-
-
一个类实现多个接口,多接口中有同样的静态方法不冲突;
-
静态方法由接口名直接调用
-
-
一个类实现多个接口,多接口中有同名默认方法,不冲突,类重写该方法即可;
-
有同名默认方法,谁的都不用,自己重写一个
-
-
一个类,继承了父类,又实现接口,又同名方法,默认用父类;
-
就近原则,继承父类
-
-
一个接口继承多个接口,没有问题,多接口中存在规则冲突则不能继承
-
类似,类实现多接口,但这里不能重写方法
-