【问题标题】:Full Fledged Multiple Inheritance in Java 8Java 8 中成熟的多重继承
【发布时间】:2014-12-03 18:13:17
【问题描述】:

似乎 Java 8 允许通过如下简单框架实现完全成熟的继承,在接口上使用静态和默认方法。

虽然总是有可能误用和编写愚蠢的代码,但这些新功能使实现多重继承变得相当容易,即使语言的设计者打算远离它。

这是使用接口作为基类的多重继承的简单实现,还是对语言的滥用? Java 设计人员是否允许这样做太过分了?

package PseudoMultipleInheritance;
import java.util.HashMap;

abstract class InstanceMap<T,T2>
{ 
     HashMap<Object,Object> instances = new HashMap<Object, Object>();
     abstract T2 createMembersInstance();
     T2 getMembersInstance(T thisObject )
     {
         if ( !instances.containsKey(thisObject) )
             instances.put(thisObject,createMembersInstance());
         return (T2) instances.get(thisObject);      
     }  
}

interface A  
{
 class Members
 {
    int x;  // just an example of an inheritable member 
 }
 InstanceMap<A,A.Members> instanceMap = new InstanceMap<A, A.Members>() {   A.Members createMembersInstance() {return new A.Members();  }};
 default A.Members thisA() { return instanceMap.getMembersInstance(this); }
 default int getX()
 {
     return thisA().x;  // // just an example of an inheritable getter
 }
 default void setX(int x)
 {
     thisA().x = x;  // just an example of an inheritable setter
 }
}

interface B 
{
 class Members
 {
    int y;  // just an example of an inheritable member
 }  
 InstanceMap<B,B.Members> instanceMap = new InstanceMap<B, B.Members>() {   B.Members createMembersInstance() {return new B.Members();} };  
 default B.Members thisB() { return instanceMap.getMembersInstance(this); }
 default int getYLastDigit()
 {
     return thisB().y % 10;  // just an example of an inheritable function
 }
 default void incrementY(int x)
 {
     thisB().y += x; // just an example of an inheritable function
 }
}

class C implements A, B
{
}

public class Example04AlmostMultipleInheritance {

 public static void main(String[] args) {
     C c1 = new C();
     C c2 = new C();
     c1.setX(5);
     c2.setX(3);
     System.out.println(c1.getX());   // prints 5
     System.out.println(c2.getX());   // prints 3
     c1.incrementY(99);
     System.out.println(c1.getYLastDigit());  // prints 9 

}
}

/////////////////////////////////////// ////

或者另一种选择:

interface A  
{
 class Members
 {
    public int x;  // just an example of an inheritable member
    void showX() { System.out.println(x); }  // just an example of an inheritable function
 }
 InstanceMap<A,A.Members> instanceMap = new InstanceMap<A, A.Members>() {   A.Members createMembersInstance() {return new A.Members();  }};
 default A.Members getA() { return instanceMap.getMembersInstance(this); }
}

interface B 
{
 class Members
 {
    int y;  // just an example of an inheritable member
 }  
 InstanceMap<B,B.Members> instanceMap = new InstanceMap<B, B.Members>() {   B.Members createMembersInstance() {return new B.Members();} };  
 default B.Members getB() { return instanceMap.getMembersInstance(this); }
}

class C implements A, B
{
}

public class Example04AlmostMultipleInheritance {

 public static void main(String[] args) {
     C c1 = new C();
     C c2 = new C();
     c1.getA().x = 5;
     c2.getA().x = 3;
     c1.getA().showX();   // prints 5
     c2.getA().showX();   // prints 3
     c1.getB().y = 99;
     System.out.println(c1.getB().y % 10);  // prints 9 

}
}

【问题讨论】:

  • 是的。而且它不是惯用的java。严格来说,如果您的团队成员试图在现实世界的项目中做这样的事情,您应该拿起枪将他射中腿。
  • @YegorChumakov ,瞄准键盘。它不那么凌乱了,文书工作也没有几乎那么糟糕。
  • @ElliottFrisch 文书工作?
  • @YegorChumakov 总是有文书工作。
  • 免责声明:我不对由此代码造成的任何伤害负责

标签: java multiple-inheritance default-method


【解决方案1】:

实现接口不是继承。就这么简单。

如果有人实现了您的两个接口,但提供的实现与默认实现不同,该怎么办?

所以不,这不是多重继承,它只是一种编写代码的方式,它依赖于没有人实际实现他们自己版本的默认方法。这意味着它取决于人们实际上没有按照他们应该的方式使用接口,因为他们应该能够实现自己的方法而不是默认方法,但是如果他们真的这样做了,你的“多重继承”就不起作用正如预期的那样。

所以我实际上认为这是对语言的滥用。

【讨论】:

  • 但是Java现在不要求您在接口上实现方法,从而使该术语的原始含义无效,这不是问题吗?毕竟,人们也可以覆盖基类中的方法,它仍然是继承。
  • 不需要你这样做,并不意味着你不能。这只是意味着现在你有一个选择。但如果你真的使用了这个选项,程序就会中断。
【解决方案2】:

它是多重继承的一种形式,但并不是在讨论多重继承时通常会提到的“钻石问题”。 Java 的实现与 Scala 对同一件事的解决方案几乎相同,这有点类似于 Python 实现多重继承的方式。

【讨论】:

  • 是的,看起来这可以正确处理“钻石问题”。成员访问将转到祖父接口的访问器函数,然后使用祖父接口上定义的静态哈希表成员。
【解决方案3】:

不,请参见此处的多重继承示例:http://java.dzone.com/articles/interface-default-methods-java

【讨论】:

  • 找不到页面
猜你喜欢
  • 2014-03-29
  • 1970-01-01
  • 1970-01-01
  • 2013-10-15
  • 2014-03-16
  • 2016-08-24
  • 2015-11-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多