纯抽象类和接口之间的区别

sji*_*sji 25 c# java oop

我和一位同事讨论过,他坚持认为在Java和C#这样的语言中,没有任何理由使用Pure Abstract基类,因为它只是意味着你无法避免缺少多重继承.

我觉得他错了,因为我一直以为如果一个东西是名词那么它就是一个对象,如果它是一个动词那么它就是一个界面.

例如,如果我想定义类型Bird,我想在fly不实现它的情况下强制执行该方法,那么我将使它成为一个纯抽象类.

如果我想定义一个类型Flies,我会把它作为该方法的接口fly.

Bird可能会实施Flies.

我错了吗?

编辑:

我能给予支持我观点的唯一可靠论点是,在未来的某个时刻,设计可能需要改变,以便鸟类可以吃.如果所有的鸟都吃同样的东西,那么就需要添加Bird它,使它成为非纯抽象的.

如果Bird是一个接口,这个改变只会是一场噩梦,因为我不知道从其他基类继承的东西是否也实现了我的Bird接口,所以我不能只重构我的问题.

Voo*_*Voo 10

我至少可以想到一个很好的理由:您可以在以后扩展抽象类,而不会破坏向后兼容性:假设一个类/接口

abstract class/interface Foo {
    void foo();
}
Run Code Online (Sandbox Code Playgroud)

如果我们使用接口,我们现在确定无法向Foo添加其他功能.这可能导致类似的事情interface Foo2 implements Foo.

另一方面,如果你有一个抽象类,只要提供一个基本实现,你就可以轻松地为它添加另一个方法.

请注意,Java8将允许接口基本上做同样的事情 - 这对于想要更新其库以使用lambdas而不必破坏与已编写的数百万行代码的兼容性的库编写者将是有用的.


Fav*_*ius 6

除了你的第一次编辑,即未来的一些要求.一个可能的用例可以声明一个常量并在抽象类中初始化它.

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"); 
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 从技术上讲,这不再是一个纯粹的抽象类...... (6认同)