2010-10-12 100 views
1

我正在使用Java中的某个API库。它有一个基类A,以及B和C,它们都扩展A. B & C提供了类似但不同的功能,所有三个类都在库中。如何在Java中实现多重继承

public abstract class A 
{ 
    virtual foo(); 
} 

public class B extends A {} 
public class C extends A {} 

我如何在我的课的ABC元素?如果我使用接口来实现这些类,那么会有很多重复的代码,并且内部类将不允许我覆盖现有方法,以便保留ABC的调用接口。

如何在Java中实现多重继承?

编辑: 感谢编辑乔治,现在更清楚了,忘了提到一个关键要求:我的类必须有A作为基础,以便他们可以通过平台API进行管理。

+6

那么这有什么问题? – aioobe 2010-10-12 17:07:23

+0

@Hemang,请参阅此问题的原始未经编辑的版本。 – Pops 2010-10-12 17:27:31

+0

既然你已经是谷歌,你可能知道Java和许多其他语言已经删除了多重继承。如果你可以更具体一点,为什么你必须拥有它,可以提出一个更好的选择 – Hemang 2010-10-12 17:38:46

回答

0

听起来像你想扩展A - 调用它D - 重写它的foo(),然后有新的子类E & F扩展D并添加它们自己的功能。

你可能会考虑提取常用接口并重用它们。一个具有重构功能的好IDE将使其变得容易。

14

要回顾一下,您有:

class A 
{ 
    public void foo() {} 
} 

class B extends A 
{ 
    public specificAMethod() {} 
} 

class C extends A 
{ 
    public specificCMethod() {} 
} 

以上类是,你不能访问或修改库。 你想在第三d类B和C的行为,就好像它是可以写:

class D extends B, C 
{ 
} 

,对吗?

如何使用B和C而不是继承?你真的需要继承吗?你想调用私人B和C方法?

class D 
{ 

private B b; 
private C c; 
} 
+4

比继承更喜欢构图! – 2010-10-12 17:19:15

+1

@Bill你读过“首先设计模式”吗? :)我做到了。 – vulkanino 2010-10-12 17:22:16

+0

这和代表团 – Saideira 2010-10-12 17:24:01

0

Java中不能实现多类继承,但是您可以对接口使用多继承。使用Delegation pattern,您可以将其他几个类的行为合并为一个。

+1

是的,我可以使用委托,但必须写很多胶水代码,因为类有很多方法 – Saideira 2010-10-12 17:22:31

+0

大部分IDE可以为您生成它,或者您可以使用动态代理。请参阅http://java.sys-con.com/node/37748 – 2010-10-12 17:43:32

+0

@Saideria您的课程是否太大?如果你的界面转发了很多东西,我想知道你是否可能做错了什么。例如,你可能有setter和getters--通常试图消除这些,并把调用它们的代码放到你的类中。你的班级可以做更多的事吗?也许它应该被分成多个类......这是没有正确答案的东西,但是每次你看任何代码时都要反复尝试这样的东西。从长远来看,这是完全值得的。 – 2010-10-12 20:41:06

2

如果您采用“首选合成优于继承”的一般方法,您可能会发现其中一个或两个类不应实际为“继承”。在这两种情况下,这些班级是否有严格的“是-A”关系?如果你可以大声说出“Has-a”并且听起来不笨,那么你可能需要合成。例如,如果你正在执行一副纸牌,黑桃3是-3,它是 - 黑桃,但你也可以认为它有 - 3,它有 - 一套(铲)。既然你可以这样想,那么你应该更喜欢有解释和使用的组合。

尽量远离继承树,而不是深入一些对象 - 如果您曾经感受到使用多重继承的愿望,请尝试解决它。这是Java类型迫使你设计代码的一种情况,即通过不提供一个特性来增强可读性(但是,当然,当你真的需要它时,它不在那里,并且可能会受到伤害!某些级别的mixin会是尼斯)。

0

完全不同的方法,在COM应用:所有的对象从IUnknown的,它有可能被转换为Java作为一种方法继承:

Object queryInterface(Class<?> clazz) 

这种方法的最简单的实现可以是:

if(clazz.isAssignableFrom(this.getClass())) 
    return this; 
else 
    return null; 

凡单继承是行不通的,它只是足够的补充:

else if(class == SomeClass.class) { 
    return something; 
} else ... 

通过这种方式,即使是最复杂的多重继承情况也可以得到解决,并且您可以完全控制什么返回以及何时返回,从而避免了像C++这样的语言的“经典”多重继承问题,例如fork-join问题。

0

自Java 1.8以来,您可以使用具有默认方法的接口。这非常方便,我倾向于使用它很多。 Covariant return types也被支持。有一个fiew rescription(见下文),但是你不必通过你自己来实现继承,并让编译器为你工作。

public interface A { 
    default A foo() { 
     return this; 
    } 
} 

public interface B extends A { 
    @Override 
    default B foo() { 
     return this; 
    } 
} 

public interface C extends A { 
    @Override 
    default C foo() { 
     return this; 
    } 
} 

public interface D extends B, C { 
    @Override 
    // if the return type does not implement B and C 
    // the comiler will throw an error here 
    default D foo() { 
     return this; 
    } 
} 

注意这一点,但请注意,你不能叫super.foo或定义字段或私有成员(直到Java的9),因为它仍然接口。如果你满足这些限制,这将为你打造一个新的面向对象编程水平。