抽象类&接口?区别?优缺点?适用场景?
- 抽象类 & 接口
- 抽象类 不能实例化对象的类。通过abstract class来定义抽象类。抽象类必须被继承,才能被使用。abstract可声明抽象方法,抽象方法只包含方法名,没有方法体,具体实现由它的子类确定。抽象方法有两条规则: (1)包含抽象方法的类必定是抽象类(但抽象类不一定有抽象方法) (2)任何子类必须重写父类的抽象方法,或者声明自身为抽象类
// 抽象类
public abstract class Employee
{
private String name;
private String address;
public Employee(String name, String address)
{
System.out.println("Constructing an Employee");
this.name = name;
this.address = address;
}
// 一般成员方法
public void setName(){this.name = name;}
public String getName(){return name;}
// 抽象成员方法
public double void computePay();
}
// 子类继承抽象类,具体实现
public class Salary extends Employee
{
private double salary; // Annual salary
// 必须实现抽象成员方法 computePay
public double computePay()
{
System.out.println("Computing salary pay for " + getName());
return salary/52;
}
}
- 接口 接口不是类,是抽象方法的集合。通过Interface来声明接口。一个类通过implements关键字来实现接口中的抽象方法。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。
// 声明接口
interface Animal {
public void eat();
public void travel();
}
// 实现接口
public class MammalInt implements Animal{
public void eat(){
System.out.println("Mammal eats");
}
public void travel(){
System.out.println("Mammal travels");
}
public int noOfLegs(){
return 0;
}
}
- 联系 & 区别
| 抽象类 abstract | 接口 interface | |
| 定义 | 不能实例化对象的类。通过abstract class来定义抽象类。抽象类必须被继承,才能被使用。一个类通过extends关键字来继承抽象类。 | 接口不是类,是抽象方法的集合。通过Interface来声明接口。一个类通过implements关键字来实现接口中的抽象方法。 |
| 作用 | is-a关系 是什么 | like-a 能做什么 |
| 描述 | 描述对象的属性和方法,关注的是事物本身的抽象 | 声明类要实现的方法,关注的是操作行为的规范 |
| 相同点 | 均不可实例化 均需要子类继承/实现对应的抽象方法 | |
| 成员方法 | 抽象类的方法有方法体,可以实现方法的具体功能 | 接口中只有方法的声明,没有方法体(接口中的方法默认public abstract类型) |
| 成员变量 | 抽象类的成员变量可以是各种类型 | 接口中只成员变量只能是public static final类型(公共静态常量) |
| static修饰符 | 抽象类可以有静态代码块和静态方法 | 接口中没有静态代码块以及静态方法 |
| 继承关系 | 一个类只能继承一个抽象类 | 一个类可以实现多个接口 |
| 优缺点 | 优点:实现公共特性的提取,使具体类可以从抽象类自动得到缺省实现,复用性强,简化代码 缺点:单继承,使子类的功能的扩展性大打折扣 | 优点:一个类可以实现多个接口,接口可以使这个类不仅具有主类型的行为,而且具有其他的次要行为,比如 HashMap主要类型是Map,而Cloneable接口使它具有一个次要类型,这个类型说明它可以安全的克隆 |
| 使用建议 | 抽象类用于给子类提供一个抽象的描述,用作主要类型的说明 接口用于给子类提供多个功能的补充,用作次要类型的说明 | |