纯抽象类和接口之间的区别 [已关闭]

2022-09-01 17:46:55

我和一位同事讨论过,他坚持认为,在Java和C#等语言中,永远没有任何理由使用纯抽象基类,因为它只是意味着你无法解决缺乏多重继承的问题。

我觉得他在这一点上是错误的,因为我一直认为,如果一个事物是名词,那么它就是一个对象,如果它是一个动词,那么它就是一个界面。

例如,如果我想定义 type ,我想在不实现它的情况下强制执行该方法,那么我会使其成为一个纯抽象类。Birdfly

如果我想定义一个类型,我会用方法使它成为一个接口。Fliesfly

Bird可能实现 。Flies

我错了吗?

编辑:

为了支持我的观点,我唯一能给出的可靠论据是,在未来的某个时候,设计可能需要改变,以便鸟类可以吃东西。如果所有的鸟都吃得一样,那么就需要加上,使它不是纯粹的抽象的。Bird

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


答案 1

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

abstract class/interface Foo {
    void foo();
}

如果我们使用一个界面,我们现在可以肯定地知道,没有办法向Foo添加其他功能。这可能会导致类似.interface Foo2 implements Foo

另一方面,如果你有一个抽象类,你可以很容易地向它添加另一个方法,只要你提供一个基本实现。

请注意,Java8 将允许接口执行基本相同的操作 - 这对于希望更新其库以使用 lambda 的库编写者非常有用,而不必破坏与已编写的数百万行代码的兼容性。


答案 2

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

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"); 
    }
}