抽象类
特点
- 拥有抽象方法的类必须是抽象类
- 抽象类可以没有抽象方法
- 继承了抽象类的子类必须实现抽象方法,如果不实现抽象方法那么子类必须是抽象类
- 抽象类中可以对方法进行声明也可以对方法进行实现
- 抽象方法不能声明为static
- 抽象方法不能声明为private
- 抽象类不能声明为static
- 抽象类可以implements接口,抽象类可以不用实现接口的方法,抽象类的子类需要实现抽象类implements的接口的方法
使用场景
JAVA为一门单继承语言,但是需要实现其多态性,所以我们对继承需要谨慎处理。抽象类可以说是一个类的所属,也就是说抽象类需要抽象出子类们所共同的属性和方法。举例如下:
public abstract class Person {
abstract void sex();
}
public class Man extends Person {
@Override
void sex() {
}
}
public class Woman extends Person {
@Override
void sex() {
}
}
由上面可见,人是一个抽象类,男人和女人类继承于人这个抽象类。该抽象类抽象出了,男人,女人都是人这个属性,以及他们的属性——性别。性别不同,所以必须实现性别这个方法。
又或者类似于广播模式。
//观察者
public abstract class Observer{
protected Subject subject;
public abstract void update();
}
//被观察对象
public class Subject {
//观察者列表
private List<Observer> observers = new ArrayList<>();
private int state;
public int getState() {
return state;
}
//更改属性state
public void setState(int state) {
this.state = state;
notifyAllObservers();
}
//添加一个观察者进入观察者列表
public void attach(Observer observer) {
observers.add(observer);
}
//通知观察者列表中的所有观察者更新
public void notifyAllObservers(){
for (Observer observer : observers) {
observer.update();
}
}
}
//其中一个观察者
public class OctalObserver extends Observer {
public OctalObserver(Subject subject){
this.subject = subject;
this.subject.attach(this);
}
@Override
public void update() {
System.out.println( "Octal String: "
+ Integer.toOctalString( subject.getState() ) );
}
}
//其中一个观察者
public class HexaObserver extends Observer {
public HexaObserver(Subject subject){
this.subject = subject;
this.subject.attach(this);
}
@Override
public void update() {
System.out.println( "Hex String: "
+ Integer.toHexString( subject.getState() ).toUpperCase() );
}
}
//其中一个观察者
public class BinaryObserver extends Observer {
public BinaryObserver(Subject subject){
this.subject = subject;
this.subject.attach(this);
}
@Override
public void update() {
System.out.println( "Binary String: "
+ Integer.toBinaryString( subject.getState() ) );
}
}
从上述可以看出,后续的OctalObserver,HexaObserver,BinaryObserver都是观察者,都继承于Observer。这是因为他们的根源都是观察者,只不过他们类型不同。
所以抽象类可以说是定义了子类的根源,它的作用也是如此。
接口
特点
- 接口只能对方法进行声明,不能拥有方法体。(即实现方法)
- 接口中的所有属性默认为public
- 接口可以extends多个接口。继承这些接口后可以不实现其方法,留给implements该接口的类来实现
- 子类必须实现接口中的所有方法
使用场景
接口更倾向于描述一系列的行为动作。比如,描述一个人的必须的活动,吃饭,睡觉,社交等。
public interface HowPersonDo {
void sleep();
void eat();
void makeFriend();
}
两者区别
在此之前可以先去了解下JAVA中的多态是什么
- 实现接口使用implements,继承抽象类使用extends
- 接口里面只能对方法进行声明,抽象类既可以对方法进行声明也可以对方法进行实现
- 接口中的方法必须全部实现,不然子类就必须为抽象类。继承抽象类,必须实现抽象类中的所有抽象方法,不然子类就必须为抽象类。
- 接口中的方法只能声明,不能实现。而抽象类中的可以声明也可以实现,实现的方法不是抽象方法。
- 抽象类中可以没有抽象方法
- 拥有抽象方法的必须为抽象类
- 由于抽象类中方法必须全部实现,所以抽象方法不能为static,也不能为private
- 接口可以继承多个接口,类只能继承一个类
使用区别:
- 抽象类是抽象出一个事物的类别,接口是抽象出方法和功能。
- 着重事物本质就用抽象类,关注操作就用接口。
- 接口更具有扩展性。(因为单继承,多接口原因)