文章目录
- Java基础---抽象类与接口
- 抽象类
- 抽象类的定义
- 抽象类的要求
- 接口
- 接口基本定义
- 接口的性质
- 接口定义的加强
- 抽象类与接口的区别
- 总结
Java基础—抽象类与接口
在类的继承中,子类继承父类的方法,如果需要进行功能的扩充,需要在子类中对父类中已有的方法进行覆写,但此时会有一个问题:父类中的关键方法,子类不知道是否需要对其进行覆写,父子之间我们需要一个约定。
对于真正需要被覆写的父类方法就需要为其设置一个特殊的使用环境,使用抽象类来实现,抽象类的主要功能就是实现对子类覆写方法的约定,后续的使用中普通的类一般不需要被继承,继承的都是抽象类。
抽象类
抽象类的定义
抽象类在形式上与其他类相比就是多了一些抽象方法,同时所有的抽象方法没有方法体,抽象方法所在的类称为抽象类,抽象方法要求必须使用abstract关键字定义,抽象类也必须用abstract关键字定义,如下所示的代码就是最基本的抽象类定义。
abstract class AbstractA{
public abstract void fun();
}
class B extends AbstractA{
public abstract void fun(){
...覆写方法体
};
}
抽象类的要求
在抽象类的使用过程中,需要遵循如下几个原则:
· 抽象类必须有子类,子类使用extnds关键字继承抽象父类;
· 抽象类的子类(如果不是抽象类)必须覆写抽象类中的全部抽象方法;
· 抽象类无法直接用new关键字实例化,所有的抽象类必须依靠子类向上转型才可以实例化对象;
· 继承抽象类的子类在命名的时候可以在名字前加上Abstract标记,说明这个子类是继承了抽象类;
· 抽象类一定要有子类继承,所以抽象类中不能使用final定义;
· 抽象类中允许没有任何的抽象方法,但没有抽象方法的抽象类依然无法进行对象的转接实例化;
· 抽象类中可以定义普通的成员属性,抽象类只是比普通类多了抽象方法,抽象类中一定存在构造方法,实现属性的初始化;
· 抽象类中提供有static方法,并且static方法不受抽象类实例化的限制;
接口
上文提到抽象类是为了限制子类对父类中的方法覆写而设置的,但继承中还会存在一个问题,继承只能够单继承,即一个子类只能通过“extends”关键字继承一个父类,为了满足的“多继承”的需求,Java引用了接口设计。
接口基本定义
接口是一种特殊形式的类,所有的接口使用“interface”关键字定义,传统的接口定义中,接口的组成就是全局常量和抽象方法,从JDK1.8之后接口定义有所加强。接口的定义如下:
interface A{
public static final int x = 6;
public abstract void send(String str);
}
说明:
在接口中提供有全局常量,可以直接通过接口来定义,但接口中的方法没有方法体,需要定义实现接口的子类,通过子类实例化来调用方法。
接口的使用规则如下:
· 接口对象无法直接实例化,必须要有子类;
· 子类通过“implements”关键字来实现若干接口;
· 接口的子类(如果不是抽象类)则一定要覆写接口中的全部抽象方法;
· 接口对象的实例化依靠对象的向上转型自动完成;
接口的使用如下所示:
class B implements A{
public void send(String str){
System.out.print("str");
}
}
因为接口中的核心组成就是抽象方法与全部局变量,所以在接口中一般可以省略abstract关键字,因为接口中定义的方法没有方法体,实现接口的子类一定需要覆写接口中的方法的。
接口的性质
接口与上述抽象类形式上非常相似,差别在于一个类可以实现多个接口但只能继承一个父类。
一个接口可以继承多个接口,接口是比类更高级的设计。
· 普通类和抽象类都可以通过implements关键字实现多个接口;
· 接口可以通过extends关键字去继承多个父接口,但是却无法继承任何一种类。
接口定义的加强
上文介绍了接口的性质,接口中的方法都是抽象方法,这样可以强制子类实现接口中的抽象方法,但这个性质有利也有弊,我们不妨来想象一下,你开开心心的写了一个接口,经过日积月累的敲代码项目规模巨大,这时候你突然想要在接口里面增加一个新的方法,这时候你面对的将会是什么呢?你需要把自己实现了这个接口的类都重新覆写这个新的方法!可能你觉得没关系,不就是加几个方法的覆写吗,写就完事了,但如果你已经实现了几千个子类呢?几万个呢?问题出现了。
在JDK1.8之前,解决这个问题的方法是,在实现接口的子类之前设置一个抽象类,这个抽象类作为中间商先实现接口,再由子类们继承它,这样只需要在抽象类中覆写这个方法就可以了,但需要注意:**子类中实现这个新增方法的操作应该完全相同。**如果每个子类都需要覆写新的方法功能的话,中间商也就没有存在的必要了。
在JDK1.8之后,Java提供了接口的加强定义,可以在接口中定义普通方法,这些普通方法可以被所有子类使用而不需要强制对他们进行覆写操作。
定义方法如下:
interface A{
//定义的新方法,不需要覆写
public default void send(String str){
System.out.print("str");
};
}
另外还提供了static定义静态方法。即,没有实例化对象字节进行调用。
interface A{
//定义的新方法,不需要覆写
public static void send(String str){
System.out.print("str");
};
}
public class Test01{
public static void mian(String args[]){
//static定义的方法可以直接调用,不需要实例化对象
A.send("张大炮");
}
}
抽象类与接口的区别
序号 | 比较 | 抽象类 | 接口 |
1 | 定义 | abstract class | interface |
2 | 组成 | 抽象方法、属性、普通方法、构造方法、全局常量 | 抽象方法、全局常量、普通方法、静态方法 |
3 | 关系 | 抽象类可以实现若干个接口 | 接口不允许继承任何类、但是可以继承多个父接口 |
4 | 子类实现 | 子类使用extends继承一个抽象类 | 子类使用implements实现多个接口 |
5 | 限制 | 单继承局限 | 不能继承类 |
总结
进行比较可以发现,接口和是抽象类的最大区别在于单继承局限性,如果接口和抽象类都有可以使用的话,优先选择接口。