论坛首页 Java企业应用论坛

【讨论】使用骨架实现类后子类是否还要实现接口

浏览 7285 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-05-13   最后修改:2009-05-13
OO

这里要讨论的是,接口、抽象类、普通类 三者的一个组合:

首先是,接口定义了功能性的方法;
然后,一个抽象类实现了这个接口,作为骨架实现类,它完成了接口的一部分实现(默认实现)
最后是一个普通类,继承自这个抽象的股价实现类,并完成了抽象类中未实现的方法。

 

接口:

public interface 交通运输able {

    void 装货();

    void 卸货();

    void 运输();

}

 

抽象类:

public class 卡车 implements 交通运输able  {

    public void 运输() {
         .....
    }

}

 

子类:

public class 某型号卡车 extends  卡车  {

    public void 装货(){
       .....
    }

    public void 卸货(){
       .....
    }
}

 

 

 以上是我给出的代码。

 

现在要考虑(或者说犹豫、疑惑)的地方是在 子类 的定义中,是否还要明示 实现 接口 ?

public class 某型号卡车 extends 卡车 implements 交通运输able {

开始我的想法是,不需要 的。因为:

1)作为父类的那个抽象类已经实现了接口,子类自然就已经实现了。

2)如果我只将这个抽象类类对外开放(允许他人扩展自己的各种卡车去)的话,可以把 接口 作为“包级私有”类封装起来。这样可以很方便日后为接口增加新的方法,只要确保新增的方法,在抽象类中都提供默认实现就可以了。

     而如果向上一行这样使子类也明示实现接口的话,就需要将接口公有化。那么日后就没法增加新方法了。(因为你不知道已经有多少人实现了这个接口,你一增加新方法,他们必须相应地增加实现)

 

似乎在“子类中也明示实现接口”是对自己的禁锢。但是,我之所以要发这个帖子请大家讨论的原因是,我看了 List、AbstractList、ArrayList 这三个源码。

 

恰恰在 AbstractList 已经实现了 List 接口的情况下,其子类 ArrayList  仍然明示的实现了 List 接口。我不知道这是一种严谨的做事风格呢?还是作者出于对自己的充分自信呢(List接口日后肯定不会扩充新方法了!)?

 

欢迎大家讨论。

 

   发表时间:2009-05-13  
抽象类的名子叫:卡车运输....不叫卡车.
0 请登录后投票
   发表时间:2009-05-13  
抛出异常的爱 写道
抽象类的名子叫:卡车运输....不叫卡车.


为什么呢?

是不是应该:
子类叫 卡车,抽象类叫 Abstract交通运输

这样才符合命名习惯
0 请登录后投票
   发表时间:2009-05-13  
强调子类有独立的实现,方便阅读吧

抽象类有了对接口实现,子类没有实现也不会出现编译错误,在接口调用的时候,调用的都是抽象类的实现,如果在子类有了实现,是以覆盖超类方法的形式出现的,明显没有实现接口的约束力强,如果indexOf方法,你写成了indexof,这时不会出现编译错误,调用时候还是会调用超类的方法,子类的独立实现就成了永远不会用到的部分。
0 请登录后投票
   发表时间:2009-05-14  
TonyLian 写道
抛出异常的爱 写道
抽象类的名子叫:卡车运输....不叫卡车.


为什么呢?

是不是应该:
子类叫 卡车,抽象类叫 Abstract交通运输

这样才符合命名习惯

名子清楚了,意义也就明确了
用的时候就不太会用错

不产生歧义是接口的一个重要作用.
0 请登录后投票
   发表时间:2009-05-15  
iaimstar 写道
强调子类有独立的实现,方便阅读吧

抽象类有了对接口实现,子类没有实现也不会出现编译错误,在接口调用的时候,调用的都是抽象类的实现,如果在子类有了实现,是以覆盖超类方法的形式出现的,明显没有实现接口的约束力强,如果indexOf方法,你写成了indexof,这时不会出现编译错误,调用时候还是会调用超类的方法,子类的独立实现就成了永远不会用到的部分。


即便子类也实现接口,如果把indexOf写成了indexof,也同样不会编译出错呀,依然是使用超类的indexOf。
从这一点上看不出 子类 写不写 implements 接口 的差别吧。
0 请登录后投票
   发表时间:2009-05-15   最后修改:2009-05-15
是不会编译出错,不过既然是Collection的东西,想必Joshua Bloch这个家伙知道点什么,可以翻翻Effective Java ,我怀疑里面肯定有
0 请登录后投票
   发表时间:2009-05-15   最后修改:2009-05-15
刚才翻了翻,思考的顺序反了就造成这个结果。
这叫个什么模式来着?偶忘了
从作者写ArrayList开始,首先ArrayList实现了List,有很多List实现,如果List要增加接口,所有的实现类就必须都修改,于是作者增加了AbstractList,这样只要实现List接口的类继承了这个AbstractList,即使List接口发生了变化,只需要修改AbstractList就可以保证其他的所有不需要新方法的List实现者继续正常工作,所以作者的思考顺序是ArrayList首先实现了List,然后才去继承了AbstractList

参考阅读
Effective Java中文版的88页

http://forums.sun.com/thread.jspa?threadID=693119&tstart=1844
3 请登录后投票
   发表时间:2009-05-15  
iaimstar 写道
刚才翻了翻,思考的顺序反了就造成这个结果。
这叫个什么模式来着?偶忘了
从作者写ArrayList开始,首先ArrayList实现了List,有很多List实现,如果List要增加接口,所有的实现类就必须都修改,于是作者增加了AbstractList,这样只要实现List接口的类继承了这个AbstractList,即使List接口发生了变化,只需要修改AbstractList就可以保证其他的所有不需要新方法的List实现者继续正常工作,所以作者的思考顺序是ArrayList首先实现了List,然后才去继承了AbstractList

参考阅读
Effective Java中文版的88页

http://forums.sun.com/thread.jspa?threadID=693119&tstart=1844

受教了....这样也可以啊
0 请登录后投票
   发表时间:2009-05-15  
0 请登录后投票
论坛首页 Java企业应用版

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