精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-05-13
最后修改:2009-05-13
这里要讨论的是,接口、抽象类、普通类 三者的一个组合:
接口: 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接口日后肯定不会扩充新方法了!)?
欢迎大家讨论。
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-05-13
抽象类的名子叫:卡车运输....不叫卡车.
|
|
返回顶楼 | |
发表时间:2009-05-13
抛出异常的爱 写道 抽象类的名子叫:卡车运输....不叫卡车.
为什么呢? 是不是应该: 子类叫 卡车,抽象类叫 Abstract交通运输 这样才符合命名习惯 |
|
返回顶楼 | |
发表时间:2009-05-13
强调子类有独立的实现,方便阅读吧
抽象类有了对接口实现,子类没有实现也不会出现编译错误,在接口调用的时候,调用的都是抽象类的实现,如果在子类有了实现,是以覆盖超类方法的形式出现的,明显没有实现接口的约束力强,如果indexOf方法,你写成了indexof,这时不会出现编译错误,调用时候还是会调用超类的方法,子类的独立实现就成了永远不会用到的部分。 |
|
返回顶楼 | |
发表时间:2009-05-14
TonyLian 写道 抛出异常的爱 写道 抽象类的名子叫:卡车运输....不叫卡车.
为什么呢? 是不是应该: 子类叫 卡车,抽象类叫 Abstract交通运输 这样才符合命名习惯 名子清楚了,意义也就明确了 用的时候就不太会用错 不产生歧义是接口的一个重要作用. |
|
返回顶楼 | |
发表时间:2009-05-15
iaimstar 写道 强调子类有独立的实现,方便阅读吧
抽象类有了对接口实现,子类没有实现也不会出现编译错误,在接口调用的时候,调用的都是抽象类的实现,如果在子类有了实现,是以覆盖超类方法的形式出现的,明显没有实现接口的约束力强,如果indexOf方法,你写成了indexof,这时不会出现编译错误,调用时候还是会调用超类的方法,子类的独立实现就成了永远不会用到的部分。 即便子类也实现接口,如果把indexOf写成了indexof,也同样不会编译出错呀,依然是使用超类的indexOf。 从这一点上看不出 子类 写不写 implements 接口 的差别吧。 |
|
返回顶楼 | |
发表时间:2009-05-15
最后修改:2009-05-15
是不会编译出错,不过既然是Collection的东西,想必Joshua Bloch这个家伙知道点什么,可以翻翻Effective Java ,我怀疑里面肯定有
|
|
返回顶楼 | |
发表时间: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 |
|
返回顶楼 | |
发表时间: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 受教了....这样也可以啊 |
|
返回顶楼 | |
发表时间:2009-05-15
|
|
返回顶楼 | |