interface,abstract class,abstract interface Java中的接口,抽象类和抽象接口的异同

接口与抽象类的比较

1.相同点:

A. 两者都是抽象类,都不能实例化。

B. interface实现类及abstrct class的子类都必须要实现已经声明的抽象方法。

2. 不同点:

A. interface需要实现,要用implements,而abstract class需要继承,要用extends。

B. 一个类可以实现多个interface,但一个类只能继承一个abstract class。

C. interface强调特定功能的实现,而abstract class强调所属关系。

D.尽管interface实现类及abstrct class的子类都必须要实现相应的抽象方法,但实现的形式不同。

interface中的每一个方法都是抽象方法,都只是声明的

(declaration, 没有方法体),实现类必须要实现。而abstract class的子类可以有选择地实现。这个选择有两点含义:

一是Abastract class中并非所有的方法都是抽象的,只有那些冠有abstract的方法才是抽象的,子类必须实现。那些没有abstract的方法,在Abstrct class中必须定义方法体。

二是abstract class的子类在继承它时,对非抽象方法既可以直接继承,也可以覆盖;而对抽象方法,可以选择实现,也可以通过再次声明其方法为抽象的方式,无需实现,留给其子类来实现,但此类必须也声明为抽象类。既是抽象类,当然也不能实例化。

E. abstract class是interface与Class的中介。

interface

是完全抽象的,只能声明方法,而且只能声明pulic的方法,不能声明private及protected的方法,不能定义方法体,也

不能声明实例变量。然而,interface却可以声明常量变量,并且在JDK中不难找出这种例子。但将常量变量放在interface中违背了其作为接

口的作用而存在的宗旨,也混淆了interface与类的不同价值。如果的确需要,可以将其放在相应的abstract class或Class中。

abstract

class在interface及Class中起到了承上启下的作用。一方面,abstract

class是抽象的,可以声明抽象方法,以规范子类必须实现的功能;另一方面,它又可以定义缺省的方法体,供子类直接使用或覆盖。另外,它还可以定义自己

的实例变量,以供子类通过继承来使用。

3、interface的应用场合

A. 类与类之前需要特定的接口进行协调,而不在乎其如何实现。

B. 作为能够实现特定功能的标识存在,也可以是什么接口方法都没有的纯粹标识。

C. 需要将一组类视为单一的类,而调用者只通过接口来与这组类发生联系。

D. 需要实现特定的多项功能,而这些功能之间可能完全没有任何联系。

4. abstract class的应用场合

一句话,在既需要统一的接口,又需要实例变量或缺省的方法的情况下,就可以使用它。最常见的有:

A. 定义了一组接口,但又不想强迫每个实现类都必须实现所有的接口。可以用abstract class定义一组方法体,甚至可以是空方法体,然后由子类选择自己所感兴趣的方法来覆盖。

B. 某些场合下,只靠纯粹的接口不能满足类与类之间的协调,还必需类中表示状态的变量来区别不同的关系。abstract的中介作用可以很好地满足这一点。

C. 规范了一组相互协调的方法,其中一些方法是共同的,与状态无关的,可以共享的,无需子类分别实现;而另一些方法却需要各个子类根据自己特定的状态来实现特定的功能。

接口与抽象接口

interface实际上就是一个抽象的,再加上abstract修饰没有多大含义,唯一可能看到这种情况就是用反编译工具生成的代码,而java源码种通常都标明了abstract和interface同时修饰一个接口,事实上这完全没必要
简要说说 接口,抽象类,实体类的用法

下面参考:http://www.cnblogs.com/iyangyuan/archive/2013/03/11/2954808.html

在程序设计过程中,读者很可能遇到这样一种困境:设计了一个接口,但实现这个接口的子类并不需要实现接口中的全部方法,也就是说,接口中的方法过多,对于某些子类是多余的,我们不得不浪费的写上一个空的实现。

今天提到的“抽象接口”,就是用来解决这个问题的。

为了不误导读者,先说明一下,什么是“抽象接口”。

所谓“抽象接口”,即在提供接口的同时,提供一个抽象类,用抽象类实现该接口(实际上这是缺省适配模式)。

下面举个例子,让读者体会这样做的好处。先上一张类图:

具体代码:

  ITestInterface.java

