Java的接口和抽象类都可以定义不提供具体实现的方法,功能上很相似,对多态都提供了很好的支持。下面我们就来好好认识认识这两个知识点。
ps:因为都是一些基本概念性的东西,所以我就不写代码举例了。
抽象类(Abstract Class)
1. 什么是抽象类,它的作用是什么呢?
先说下抽象类长啥样,Java里面定义抽象类很简单,用abstract修饰的类就是抽象类。抽象类是实现多态的一种机制。
抽象类是不能实例化的,抽象类代表那一类的事物,不能实例化为具体的对象。很多人都会问为什么不能实例化?因为语法上就是这么规定的,你new一个就会报错。所以,抽象类主要是起到规范的作用,它只是声明了成员变量和方法,是要子类去实现他的所有的抽象方法的。
2. 使用抽象类,需要注意什么?
① 抽象类是不能实例化的(上面已经讲过)。
② 要求非抽象子类必须实现基类中的抽象方法。
③ 只要类中存在抽象方法,要求该类必须是抽象类。
④ 抽象类内可以全都是抽象方法,也可以没有抽象方法。
⑤ 基类内不能写静态的抽象方法,因为不能被重写。
3. 一个小例子
举个常用的抽象类“人”,两个子类“男人”、“女人”。“人”有个可继承普通方法【走路】,有个抽象方法【撒尿】。“男人”和“女人”【撒尿】方式是不一样的,声明为抽象方法最好。而【走路】都是一样的,可以在父类实现好,子类继承就可以了。
这就是抽象类的好处,把子类的共性逻辑上提抽象出来,共有的可以继承,有区别的在子类中自己去实现。这就提高了程序的扩展、移植、复用。
接口(Interface)
1. 什么是接口,有什么用呢?
接口是抽像类的变体。定义一个接口使用interface关键字,实现一个接口使用implements关键字,接口它起到规范的作用,降低了各模块的耦合性,提高了扩展性。
2. 使用接口,需要注意些什么,它有什么特点?
① 在接口中,所有方法都是抽象的(跟抽象类不同),没有方法体。
② 接口只可以定义static final成员变量(跟抽象类不同)。
③ 接口可以继承接口,切可以多继承,可用逗号隔开。
④ 接口里的常量public static final 都可以不写,方法中的public abstract 也可以不写,编译器默认会帮我们添加。但是推荐写上,写上增加代码的可读性。
⑤ 假如两个接口中有一样的抽象方法,但是它没有实现部分,所以也就没有菱形缺陷,相当于对多继承的优化方案。
⑥ 抽象类实现某个接口,可以不实现所有接口的方法,可以由它的子类实现。而普通类即非抽象类则必须实现接口里的全部方法。
关于第五点,感觉还是写下例子比较好。
public interface InterfaceA {
public static final double PI = 3.14;
public abstract void foo();
public abstract void foo1();
public abstract void foo2();
public abstract void fooA();// A里面有B的抽象方法
}
public interface InterfaceB {
public abstract void fooA();
public abstract void fooB();
public abstract void fooC();
}
//接口多继承
public interface InterfaceC extends InterfaceA, InterfaceB{
public abstract void foo3();
}
public class Demo implements InterfaceA, InterfaceB{
// 可以看到虽然两个接口都有public abstract void fooA()这个方法,但是在实现里,只重写一次。
@Override
public void foo() {
System.out.println(InterfaceA.PI);
}
@Override
public void foo1() {
}
@Override
public void foo2() {
}
@Override
public void fooA() {
}
@Override
public void fooB() {
}
@Override
public void fooC() {
}
}
public class Demo1 implements InterfaceA, InterfaceC{
// 这个也是同理。
@Override
public void foo3() {
}
@Override
public void foo() {
}
@Override
public void foo1() {
}
@Override
public void foo2() {
}
@Override
public void fooA() {
}
@Override
public void fooB() {
}
@Override
public void fooC() {
}
}
Java 8 新特性:接口默认方法
接口的一个缺陷就是,当我们修改接口的时候,需要修改全部实现该接口的实现类。对于已发布的版本,是没法在给接口添加新的方法的同时不影响已有的实现。所以在Java 8引进了默认的方法,就解决了接口的修改与已有的实现不兼容的问题。
默认方法就是接口可以有实现方法,而且不需要实现类去实现其方法,前面需要加default 关键词来修饰。还可以有静态方法,示例如下。
public interface InterFaceD {
default void foo(){
System.out.println("默认方法可以有多个。");
}
// 静态方法
static void fooA(){
System.out.println("这是接口里面的一个静态方法");
}
}
抽象类与接口的区别
语法用法上的区别。
在抽象类中,抽象类可以拥有更丰富类型成员变量,同时也可以拥有自己的非抽象方法。但是在接口中,它仅能够有静态、不能修改的成员数据(即final static,但是我们一般是不会在接口中使用成员数据),同时它所有的方法都必须是抽象的。在某种程度上来说,接口是抽象类的特殊化。抽象层次上的区别。
抽象类是内容,是对一种事物的抽象,是整体上的抽象。比如,老师是所有教师的抽象,老师的工作是教育学生。
接口是特征,是对一种行为的抽象,是局部抽象,比如,上课、批改作业、家访。抽象概念上的区别。
抽象类所体现的是一种合理的继承关系,即父类和子类在概念本质上应该是相同的。对于接口则不然,并不要求接口的实现者和接口定义在概念本质上是一致的, 仅仅是实现了接口定义的契约而已。
抽象类和接口是java语言中两种不同的抽象概念,他们的存在对多态提供了非常好的支持,虽然他们之间存在很大的相似性。但是对于他们的选择往往反应了我们对问题的理解程度。
Java8关于接口的另一个新特性就是函数式接口,后面会结合Lambda表达式,作进一步的介绍。
写完喽!ㄟ(▔,▔)ㄏㄟ(▔,▔)ㄏㄟ(▔,▔)ㄏ
知识重在总结和梳理,只有不断地去学习并运用,才能化为自己的东西。当你能为别人讲明白的时候,说明自己已经掌握了。
欢迎转载,转载请注明出处!
如果有错误的地方,或者有您的见解,还请不啬赐教!
喜欢的话,麻烦点个赞!