我与一位同事进行了一次讨论,他坚持认为,在Java和C#等语言中,永远不会有任何理由使用纯抽象基类,因为这只是意味着您无法绕过多重继承的缺失。
我觉得他在这一点上错了,因为我一直认为,如果一个东西是名词,那么它就是宾语,如果它是动词,那么它就是一个接口。
例如,如果我想定义类型Bird,我想在不实现方法fly的情况下强制执行它,那么我会使它成为一个纯抽象类。
如果我想定义一个类型Flies,我会用fly方法使它成为一个接口。
Bird可能会实现Flies。
我说错了吗?
编辑:
为了支持我的观点,我能给出的唯一可靠的论据是,在未来的某个时候,设计可能需要改变,以便鸟类可以吃东西。如果所有的鸟都吃同样的东西,那么这就需要添加到Bird中,使其不是纯粹的抽象。
如果Bird是一个接口,那么这种更改将是一场噩梦,因为我不知道从其他基类继承的东西是否也实现了我的Bird接口,所以我不能简单地重构我的问题。
发布于 2012-02-29 19:06:29
除了你的第一次编辑,也就是将来的一些需求。一种可能的用例是声明一个常量并在抽象类中对其进行初始化。
import java.util.ArrayList;
import java.util.List;
public abstract class AbstractPure implements ISomeInterface {
public static final List<String> days = new ArrayList<String>();
static{
days.add("Monday");
days.add("Tuesday");
days.add("Wednesday");
days.add("Thursday");
days.add("Friday");
days.add("Saturday");
days.add("Sunday");
}
}发布于 2012-02-29 19:04:37
我能想到至少一个很好的理由:您可以稍后扩展抽象类,而不会破坏向后兼容性:假设一个类/接口
abstract class/interface Foo {
void foo();
}如果我们使用一个接口,我们现在肯定知道没有办法向Foo添加额外的功能。这可能会导致像interface Foo2 implements Foo这样的事情。
另一方面,如果你有一个抽象类,你可以很容易地向它添加另一个方法,只要你提供了一个基础实现。
请注意,Java8将允许Interfaces做基本上相同的事情-这对于想要更新他们的库以使用lambda的库编写者来说很有用,而不一定会破坏与已经编写的数百万行代码的兼容性。
发布于 2012-02-29 19:00:55
我对纯抽象类做了一些搜索(我上次使用C++已经有一段时间了),我能找到的唯一的用例就是在C++中定义接口(它没有接口)。
所以我想说,如果你可以使用一个纯粹的抽象类,你也可以像你的朋友说的那样,使用一个接口。
但是,我从来没有遇到过在C#中需要一个纯抽象类,所以这可能是一个假设问题。
https://stackoverflow.com/questions/9497729
复制相似问题