1 /*
2     假设有一个顶层接口
3 */
4 public interface ITestInterface{
5     void method1();
6     int method2();
7     boolean method3();
8 }

  TestAbstract.java

 1 /*
 2     抽象类abstract实现了ITestInterface顶层接口
 3 */
 4
 5 public abstract class TestAbstract implements ITestInterface{
 6     //找出接口中必要的方法,也就是子类必须实现的方法,定义成抽象方法,交由子类实现
 7     public abstract void method1();
 8     public abstract int method2();
 9
10     //一些独特的方法可以在抽象类中默认实现
11     public boolean method3(){
12         return true;
13     }
14 }

  

  TestClass1.java

 1 /*
 2     普通类TestClass1继承了TestAbstract抽象类
 3 */
 4
 5 public class TestClass1 extends TestAbstract{
 6
 7     //TestClass1必须实现抽象的method1方法,该方法最早是接口中定义的
 8     public void method1(){
 9
10     }
11     //TestClass1必须实现抽象的method2方法,该方法最早是接口中定义的
12     public int method2(){
13         return 1;
14     }
15
16     //接口中的method3方法对于TestClass1无关紧要,因此不做重写。
17 }

  TestClass2.java

 1 /*
 2     普通类TestClass2继承了TestAbstract抽象类
 3 */
 4
 5 public class TestClass2 extends TestAbstract{
 6
 7     //TestClass2必须实现抽象的method1方法,该方法最早是接口中定义的
 8     public void method1(){
 9
10     }
11     //TestClass2必须实现抽象的method2方法,该方法最早是接口中定义的
12     public int method2(){
13         return 2;
14     }
15
16     //method3方法对于TestClass2来说至关重要,因此必须重写。
17     public boolean method3(){
18         return false;
19     }
20
21 }

代码精讲:

    从以上例子可以看出,最高层的接口被一个抽象类实现,在抽象类中,我们把关键的method1、method2方法定义成抽象方法,强制子类去实现,而“独特”的method3方法在抽象类中做一个默认实现。

    等到TestClass1、TestClass2继承TestAbstract抽象类时,优势就体现出来了,TestClass1、TestClass2必须实现method1、method2,但如果用不到method3,可以直接无视。

    通过接口和抽象类的结合,避免了在实现接口的子类中出现大量的“无意义”实现,这个“无意义”实现,被缓冲到了抽象类中,完美展现了代码复用(可以把抽象类理解成接口和实现类之间的缓冲)。

    需要指出的是,我们既可以选择继承抽象类,也可以选择实现接口,并不是说一定要继承抽象类,看情况而定,这里是两种选择,两个机会。

写到这,或许读者觉得文章已经结束了,其实没有。。。

这样做的好处不仅仅是这一点,细细品味,假如我们向接口中增加了一个方法。。。

具体代码:

  温馨提示:不要被代码吓到,其实这些代码和上边的差不多,只不过加了个方法而已。

  ITestInterface.java

 1 /*
 2     假设有一个顶层接口
 3 */
 4 public interface ITestInterface{
 5     void method1();
 6     int method2();
 7     boolean method3();
 8     //接口中新增加了方法
 9     String method4();
10 }

  TestAbstract.java

 1 /*
 2     抽象类abstract实现了ITestInterface顶层接口
 3 */
 4
 5 public abstract class TestAbstract implements ITestInterface{
 6     //找出接口中必要的方法,也就是子类必须实现的方法,定义成抽象方法,交由子类实现
 7     public abstract void method1();
 8     public abstract int method2();
 9
10     //一些独特的方法可以在抽象类中默认实现
11     public boolean method3(){
12         return true;
13     }
14
15     //抽象类中提供一个默认实现,这样就可以避免"惊动"所有子类
16     public String method4(){
17         return "";
18     }
19 }

  TestClass1.java

 1 /*
 2     普通类TestClass1继承了TestAbstract抽象类
 3 */
 4
 5 public class TestClass1 extends TestAbstract{
 6
 7     //TestClass1必须实现抽象的method1方法,该方法最早是接口中定义的
 8     public void method1(){
 9
10     }
11     //TestClass1必须实现抽象的method2方法,该方法最早是接口中定义的
12     public int method2(){
13         return 1;
14     }
15
16     //接口中的method3方法对于TestClass1无关紧要,因此不做重写。
17
18     //新增的方法对于TestClass1来说至关重要,因此必须重写
19     public String method4(){
20         return "Class1";
21     }
22
23 }

  TestClass2.java

 1 /*
 2     普通类TestClass2继承了TestAbstract抽象类
 3 */
 4
 5 public class TestClass2 extends TestAbstract{
 6
 7     //TestClass2必须实现抽象的method1方法,该方法最早是接口中定义的
 8     public void method1(){
 9
10     }
11     //TestClass2必须实现抽象的method2方法,该方法最早是接口中定义的
12     public int method2(){
13         return 2;
14     }
15
16     //method3方法对于TestClass2来说至关重要,因此必须重写。
17     public boolean method3(){
18         return false;
19     }
20
21     //新增的方法对于TestClass2来说无关紧要,无需知道新增method4的存在
22 }

代码精讲:

    这段代码演示了假如项目已经成型,但是需求有变,我们不得不向接口中增加一个新的方法,假如子类直接实现了接口,那么这些子类都要修改,来实现接口新增的方法。

    但本例中的TestClass1、TestClass2子类没有直接实现接口,而是通过继承抽象类间接实现接口,这样好处一下就体现出来了!

    向接口中新增的方法,可以在实现接口的抽象类中缓冲一下,提供一个默认的实现,这样一来,就不必强制所有的子类(通过继承抽象类间接实现接口的类)都进行修改,可以形象的理解为“没有惊动子类”。而需要使用这个方法的子类,直接重写即可。

    人类的智慧真伟大!数组和链表结合,产生了高效的哈希表;接口和抽象类结合,产生了优雅的缺省适配模式。大家努力吧!!!

