Java中抽象类和接口在使用上如此相似,在高级开发中应该如何使用两者,本文对抽象类和接口的区别做如下总结。
一、抽象类
1.定义
抽象类:包含一个抽象方法的类称为抽象类,在方法头中使用abstract修饰符表示
abstract class A{
public abstract void fun();
};
public class AbstractDemo01{
public static void main(String[] args) {
A a = null;//声明对象
a = new A();//出错,不能直接进行实例化操作
}
};
2.抽象类继承
对于抽象类,不能直接进行实例化的操作,但是可以声明,如果想使用抽象类,则必须依靠子类,抽象类是必须被子类继承的,而且被继承的子类需要实现抽象类中的全部抽象方法
abstract class Person{
public abstract void fun();
};
class Student extends Person{//继承抽象类
public void fun(){//覆写方法时需要注意访问控制权限
System.out.println("Hello World!");
}
};
public class AbstractDemo02{
public static void main(String[] args) {
Student s = new Student();
}
};
3.抽象方法
抽象方法只有定义而没有实现,抽象类中允许有构造方法,但是此构造方法时不能直接调用的,交给子类去调用,子类对象的实例化过程中,先调用父类中的构造方法
abstract class Person{
private String name ;
public Person(String name){ //构造方法
this.name = name ;
}
public String getName(){
return this.name ;
}
public abstract void fun() ;
};
class Student extends Person{ //继承抽象类
public Student(String name){
super(name) ;
}
public void fun(){ //覆写方法时需要注意访问控制权限
System.out.println(super.getName()) ;
}
};
public class AbstractDemo03{
public static void main(String args[]){
Student s = new Student("GEEKFANR") ;
s.fun() ;
}
};
4.抽象类的应用
从对象多态性的改变上来看,子类为父类实例化是一个比较容易的操作,因为可以发生自动的向上转型关系,那么调用的方法永远是被子类覆写过的方法
abstract class Person{
private String name ;//姓名属性
private int age ;//年龄属性
public Person(String name,int age){//工人和学生都有姓名和年龄
this.name = name ;
this.age = age ;
}
public String getName(){
return this.name ;
}
public int getAge(){
return this.age ;
}
public void say(){//说话是一个具体的功能,不同的人物说话内容由各个子类单独实现
System.out.println(this.getContent()) ;
}
public abstract String getContent() ;
};
class Student extends Person{//继承抽象类
private float score ;
public Student(String name,int age,float score){
super(name,age) ;
this.score = score ;
}
public String getContent(){//Student类覆写Person类的getContent()抽象方法
return "学生说我叫:" + super.getName()
+ ",我今年:" + super.getAge()
+ ",我的成绩:" + this.score ;
}
};
class Worker extends Person{//继承抽象类
private float salary ;
public Worker(String name,int age,float salary){
super(name,age) ;
this.salary = salary ;
}
public String getContent(){{//Worker类覆写Person类的getContent()抽象方法
return "工人说我叫:" + super.getName()
+ ",我今年:" + super.getAge()
+ ",我的工资:" + this.salary ;
}
};
public class AbstPolDemo{
public static void main(String args[]){
Person per1 = new Student("大队长",20,89.0f) ;
Person per2 = new Worker("张全蛋",30,5189.0f) ;
per1.say() ;
per2.say() ;
}
};
二、接口
1.定义
接口是一个特殊的类,在Java中接口是由抽象方法和全局常量组成
interface A{
public static final String INFO = "GEEKFANR" ; // 全局常量
public abstract void fun() ; // 抽象方法
}
2.接口继承
接口与抽象类一样,需要有子类,此时不再称为继承类,而是实现接口,通过implements关键字完成,接口继承本质上与类继承相同。
interface A{
// public static final String INFO = "GEEKFANR" ;//简化操作
String INFO = "GEEKFANR" ; // 全局常量
// public abstract void print() ;//简化操作
void print() ; // 抽象方法
public void fun() ; // 抽象方法
}
class B implements A{ // 子类B实现了接口A
public void print(){ // 实现抽象方法
System.out.println("HELLO WORLD!!!") ;
}
public void fun(){
System.out.println(INFO); // 输出全局常量
}
};
public class InterfaceDemo02{
public static void main(String args[]){
B b = new B() ;
b.print() ;
b.fun() ;
}
};
注意:由于接口中所有的数据域都是public final static而且所有的方法都是public abstract,所以Java允许忽略这些修饰符,简化操作。
3.接口的多继承
Java只允许为类的扩展做单一继承,但是允许使用接口做多重继承
interface A{
String INFO = "CHINA" ; // 全局常量
void print() ; // 抽象方法
public void fun() ; // 抽象方法
}
interface C{
public void funA() ;
}
class B implements A,C{ // 子类B实现了接口A
public void print(){ // 实现抽象方法
System.out.println("HELLO WORLD!!!") ;
}
public void fun(){
System.out.println(INFO); // 输出全局常量
}
public void funA(){
System.out.println("信息:" + INFO) ;
}
};
public class InterfaceDemo03{
public static void main(String args[]){
B b = new B() ;
b.print() ;
b.fun() ;
b.funA() ;
}
};
4.接口的灵活性
一个接口虽然不可以继承一个抽象类,但是一个接口却可以同时继承多个接口
interface A{
public void printA() ;
}
interface B{
public void printB() ;
}
interface Z extends A,B{ // X接口同时继承了A和B两个接口
public void printZ() ;
}
abstract class C{
public abstract void printC() ;
};
class X extends C implements Z{
public void printA(){}
public void printB(){}
public void printC(){}
public void printZ(){}
};
public class InterfaceDemo04{
public static void main(String args[]){
B b = new B() ;
b.print() ;
b.fun() ;
b.funA() ;
}
};
5.接口的应用
接口可以通过对象多态性进行对象的实例化操作
interface USB{
public void start() ; // 开始工作
public void stop() ; // 结束工作
}
class Computer{
public static void plugin(USB usb){
usb.start() ;
usb.stop() ;
}
};
class Flash implements USB{
public void start(){
System.out.println("U盘开始工作。") ;
}
public void stop(){
System.out.println("U盘停止工作。") ;
}
};
class Print implements USB{
public void start(){
System.out.println("打印机开始工作。") ;
}
public void stop(){
System.out.println("打印机停止工作。") ;
}
};
public class InterPolDemo{
public static void main(String args[]){
Computer.plugin(new Flash()) ;
Computer.plugin(new Print()) ;
}
};
三、总结
No. | 比较点 | 抽象类 | 接口 |
---|---|---|---|
1 | 组成 | 抽象方法、普通方法、常量、变量、构造方法、全局常量 | 抽象方法、全局常量 |
2 | 定义 | abstract | interface |
3 | 子类 | 子类通过extends继承抽象类 | 子类通过implents实现接口 |
4 | 限制 | 一个子类只能继承一个抽象类 | 一个子类可以同时实现多个接口 |
5 | 关系 | 一个抽象类可以实现多个接口 | 一个接口不能继承一个抽象类只能实现多个接口 |
一个抽象类中可以包含多个接口 | 一个接口中可以包含多个抽象类 | ||
6 | 设计模式 | 模板设计 | 工厂设计、代理设计 |
两个一起操作可以完成适配器设计 | |||
7 | 实例化 | 通过对象的多态性,通过子类进行对象的实例化操作 | 通过对象的多态性,通过子类进行对象的实例化操作 |
8 | 实现限制 | 存在单继承局限 | 不存在此类局限 |
9 | 特性 | - | 表示一个标准、一种能力 |
因为接口可以避免单继承的局限,如果抽象类和接口同时都可以使用的话,优先使用接口