为什么我不能在Java中编写“implements A Class”?

时间:2011-01-14 22:11:08

标签: java compiler-construction jvm

在Java中,人们经常将类与类一起定义并尽可能使用接口名而不是类名,以便以后允许新的实现。这里逻辑接口是重复的。

如果Java允许使用类作为接口,例如:class MyScanner extends MyStuff implements java.util.Scanner,则不需要这种“以防万一”重复。此外,这将缓解我需要提供类类型但我不想扩展该类的情况。

据我所知,“实现类”不仅会被编译器拒绝,还会被JVM拒绝(如果我将此声明破解为类文件)。对此有一些技术上的困难,还是不重要?它看起来不像是向后兼容问题(我的意思是,如果JVM支持这个问题,旧代码就可以运行了。)

编辑:为了澄清,我将在这里复制StriplingWarrior更好的相同问题的措辞:

为什么一个类“实现”另一个类的方法契约而不实际扩展该类?这是技术问题吗?是否会以某种方式向我们展示OP无法预见的一些问题?

3 个答案:

答案 0 :(得分:9)

我是否理解MyClass implements AClass是否意味着MyClass必须为AClass所拥有的所有公共方法提供(或继承)实施?即每个类隐式定义一个由其公共方法组成的接口?

如果是这样,那么我看到的问题是接口实际上与类非常不同,并且两者不应该像那样混合。接口定义合同,对实现进行分类。结果是:类的功能可以相对自由地扩展,但不能与现有实现接口。

因此,您有一个非常具体的理由说明您的建议不好:您永远不会将任何公共方法添加到任何类,而不会破坏implements该类的某些代码。

另一方面,它会解决什么问题?当您具有单个实现的接口时代码重复?如何解决这个问题呢? IMO通常是由于人们在使用过时的模拟框架而不能模仿具体类的情况下进行TDD教学所做的事情。

答案 1 :(得分:5)

问题是multiple inheritance。如果您尝试扩展或实现两个类,则存在潜在的语义问题。

您可以实现多个接口,也可以从一个类扩展。但是你只能通过强制规范本质上是声明性的,要求实现者直接实现这些方法来实现接口,这些接口可以解决多重继承的大部分问题。在这种情况下,方法冲突通过简单的方法实现一个方法并使其计入两个接口来解决。

答案 2 :(得分:1)

如前所述,这就是标准的定义方式,而不是决策制定过程的一部分,我只能以0.02美元的价格购买。

这不是重复的逻辑接口,而是创建您希望灵活的API的标准。即使在支持多继承的语言中,它也被认为是一种良好的设计实践,可以从API公开接口。

鉴于IDE的当前状态,很容易不事先做到这一点,然后在你决定需要多个给定类型的实现时重构。

对于这种情况,可能还存在一些用例,在这些用例中,您对代码的功能有很强的依赖性,并且您的代码可能会破坏不同的实现。这是能够做到的一点:

ClassA a = new ClassA();

而不是

InterfaceA a = new ClassA();

这可能会导致意外行为。