写在后面的话:

    世间没有完美的事物,设计模式也是如此,过多的讨论优缺点没有意义,合适的就是最好的,什么是合适的呢?这才是体现智慧的地方。

时间: 2024-10-11 06:13:07

interface,abstract class,abstract interface Java中的接口,抽象类和抽象接口的异同的相关文章

java中并不是任意多个接口都可以实现多实现

interface A{ public abstract void show(); } interface B{ public abstract int show(); } public class Test implements A, B{ public void show(){ System.out.println("A show!"); } /* 只写 void show()出现的问题: Test不是抽象的, 并且未覆盖B中的抽象方法show(); */ public int s

Java中的深克隆和浅克隆——Cloneable接口

一.没有使用克隆带来的问题 public class CloneTest { static Student s = new Student("aaa", 20); // 直接赋值带来的问题 public static void noclone() { // 传的是引用的副本,改变了noCloneStudent也改变了s Student noCloneStudent = new Student(); noCloneStudent = s; noCloneStudent.setName(&

Java中多态、抽象类和接口

1:final关键字(掌握) (1)是最终的意思,可以修饰类,方法,变量. (2)特点: A:它修饰的类,不能被继承. B:它修饰的方法,不能被重写. C:它修饰的变量,是一个常量. (3)面试相关: A:局部变量 a:基本类型 值不能发生改变 b:引用类型 地址值不能发生改变,但是对象的内容是可以改变的 B:初始化时机 a:只能初始化一次. b:常见的给值 定义的时候.(推荐) 构造方法中. 2:多态(掌握) (1)同一个对象在不同时刻体现出来的不同状态. (2)多态的前提: A:有继承或者实

java中,一个类实现某个接口,必须重写接口中的所有方法吗

不一定,关键要看子类是否是抽象类.如果子类是非抽象类,则必须实现接口中的所有方法: 如果子类是抽象类,则可以不实现接口中的所有方法,因为抽象类中允许有抽象方法的存在!1.抽象类定义抽象类往往用来表征对问题领域进行分析.设计中得出的抽象概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象.通常在编程语句中用 abstract 修饰的类是抽象类.在C++中,含有纯虚拟函数的类称为抽象类,它不能生成对象:在java中,含有抽象方法的类称为抽象类,同样不能生成对象.抽象类是不完整的,它只能用作基类

java 中调用支付宝支付功能的接口

支付宝接口: 申请支付宝接口服务: 1.https://fuwu.alipay.com/platform/doc.htm#c11   Java-JDK 1.5 SDK 2.https://cshall.alipay.com/enterprise/help_detail.htm?help_id=516349 java 调用jdk服务: 1.https://openhome.alipay.com/platform/document.htm#down 2.https://b.alipay.com/or

java中的Reference抽象类

一.概述 位于java.lang.ref包下,声明:public abstract class Reference<T> extends Object 引用对象的抽象基类.此类定义了常用于所有引用对象的操作.因为引用对象是通过与垃圾回收器的密切合作来实现的,所以不能直接为此类创建子类. 二.方法详细 1.public T get()  返回此引用对象的指示对象.如果此引用对象已经由程序或垃圾回收器清除,则此方法将返回 null. 2.public void clear()  清除此引用对象.调

java中的Buffer抽象类

一.概述 Buffer是一个抽象类,位于java.nio包下,类声明如下:public abstract classBuffer extends Object Buffer是一个用于特定基本类型数据的容器. 缓冲区是特定基本类型元素的线性有限序列.除内容外,缓冲区的基本属性还包括容量.限制和位置: 缓冲区的容量 是它所包含的元素的数量.缓冲区的容量不能为负并且不能更改. 缓冲区的限制 是第一个不应该读取或写入的元素的索引.缓冲区的限制不能为负,并且不能大于其容量. 缓冲区的位置 是下一个要读取或

java中的HttpsURLConnection抽象类

一.概述 该类位于javax.net.ssl包下,类声明:public abstract class HttpsURLConnection extends HttpURLConnection 类层次结构: java.lang.Object java.net.URLConnection java.net.HttpURLConnection javax.net.ssl.HttpsURLConnection HttpsURLConnection 扩展 HttpURLConnection,支持各种特定于

Java中的类继承机制、接口

1)声明一个Person类,有name(String类型).age(int类型).sex(char类型)属性,通过构造方法进行赋值.一个show方法,返回String类型,内容如下: 某某 男(女) 年龄 2)声明一个Student类,继承Person类,增加id(int,学号)属性,通过构造方法,利用super调用父类构造方法来进行变量赋值.Override父类的show方法,返回String类型,内容如下: 某某 男(女) 年龄 学号 (提示:利用super调用父类的show方法得到除学号部