接口与抽象类的比较
接口(Interface)
接口的概念:
接口是一种特殊的类型,通常只包含抽象方法,表示的是一种能力,常常用于扩展类的行为。
接口的特点:
-
接口不可以被实例化。
-
实现类必须实现(不说继承)接口的所有方法(implements)。
-
实现类可以实现多个接口。
-
接口中的变量都是静态常量。
-
接口中可以包含静态方法和普通方法,但普通方法必须是default权限。
PS: 传统的理解是接口只包含抽象方法。但是程序员们在使用中,发现很不方便,实现接口必须重写所有方法,很麻烦。所以java设计者妥协了,在java8中,支持default和static方法,这样,实现接口时,可以选择不对default修饰的方法重写。
-
接口提供一个默认实现的方法,并且不强制实现类重写此方法。
-
默认方法使用default关键字来修饰。
-
在接口中被default标记的方法为普通方法,必须要写方法体。
-
接口中支持定义静态方法,将关键字换成static即可。
-
演示:
package interfaceDoor;
/**
* @author WuYongheng
* @date 2021/12/3
* @description 抽象类门
*/
public abstract class Door {
private String name;
private String type;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
/**
* 开门
*/
public abstract void open();
/**
* 关门
*/
public abstract void close();
}
package interfaceDoor;
/**
* @author WuYongheng
* @date 2021/12/3
* @description 定义一个锁接口,有上锁和开锁两个方法
*/
public interface Lockable {
void lockUp();
void openLock();
}
package interfaceDoor;
/**
* @author WuYongheng
* @date 2021/12/3
* @description 木门继承门父类(抽象类),实现了上锁接口
* 如以后业务拓展,比如增加门铃功能,猫眼功能,
* 只需要实现门铃、猫眼接口即可,很方便
*/
public class WoodenDoor extends Door implements Lockable {
@Override
public void open() {
System.out.println("轻轻推,门开了");
}
@Override
public void close() {
System.out.println("轻轻拉,门关了");
}
/**
* 锁门
*/
@Override
public void lockUp() {
System.out.println("左三圈,门上的锁,上锁了。。。");
}
/**
* 开锁
*/
@Override
public void openLock() {
System.out.println("右三圈,门上的锁,开了。。。");
}
}
package interfaceDoor;
/**
* @author WuYongheng
* @date 2021/12/3
* @description 演示
*/
public class TestWoodenDoor {
public static void main(String[] args) {
WoodenDoor door = new WoodenDoor();
door.setName("盼盼");
door.setType("不锈钢");
// 模拟门开关的过程
// 先开锁
door.openLock();
// 再开门
door.open();
// 先关门
door.close();
// 再上锁
door.lockUp();
}
}
抽象类(abstract)
抽象的概念:
-
一个类被声明为抽象类后,不可以在外部被实例化。
-
抽象类中,可以包含抽象方法和普通方法。
-
一个类如果包含了抽象方法,则该类必须是一个抽象类。
为什么需要抽象?(没有一个叫动物的动物)
回想之前讲到的Dog、Cat类及其它们的父类Animal类, 我们在具体使用时,通常不会去特意实例化父类Animal, 而是去实例化具体的某个子类对象。
Animal类被抽象化以后,我们继续思考它里面的方法,eat(), speak(), sleep() 这些方法,其实都在描述一种动物它应该所具备的一些行为特征,其实也是一种抽象的概念。把这些概念性的,但是又包含具体方法实现的方法,继承给我们的子类后,这些子类往往是用不上的,有时为了正确使用,不得不去重写它们,而如果忘记重写它们,在调用时,又会调用到这些不太有意义的方法。
我们就可以使用抽象方法进行解决。我们将抽象的父类中的那些对子类很重要的方法,但是又不需要父类去定义方法主体的方法,定义成抽象方法。
这样,子类继承了这个父类后,就必须要重写这些方法后,才能使用。
演示:
package abstractAnimal;
/**
* @author WuYongheng
* @date 2021/12/3
* @description 动物类(抽象类),里面包含了所有动物都共有的属性
*/
public abstract class Animal {
public String name; // 名称
public double weight; // 体重
public String breed; // 品种
public abstract void speak() ;
public abstract void sleep() ;
public abstract void eat() ;
}
package abstractAnimal;
/**
* @author WuYongheng
* @date 2021/12/3
* @description 猫,继承自动物类(抽象的类),必须重写父类所有的方法
*/
public class Cat extends Animal {
public static void main(String[] args) {
// 父类引用,指向子类对象
Animal cat = new Cat();
cat.name = "kitty";
cat.eat();
cat.speak();
cat.sleep();
}
/**
* 重写父类的睡觉方法,改为自己独有的方法
*/
@Override
public void sleep() {
System.out.println(name + "喜欢挨着我睡");
}
/**
* 重写父类说方法,改为自己独有的方法
*/
@Override
public void speak() {
System.out.println("喵喵喵。。。");
}
/**
* 重写父类的吃方法,改为自己独有的方法
*/
@Override
public void eat() {
System.out.println(name + "正在舔食物");
}
}
package abstractAnimal;
/**
* @author WuYongheng
* @date 2021/12/3
* @description 狗,继承自动物类,演示继承和多态
*/
public class Dog extends Animal {
public static void main(String[] args) {
// 父类引用,指向子类对象
Animal dog = new Dog();
dog.name = "乔治";
dog.eat();
dog.speak();
dog.sleep();
}
/**
* 重写父类的睡觉方法,改为自己独有的方法
*/
@Override
public void sleep() {
System.out.println(name+"和玩具一起睡觉");
}
/**
* 重写父类的说方法,改为自己独有的方法
*/
@Override
public void speak() {
System.out.println("汪汪汪。。。");
}
/**
* 重写父类的吃方法,改为自己独有的方法
*/
@Override
public void eat() {
System.out.println(this.name + "正在啃骨头");
}
}
接口与抽象类的对比(简单题)
- 接口表示一种能力,是对类的行为的一种扩展
- 体现在接口的方法上
- 面向接口编程,关心的是实现类有什么能力,而不关心实现的细节
- 面向接口考虑的是一种约定而不考虑接口的具体实现
比如,我们需要一个英语老师。则,只要有人会教英语这个技能即可,我们不关心她是谁,只要她有这种能力就行。
我们想让小明同学学会说英语,然后小明去说就行了,我们不关心他是怎么学的。
- 抽象类,主要是为了约束子类的行为
- 比如,一名英语老师,她必须要会教英语这个技能,才算一个英语老师。
- 普通的类与父类,是 is a 的关系; 与接口是 has a 的关系
- 木门 is a 门
- 木门 has a 上锁、开锁的功能,has a 门铃的功能