论坛首页 入门技术论坛

abstract and interface

浏览 6224 次
该帖已经被评为新手帖
作者 正文
   发表时间:2007-01-10  

1、可以实现多个interface(implements),但只能继承(extends)一个abstract类;

2、abstract类要声明方法体,但不提供实现;interface不用声明方法体,不允许提供方法的实现;

exam:

public abstract class family {
 void eat() {
 }
 void eat(String s) {
 }

}

而interface如下:

public interface family {
 void eat();
 void eat(String s);

}

智力测试:所有继承抽象类的类,必须实现抽象类中的各个方法,对吗?

答:不对,如果子类不是抽象类那么需要实现各个方法。

3、不能创建接口或抽象类的实例。

exam:family f = new family();  //error

4、继承abstract的子类可以部分实现基类的方法(非abstract方法),而interface必须全部实现。

exam:

public abstract class family {
 abstract void eat();
 abstract void eat(String s);
  void run() {  //这个在子类中没有实现,如果为abstract类型则必须在子类中实现
 }
}

public  class grandpa extends family {

 public void eat(){
  System.out.println("grandpa eat!");
 }

 @Override
 void eat(String s) {
  // TODO Auto-generated method stub
  
 }
}

Java的interface和abstract class都可以定义不提供具体实现的方法。其中一个类不能继承自多个abstract class,但是可以实现多个interface。Java的类没有多重继承,所以用interface的概念来补充,通过实现多个interface来实现多重的继承。

在Java中所有的对象都用类来描绘,但是不是每一个类都用来描绘对象的。用来描绘某一类对象共有的本质,这就是抽象。比如:形状存在着圆、三角形这样一些具体概念,它们是不同的,但是它们又都属于形状这样一个概念,形状这个概念在问题领域是不存在的,它就是一个抽象概念。正是因为抽象的概念在问题领域没有对应的具体概念,所以用以表征抽象概念的抽象类(这儿的抽象类并不是abstract class翻译而来的,它包括interface和abstract class)是不能够实例化的。我们可以构造出一个固定的一组行为的抽象描述,但是这组行为却能够有任意个可能的具体实现方式。

从语言层面上面来讲:abstract class可以有自己的数据成员,也可以有非abstarct的成员方法,而在interface方式的实现中,只能够有静态的不能被修改的数据成员(也即interface是static final的),所有的成员方法都是abstract的。从这种角度来说,interface是abstarct class的一种特殊情况。abstract class可以提供某些方法的部分实现,而interface不可以,这大概就是abstract class唯一的优点吧,但这个优点非常有用。如果向一个抽象类里加入一个新的具体方法时,那么它所有的子类都一下子都得到了这个新方法,而interface做不到这一点,如果向一个interface里加入一个新方法,所有实现这个接口的类就无法成功通过编译了,因为你必须让每一个类都再实现这个方法才行。

而从设计出发:假设在我们的问题领域中有一个关于Door的抽象概念,该Door具有执行两个动作open和close,此时我们可以通过abstract class或者interface来定义一个表示该抽象概念的类型,定义方式分别如下所示:
abstract class:

代码
  1. abstract class Door{   
  2.     abstract void open();   
  3.     abstract void close();   
  4. }  

<script>render_code();</script>
interface:

代码
  1. interface Door{   
  2.     void open();   
  3.     void close();   
  4. }  

<script>render_code();</script>
其他具体的Door类型extends absract class或者implements interface就可以了。
看起来好像使用abstract class和interface没有大的区别。

 

但是现在如果要求Door加上报警的alarm功能,我们应该如何去设计程序的结构呢?
方案一、简单的在abstract class添加abstract void alarm()方法或者在interface中加一个alarm()方法?但是如果这样,在Door的定义中把Door概念本身固有的行为方法和另外一个概念"报警器"的行为方法混在了一起。这样引起的一个问题是那些仅仅依赖于Door这个概念的模块会因为"报警器"这个概念的改变(比如:修改alarm方法的参数)而改变。
方案二、既然open()、close()和alarm()是属于两个不同的概念,那么就应该分两个模块来设计。那,这样是应该分成两个abstract class、两个interface还是一个abstract class一个interface呢?
在java中,类是不支持多重继承的,所以,第一种方式不行,第二种方式,用两个interface来描绘:当我们明白AlarmDoor是属于alarm或者door的一种的时候,它会有一个侧重点,用两个相同的interface来描绘,很明显是不能够描绘出来问题的特点的。假设AlarmDoor是属于一个具有报警功能的Door,那么它本质上来说,是一个Door,不过是附加了alarm()的功能而已。所以对于Door的概念我们应该用一个abstract class去描绘,而alarm()的功能则用interface去描绘,代码如下:

代码
  1. abstract class Door{   
  2.     abstract void open();   
  3.     abstract void close();   
  4. }   
  5. interface Alarm{   
  6.     void alarm();   
  7. }   
  8. Class AlarmDoor extends Door implements Alarm{   
  9.     void open(){...}   
  10.     void close(){...}   
  11.     void alarm(){...}   
  12. }  

<script>render_code();</script>

 

文章借鉴了csdn的jackrong的一篇文章的例子(原文地址已经不知道了),而本身对于abstarct class和interface的理解有一部分也来自这个文章,当是我模仿加抄袭写成的文章吧。初学Java,对概念确实达不到一个高度的认识,只有通过这样的方式,希望今后可以慢慢提高……

   发表时间:2007-01-10  
java的interface还可以定义常量比如

interface Alarm {
   public static final int WARNING = 2;
}


呵呵,献丑了
0 请登录后投票
   发表时间:2007-01-10  
最上面 abstract 的例子是有误导的.
没有abstract  方法的 abstract  类,仅仅是限制了其无法实例化,

应该
public abstract class family {
 abstract  void eat() ;
 void eat(String s) {
 }

}



类与接口的关系叫作实现,而不是继承.
abstract 类可以只实现部分接口方法.
0 请登录后投票
   发表时间:2007-02-09  
谢谢,已经改正。
0 请登录后投票
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics