本文参照教科书《Java语言程序设计与数据结构(第11版)》以及网上资料进行编写。
参考网址:https://www.runoob.com/java/java-interfaces.htmlhttps://www.runoob.com/java/java-abstraction.html
JAVA——抽象类与接口
本文关键词:JAVA、抽象类、接口
文章目录
- JAVA——抽象类与接口
- 一、抽象类的简介
- 1.抽象类
- 2.抽象方法
- 3.抽象类的相关说明
- 4.抽象类的举例
- 二、接口的简介
- 1.接口介绍
- 2.接口的相关特性
- 3.接口的举例
- 三、抽象类和接口的区别与联系
- 1.区别
- 2.联系
一、抽象类的简介
1.抽象类
在继承的层次结构中,每个新的子类都使类变得更加明确具体。如果从一个子类向父类追溯,类就会变得更通用、更加不明确。类的设计应该确保父类包含它的子类的共同特点。有时候,一个父类设计得非常抽象,以至于它都没有任何具体的实例。这样的类成为抽象类(abstract class)。
- Java中用abstract class定义抽象类,如下实例:
public abstract class Employee
{
private String name;
private String address;
private int number;
public Employee(String name, String address, int number)
{
System.out.println("Constructing an Employee");
this.name = name;
this.address = address;
this.number = number;
}
public double computePay()
{
System.out.println("Inside Employee computePay");
return 0.0;
}
public void mailCheck()
{
System.out.println("Mailing a check to " + this.name
+ " " + this.address);
}
public String toString()
{
return name + " " + address + " " + number;
}
public String getName()
{
return name;
}
public String getAddress()
{
return address;
}
public void setAddress(String newAddress)
{
address = newAddress;
}
public int getNumber()
{
return number;
}
}
2.抽象方法
通过abstract关键字将getArea方法修饰为抽象的,此时的方法成为抽象方法。
public abstract void getArea()
//访问修饰符 abstract 返回类型 方法名(参数列表)
声明抽象方法会造成下面两个结果:
- 如果一个类包含抽象方法,那么该类必须是抽象类。
- 任何子类必须重写父类的抽象方法,或声明自身为抽象类。
3.抽象类的相关说明
- 包含抽象方法的类会自动变成抽象类,必须用abstract关键字,如果派生类没有重写抽象方法,编译器会报错。抽象方法用来被确保派生类会实现这个方法。
- 抽象方法不能包含在非抽象类中。如果抽象父类的子类不能实现所有的抽象方法,那么子类也必须定义为抽象的。抽象方法是非静态的。
- 抽象类不能使用new操作符来初始化。(可构造这个方法)
- 包含抽象方法的类必须是抽象的,不能实例化。
- 子类可以重写父类的方法并将它定义为抽象的。
- 即使子类的父类是具体的,这个子类也可以是抽象的
- 不能使用new操作符从一个抽象类创建一个实例,但是抽象类可以用作一种数据类型。
下面语句创建一个元素是GeometricObject类型的数组是正确的:
GeometricObject[] objects = new GeometricObject[10];
- 然后可以创建一个GeometricObject的实例,并将它的引用赋值给数组,如下所示
objects[0]=new Circles();
4.抽象类的举例
- 抽象的Number类
import java.util.ArrayList;
import java.math.*;
public class LargestNumber {
public static void main(String[] args) {
// TODO Auto-generated method stub
ArrayList<Number>list = new ArrayList<>();
list.add(45);//Add an integer
list.add(3445.53);//Add a double
//Add a BigInteger
list.add(new BigInteger("3432323234344343101"));
//Add a BigDecimal
list.add(new BigDecimal("2.0909090989091343433344343"));
System.out.println("The largest number is "+
getLargestNumber(list));
}
private static Number getLargestNumber(ArrayList<Number> list) {
// TODO Auto-generated method stub
if(list==null ||list.size()==0)
return null;
Number number=list.get(0);
for (int i =1;i<list.size();i++)
if(number.doubleValue()<list.get(i).doubleValue())
number=list.get(i);
return number;
}
}
运行结果
The largest number is 3432323234344343101
程序创建了一个Number对象的ArrayList(第六行),向列表中添加一个Integer对象、一个Double对象、一个BigInteger对象。
二、接口的简介
1.接口介绍
接口是一种与类相似的结构,用于为对象定义共同的操作。
类和接口之间的关系成为接口继承,因为接口继承和类继承本质上是相同的,所以我们将它们都建成为继承。
为了区分接口和类,Java采用下面的语法来定义接口:
modifier interface InterfaceName{
/**Constant declarations*/
/**Abstract method signatures*/
}
2.接口的相关特性
- 接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为public abstract(只能是public abstract,其他修饰符会报错)。
- 接口中可以含有变量,但是接口中的变量会被隐式的指定为public static final 变量(并且只能是public,用private修饰会报编译错误)。
- 接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法。
- 接口中的方法都是共有的。
3.接口的举例
- 接口的实现:
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;
}
public static void main(String args[]){
MammalInt m = new MammalInt();
m.eat();
m.travel();
}
}
运行结果:
Mammal eats
Mammal travels
三、抽象类和接口的区别与联系
1.区别
抽象类 | 接口 | |
关键字 | abstract class | interfoce |
字段 | 无限制 | public、static、final |
方法 | 即可普通方法,也可抽象方法 | 只能含抽象方法,必须为public |
继承 | 只能被类或抽象类继承 | 可被接口继承 |
多重继承 | 不支持 | 可以继承多个父接口 |
关于类 | 一个类只能继承一个抽象类 | 一个类却可以实现多个接口 |
- 举例:Java只允许为类的继承做单一继承,但是允许使用接口做多重继承
public class NewClass extends BaseClass
implements Interface1,...,InterfaceN{
...
}
- 利用关键字extends,接口可以继承其它接口。这样的接口成为子接口(subinterface)。例如:
public interface NewInterface extends Interface1,...,InterfaceN{
//constants and abstract methods
}
2.联系
- 抽象类和接口都是用来制定多个对象的共同特性的,通常,推荐使用接口而非抽象类,因为接口可以为不相关类定义共同的父类型,接口比类更灵活。
- 通常来说决定使用类还是接口时:
- 比较强的is-a(是一种)关系清晰地描述了父子关系,应该采用类来建模。
例如:因为橘子是一种水果,它们的关系就应该采用类的继承关系来建模。 - 比较弱的is-a关系,也称为is-kind-of(是一类)关系,标明一个对象拥有某种属性,弱的is-a关系可以使用接口建模。
例如:所有的字符串都是可以比较的,因此String类实现了Comparable接口。