1 抽象类
一种比较苍白的说法是:在 Java 中,通过关键字 abstract 定义的类叫做抽象类。Java 是一门面向对象的语言,因此所有的对象都是通过类来描述的;但反过来,并不是所有的类都是用来描述对象的,抽象类就是其中的一种。
以下示例展示了一个简单的抽象类:
abstract class Coach {
public abstract void defend();
public abstract void attack();
}
在一个抽象类中,至少有一个抽象方法(通过关键字 abstract 定义的方法,并且没有方法体,如上例中的 defend() 方法和 attack() 方法),否则就没有必要称之为抽象类。需要注意的是,抽象类是不能实例化的! 它需要被一个子类继承,就像以下示例那样。
abstract class Coach {
public abstract void defend();
public abstract void attack();
}
class Hesai extends Coach {
@Override
public void defend() {
System.out.println("防守赢得冠军");
}
@Override
public void attack() {
System.out.println("控球是把双刃剑");
}
}
public class Demo {
public static void main(String[] args) {
Coach moliniao = new Hesai();
moliniao.defend();
moliniao.attack();
}
}
抽象类的特征:
1、抽象类不能被实例化。
2、抽象类应该至少有一个抽象方法,否则它没有任何意义。
3、抽象类中的抽象方法没有方法体。
4、抽象类的子类必须给出父类中的抽象方法的具体实现,除非该子类也是抽象类。
5、抽象类中可以有非抽象方法(也就是不被abstract修饰的方法)
抽象类的应用(适配器模式):
适配器模式的思想是,针对调用者的需求对原有的接口进行转接。生活当中最常见的适配器就是HDMI(英语:High Definition Multimedia Interface,中文:高清多媒体接口)线,可以同时发送音频和视频信号。适配器模式的示例如下:
interface Coach {
void defend();
void attack();
}
// 抽象类实现接口,并置空方法
abstract class AdapterCoach implements Coach {
public void defend() {};
public void attack() {};
}
// 新类继承适配器
class Hesai extends AdapterCoach {
public void defend() {
System.out.println("防守赢得冠军");
}
}
public class Demo {
public static void main(String[] args) {
Coach coach = new Hesai();
coach.defend();
}
}
Coach 接口中定义了两个方法(defend() 和 attack()),如果类直接实现该接口的话,就需要对两个方法进行实现。
如果我们只需要对其中一个方法进行实现的话,就可以使用一个抽象类作为中间件,即适配器(AdapterCoach),用这个抽象类实现接口,并对抽象类中的方法置空(方法体只有一对花括号),这时候,新类就可以绕过接口,继承抽象类,我们就可以只对需要的方法进行覆盖,而不是接口中的所有方法。
2 接口
我们知道,有抽象方法的类被称为抽象类,也就意味着抽象类中还能有不是抽象方法的方法。这样的类就不能算作纯粹的接口,尽管它也可以提供接口的功能——只能说抽象类是普通类与接口之间的一种中庸之道。
接口(英文:Interface),在 Java 中是一个抽象类型,是抽象方法的集合;接口通过关键字 interface 来定义。接口与抽象类的不同之处在于:
1、抽象类可以有方法体的方法,但接口没有。
2、接口中的成员变量隐式为 static final,但抽象类不是的。
3、一个类可以实现多个接口,但只能继承一个抽象类。
以下示例展示了一个简单的接口:
// 隐式的abstract
interface Coach {
// 隐式的public
void defend();
void attack();
}
接口是隐式抽象的,所以声明时没有必要使用 abstract 关键字;接口的每个方法都是隐式抽象的,所以同样不需要使用 abstract 关键字;接口中的方法都是隐式 public 的。
和抽象类一样,接口也不能直接被实例化,它需要一个类来实现它,就像以下示例展示那样:
class Hesai implements Coach {
@Override
public void defend() {
System.out.println("防守赢得冠军");
}
@Override
public void attack() {
System.out.println("控球是把双刃剑");
}
}
public class Demo2 {
public static void main(String[] args) {
Coach moliniao = new Hesai();
moliniao.defend();
moliniao.attack();
}
}
实现一个接口需要用到关键字 implements,它表示:“我这个类遵从了接口的协议,如果你想使用我,看接口就行了,具体实现不用关心。”