在Java中,人们经常将接口与类一起定义,并在可能的情况下使用接口名称而不是类名称,以便以后允许新的实现。这里逻辑接口是重复的。
如果 Java 允许使用类作为接口,那么这种“以防万一”的重复就没有必要,例如:
class MyScanner extends MyStuff implements java.util.Scanner
。这也可以缓解我需要提供类类型但我不想扩展该类的情况。
据我了解,“实现一个类”不仅会被编译器拒绝,还会被 JVM 拒绝(如果我将此声明写入类文件)。这是否存在一些技术困难或者它不被认为是重要的事情?它看起来不像是向后兼容性问题(我的意思是,如果 JVM 支持这一点,旧代码可以正常运行)。
编辑:为了澄清起见,我将在这里复制 StriplingWarrior 对相同问题的更好措辞:
为什么一个类不能在不实际扩展该类的情况下“实现”另一个类的方法契约?是技术问题吗?它会以某种方式让我们面对一些OP无法预见的问题吗?
我是否正确理解
MyClass implements AClass
意味着MyClass
必须为AClass
拥有的所有公共方法提供(或继承)实现? IE。每个类都隐式定义了一个由其公共方法组成的接口?
如果是这样,那么我看到的问题是接口实际上与类非常不同,并且两者不应该像这样混合在一起。接口定义契约,类定义实现。其结果是:类的功能可以相对自由地扩展,但不能与现有实现进行接口。
因此,您有一个非常具体的理由来解释为什么您的建议会很糟糕:您永远不可能向任何类添加任何公共方法,而不冒着破坏该类的某些代码的风险。
另一方面,它会解决什么问题?当您有一个具有单一实现的接口时,代码重复吗?如果不这样做就可以解决这个问题吗?在我看来,这通常是人们教条地进行 TDD,同时使用无法模拟具体类的过时的模拟框架来完成的。
这与重复的逻辑接口无关,而是创建您希望灵活的 API 的标准。即使在支持多重继承的语言中,从 API 公开接口也被认为是一种良好的设计实践。
考虑到 IDE 的当前状态,很容易不预先执行此操作,然后在您决定需要给定类型的多个实现时进行重构。
也可能存在与此相反的用例,在您的代码中,您对类的功能有很强的依赖性,并且通过使用不同的实现,您的代码可能会崩溃。这就是能够做到的点:
implements
而不是
ClassA a = new ClassA();
这可能会导致意外行为。