接口和抽象类的区别
方法 | 可以有抽象和具体方法 | 只能有抽象方法(Java 8+ 支持默认方法) |
变量 | 可以有普通变量 | 只能有常量 (public static final ) |
抽象类:定义共同的特征(Cat和Dog都具有Animal的行为,所以可以定义一个Animal抽象类,包含动物的共同行为),比如以下代码
// 抽象类 Animal
abstract class Animal {
String name;
Animal(String name) { // 构造函数
this.name = name;
}
// 抽象方法:子类必须实现
abstract void makeSound();
// 具体方法:所有子类共享
void sleep() {
System.out.println(name + " is sleeping.");
}
}
// 子类:狗
class Dog extends Animal {
Dog(String name) {
super(name);
}
@Override
void makeSound() {
System.out.println(name + " says: Woof!");
}
}
// 子类:猫
class Cat extends Animal {
Cat(String name) {
super(name);
}
@Override
void makeSound() {
System.out.println(name + " says: Meow!");
}
}
// 测试类
public class Main {
public static void main(String[] args) {
Dog dog = new Dog("Buddy");
Cat cat = new Cat("Whiskers");
dog.makeSound();
dog.sleep();
cat.makeSound();
cat.sleep();
}
}
接口:定义某种行为规范,动物的某个行为作为一个接口,在实际业务中,某个功能服务会作为一个接口,代码示例:
// 接口:定义跑步行为
interface CanRun {
void run();
}
// 接口:定义发出声音的行为
interface CanMakeSound {
void makeSound();
}
// 狗类:实现跑步和发声行为
class Dog implements CanRun, CanMakeSound {
String name;
Dog(String name) {
this.name = name;
}
@Override
public void run() {
System.out.println(name + " is running!");
}
@Override
public void makeSound() {
System.out.println(name + " says: Woof!");
}
}
// 猫类:实现跑步和发声行为
class Cat implements CanRun, CanMakeSound {
String name;
Cat(String name) {
this.name = name;
}
@Override
public void run() {
System.out.println(name + " is running!");
}
@Override
public void makeSound() {
System.out.println(name + " says: Meow!");
}
}
// 测试类
public class Main {
public static void main(String[] args) {
Dog dog = new Dog("Buddy");
Cat cat = new Cat("Whiskers");
dog.run();
dog.makeSound();
cat.run();
cat.makeSound();
}
}