抽象类与接口的异同
作者:互联网
一、概述
对于面向对象的编程来说,抽象其特征之一。而在Java中,可以通过两种形式来体现OOP的抽象:抽象类与接口。接口在许多方面都与抽象类很相似,但是它的目的是指明相关或者是不相关类的对象的共同行为。所以说,这两者有很多相似的地方,但同时也有着很多不同的地方。它们的不可以随意的互换使用,需要明确它们的异同点。
二、背景
1、抽象类
在继承的层次结构中,每个新的子类都使类变得更加明确和具体。如果从一个子类向父类追溯,类就会变得更通用,但也会更加不明确。类的设计应该确保父类包含它的子类的共同特征。有时候,一个父类设计得非常抽象(即一个类中没有包含足够的信息来描绘一个具体的对象),以至于它都没有任何具体的实例。这样的类称为抽象类。
(1)抽象方法:[访问修饰符]abstract<返回类型><方法名>([参数列表])
注意:抽象类不能被实例化,抽象方法必须在子类中被实现。抽象类不能直接使用,必须用子类去实现抽象类,然后使用其子类的实例。
(2)抽象类
abstract class<类名>{
}
(3)定义一个抽象类
public abstract class 类名称{
修饰符 absteact 返回类型 方法名();
修饰符 返回类型 方法名(){
方法体
}
}
(4)实例
abstract class People{
private String name;
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
//抽象方法
public abstract void work();
}
class Teacher extends People{
//必须实现该方法
public void work(){
System.out.println("我叫"+this.getName());
}
}
class Driver extends People{
//必须实现该方法
public void work(){
System.out.println("我叫"+this.getName());
}
}
(5)一些说明
a.抽象方法不能包含在非抽象类中。在继承自抽象类的非抽象子类中,必须实现所有的抽象方法,还要注意抽象方法是静态的。
b.抽象类不能使用new操作符来初始化。但仍然可以定义它的构造方法,这个方法在它的子类的构造方法中调用。
c.包含抽象方法的类必须是抽象的。然而,可以定义一个不包含抽象方法的抽象类。这个抽象类用于定义新子类的基类。
d.子类可以重写父类的方法并将它定义为抽象的。
e.即使子类的父类是具体的,但这个子类也可以是抽象的。
f.不能使用new操作符从一个抽象类创建一个实例,但是抽象类可以用作一种数据类型。
2、接口
Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。
(1)接口定义:
modifier interface InterfaceName {
/** Constant declarations */
/** Abstract method signatures */
}
(2)实现接口
public 类名 implements接口名{
实现方法
普通方法
}
- 实现接口使用implements关键字。
- 实现接口的类必须实现接口中定义的所有抽象方法。
- 接口的实现类包含普通方法。
(3)一个接口例子:
public interface Edible {
/** Describe how to eat */
public abstract String howToEat();
}
(4)接口的特点和作用
- 接口指明了一个类必须要做什么和不能做什么,相当于类的蓝图。
- 一个接口就是描述一种能力,比如“歌手”也可以作为一个接口,并且任何实现“运动员”接口的类都必须有能力实现唱歌这个动作。
- 抽象方法只能存在于抽象类或者接口中,但抽象类中却能存在非抽象方法,即有方法体的方法。接口是百分之百的抽象类。
- 因为Java不支持多继承,所以Java可以通过实现接口来弥补这个局限。
- 接口的作用就是告诉类,你要实现我这种接口代表的功能,你就必须实现某些方法,我才能承认你确实拥有该接口代表的某种能力。
(5)一些说明
- 接口中的方法默认都是public abstract的抽象方法。
- 接口没有构造方法,不能被实例化。
- 接口的实现类必须实现接口的全部方法,否则必须定义为抽象类。
- 若一个类在继承父类的同时又实现了多个接口,extends必须位于implements前。
(6)实例
public class Attribute implements Cloneable {
private String no;
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
return null;
}
}
}
public class Product implements Cloneable {
private String name;
private Attribute attribute;
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
return null;
}
}
}
三、详述(抽象类与接口的异同)
1、相同点
接口的使用和抽象类的使用基本类似。
- 接口和抽象类都不能实例化,只能被继承实现。
- 接口和抽象类都可以包含抽象方法。实现接口和抽象类的类都必须实现这些抽象方法。
- 用于描述系统提供的服务,不必提供具体实现。
2、不同点
变量 | 构造方法 | 方法 | 关键字 | 继承/实现 | 多继承 | |
抽象类 | 无限制 | 子类通过构造方法链调用构造方法,抽象类不能用new操作符实例化 | 无限制 | abstract class | 只能被类或抽象类继承 | 不支持 |
接口 | 所有的变量必须是public static final | 没有构造方法。接口不能用new操作符实例化 | 可以包含public的抽象实例方法、public的静态方法 | interface | 既可以被接口继承,也能被类或抽象类实现 | 可以继承多个父接口 |
补充
- 抽象类可以为部分方法提供默认实现,接口中只能包含抽象方法。
- 抽象类便于复用,接口便于代码维护。
- 一个类最多只能有一个直接父类,包括抽象类;但一个类可以直接实现多个接口,通过实现多个接口来弥补java单继承的不足。
3、说明
(1)抽象类和接口都是用来指定多个对象的共同特征的。一般来说,清晰描述父子关系的强的“是...的一种”关系应该用类建模。例如,因为公历是一种日历,所以类Java.util.GregorianCalendar和java.util.Calendar是用类继承建模的。弱的“是...的一种”关系也称为类属关系,它表明对象拥有某种属性,可以用接口来建模。例如,所有的字符串都是可比较的,因此,String类实现Comparable接口。
(2)接口的优势
- 接口表示一种能力,一个类实现了某个接口,就表示这个类具备了某种能力,一个类可以实现多个接口。
- 接口弥补了JAVA只能单继承的缺点,还有利于代码的扩展和维护。
- 接口类似于一个组件,需要时可以自由组装。
- 接口可以降低代码的耦合性,提高代码的可扩展性和可维护性。
设计良好的接口就像日常使用的万能插座,不论插头如何变化,都能使用。所以说,通常推荐使用接口而非抽象类。接口比类更加灵活。
四、总结
接口和抽象类是支持抽象类定义的两种机制。
接口是公开的,不能有私有的方法或变量,接口中的所有方法都没有方法体,通过关键字interface实现。
抽象类是可以有私有方法或私有变量的,通过把类或者类中的方法声明为abstract来表示一个类是抽象类,被声明为抽象的方法不能包含方法体。子类实现方法必须含有相同的或者更低的访问级别(public->protected->private)。抽象类的子类为父类中所有抽象方法的具体实现,否则也是抽象类。
接口可以被看作是抽象类的变体,接口中所有的方法都是抽象的,可以通过接口来间接的实现多重继承。接口中的成员变量都是static final类型,由于抽象类可以包含部分方法的实现,所以,在一些场合下抽象类比接口更有优势。
标签:异同,接口,实现,抽象,抽象类,方法,public 来源: https://blog.csdn.net/lniiiiii/article/details/122014928