在面向对象编程中,抽象类和接口是两个重要的概念。它们都被用来实现多态性,也就是说,允许不同的类实现相同的接口或继承相同的抽象类。然而,抽象类和接口有着不同的作用和实现方式。
一.抽象类
定义:抽象类是一个不能被实例化的类,它的目的是被子类继承。抽象类中可以包含抽象方法,这些方法在抽象类中没有具体的实现,需要由子类来实现。一个类只有继承了抽象类,才能够实现它的抽象方法。抽象类可以包含具体方法和字段,这些方法和字段可以在子类中被直接使用。抽象类的定义使用关键字“abstract”,例:
public abstract class Animal {
public abstract void makeSound();
public void eat() {
System.out.println("I am eating.");
}
}
我们再看另一个概念,抽象方法:
抽象方法是一种特殊的方法:它只有声明,而没有具体的实现 .
• 抽象方法必须用 abstract 关键字进行修饰 .
public abstract void eat();
●抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法。
● 用 abstract 修饰的类就是抽象类。如果某个类中包含有抽象方法,那么该类就必须定义成抽象类。
抽象类的用法:
抽象类只能用作基类,表示的是一种继承关系。继承抽象类的非抽象类必须实现其中的所有抽象方法,而已实现方法的参数、返回值要和抽象类中的方法一样。否则,该类也必须声明为抽象类。
注意: 1.继承抽象类必须重写里面的所有抽象方法,除非子类也是一个抽象类
2. 抽象类中不一定有抽象方法, 但有抽象方法的类一定是抽象类
代码示例 :
public abstract class Animals {
int root;
public Animals() {
}
public Animals(int root) {
this.root = root;
}
public abstract void eat();
}
两个子类:
public class Dog extends Animals{
public Dog(){
super(4); //狗4只脚
}
@Override
public void eat() { //重写eat方法
System.out.println("吃狗粮");
}
}
public class Cat extends Animals{
public Cat() {
super(4);
}
@Override
public void eat() {
System.out.println("吃猫粮");
}
}
二.接口
接口是一种完全抽象的类型,它定义了一组可以被实现的方法。一个类可以实现多个接口,并且必须实现接口中的所有方法。与抽象类不同,接口不能包含具体方法和字段。接口的定义使用关键字“interface”,例如:
public interface Flyable {
void fly();
}
接口中定义的方法都是公共的,不能有任何的访问修饰符,包括 public、private、protected 等。因为接口中的方法都是公共的,所以实现接口的类必须将接口中的方法设置为公共的。此外,接口中的常量是静态和最终的,不能被修改。
特性:
• 接口中方法可以是抽象的,静态的,默认的.声明的属性默认为 public static final 的;
• 接口不是被类继承,而是要被类实现。
• 接口不能实例化对象(无构造方法),但可以声明对象的引用。(多态性)
• 多个类可以实现同一个接口。
• 一个类可以实现多个接口,但只能继承一个类。
• 与继承关系类似,接口与实现类之间存在多态性。
• 一个接口能继承其它多个接口。
• 当类实现接口的时候,类要实现接口中所有的方法。否则,类必须声明为抽象的类。
另外, 在jdk 8 之后 ,我们可以在接口中声明一个default(默认)方法,在类实现这个接口的时候,接口中这个默认的方法也会被继承进类,供我们使用。
我们在上面抽象类 animals 的两个子类里来实现一个接口:
定义接口:
public interface Things { //接口
final int count = 10; //常量
void sleep(); //抽象方法
default void setA(){ //方法
System.out.println("功能");
}
}
两个子类的实现:
public class Dog extends Animals implements Things{
@Override
public void eat() {
System.out.println("吃狗粮");
}
@Override
public void sleep() {
System.out.println("睡狗窝");
}
}
public class Cat extends Animals implements Things{
@Override
public void eat() {
System.out.println("吃猫粮");
}
@Override
public void sleep() {
System.out.println("睡猫窝");
}
}
三.接口和抽象类的区别在于:
实现方式:抽象类是一个类,它可以有字段、构造函数和具体方法,而接口只是一组方法的定义,它不能包含具体的实现。
继承关系:一个类只能继承一个抽象类,但可以实现多个接口。这是因为 Java 中只支持单继承,但支持多实现。
使用场景:抽象类适合于那些具有共同属性和方法的类,而接口适合于定义类之间的通用行为。
实现方法:实现抽象类时,子类必须继承抽象类,并实现其中的抽象方法。实现接口时,类必须实现接口中的所有方法。
总的来说,抽象类和接口都是实现多态性的重要工具。抽象类用于定义类之间的共性,接口用于定义类之间的通用行为。选择使用哪种方式取决于具体的需求。
如果需要定义类之间的共同属性和方法,可以使用抽象类;如果需要定义类之间的通用行为,可以使用接口。此外,如果需要在定义的类中提供一些默认实现,可以使用抽象类,而如果需要强制实现某些方法,则可以使用接口。