2009-05-21 137 views
5
public abstract class Parent { 

    private Parent peer; 

    public Parent() { 
     peer = new ??????("to call overloaded constructor"); 
    } 

    public Parent(String someString) { 
    } 

} 

public class Child1 extends parent { 

} 

public class Child2 extends parent { 

} 

当我构建Child1的实例,我希望有一个“同行”自动构建它的类型是Child1还,并存储在同行财产。对于Child2,同样是Child2类型的对等。呼叫从抽象类子类构造函数在Java中

的问题是,在父类中对财产的分配。我无法通过调用new Child1()因为那将不是CHILD2工作构建一个新的子类。我怎样才能做到这一点?有没有一个关键字可以用来引用子类?像new self()

+1

似乎是一个奇怪的图案给我。使用“ParentFactory”来实例化这些对象可能会更好吗? – 2009-05-21 08:09:45

+0

这是一个非常奇怪的设计。我想,同行的同伴会是原始的对象吗? – Thilo 2009-05-21 08:23:48

+0

_peer_变成了什么?我的意思是它的用途是什么,或者有什么实际的启发。 – soufrk 2016-07-01 09:35:43

回答

2
public abstract class Parent implements Clonable{ 

    private Object peer; 

    // Example 1 
    public Parent() { 
    try { 
     peer = this.clone(); 
    } catch (CloneNotSupportedException e) { 
     e.printStackTrace(); 
    } 
    } 

    // Example 2 
    public Parent(String name) { 
    try { 
     peer = this.getClass().getConstructor(String.class).newInstance(name); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    } 
    } 

    public <T extends Parent> T getPeer() { 
    return (T)peer; 
    } 
} 

public class Child01 extends Parent { } 

public class Child02 extends Parent { } 

看来代码可能更简单。

-3
public abstract class Parent { 

    private Parent peer; 

    public Parent(Parent peer) { 
     this.peer = peer; 
    } 

    public Parent(String someString) { 
    } 

} 

public class Child1 extends parent { 
    public Child1() { 
     super(new Child1()) 
    } 
} 

public class Child2 extends parent { 
    public Child2() { 
     super(new Child2()) 
    } 
} 

这是我能想到的最简单的方法。使用一些Java反射API的,但(这样问“这个”基准是什么类,构建一个新的类,型的你也许可以做到这一点在父类中,可能不依赖于Java的构造虽然是如何工作的工作。在C++中,在构造函数中的this指针是同一类型的构造类)

+0

是的。这正是我希望避免的,但我可能不得不这样做。干杯 – Joel 2009-05-21 08:06:14

+9

不是Child1()和Child2()构造函数调用自己的无限? – banjollity 2009-05-21 08:08:45

0

事情是这样的:

public class Peer { 
    public static abstract class Parent { 
      private Parent peer; 

      protected Parent(boolean needPeer) { 
        if (needPeer) { 
          try { 
            peer = getClass().newInstance(); 
          } 
          catch (Throwable e) { 
            System.err.println(e); 
          } 
        } 
      } 

      public String getPeerClass() { 
        return peer.getClass().toString(); 
      } 
    } 

    public static class Child1 extends Parent { 
      public Child1() { 
        this(false); 
      } 
      public Child1(boolean needPeer) { 
        super(needPeer); 
      } 
    } 

    public static class Child2 extends Parent { 
      public Child2() { 
        this(false); 
      } 
      public Child2(boolean needPeer) { 
        super(needPeer); 
      } 
    } 

    public static void main(String[] args) { 
      Parent p1 = new Child1(true); 
      Parent p2 = new Child2(true); 

      System.out.println(p1.getPeerClass()); 
      System.out.println(p2.getPeerClass()); 
    } 
} 

这一个工程用默认的构造函数,还有涉及若再有点挂羊头卖狗肉你想用一个非默认的构造函数构造一个新的对等体。请参阅Class的javadoc。

编辑:固定的无限递归:)

8

我不知道是否有可能做到这一点,而不会在周期。我相信,使用工厂方法而不是构造函数来编写它会更清晰。

0

注意,如果没有在父类的访问,你不能得到同行的对象(你不能实例父),所以这样的设计才有意义的概念证明。

1

,我会说,我认为这可能是一个非常糟糕的设计启动。班级名称也很糟糕,但我会坚持下去。

然而,处理它的方法之一:

public abstract class Parent { 
    interface PeerFactory { 
     Parent create(Parent peer); 
    } 
    private final Parent peer; 

    protected Parent(Parent peer) { 
     super(); 
     this.peer = peer; 
    } 
    protected Parent(PeerFactory peerFactory) { 
     super(); 
     this.peer = peerFactory.create(this); 
    } 
} 

public class Child1 extends parent { 
    private static final PeerFactory peerFactory = new PeerFactory { 
     public Parent create(Parent peer) { 
      return new Child1(peer); 
     } 
    }; 
    public Child1() { 
     super(peerFactory); 
    } 
    private Child1(Peer peer) { 
     super(peer); 
    } 
} 
0

我建议用工厂模式,在这里你有什么获取增加了一个对完全控制代替这整个事情,你不必在构造函数中执行。

-1
public abstract class Parent implements Clonable { 
    private Object peer; 

    // Example 1 
    public Parent() { 
    try { 
     peer = this.clone(); 
    } catch (CloneNotSupportedException e) { 
     e.printStackTrace(); 
    } 
    } 

    // Example 2 
    public Parent(String name) { 
    try { 
     peer = this.getClass().getConstructor(String.class).newInstance(name); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    } 

} 

public <T extends Parent> T getPeer() { 
return (T)peer; 
} 

public class Child01 extends Parent { } 

public class Child02 extends Parent { } 
0

答复为Leonid Kuskov

你举的例子2的答案总是会抛出一个StackOverflowException。我摆弄了一下代码,下面是正确的实现。尽管感谢你给我指出了这个方向。

public class AbstractClassDemo { 

    public static void main(String[] args) { 
     Child1 c1 = new Child1(); 
     System.out.println(c1.getPeer().getClass().getName()); 
    } 

} 

abstract class Parent { 
    private Object peer; 

    public Parent() { 

    } 

    public Parent(String s) { 
     try { 
      setPeer(this.getClass().getConstructor(String.class) 
        .newInstance("")); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    public Object getPeer() { 
     return peer; 
    } 

    public void setPeer(Object peer) { 
     this.peer = peer; 
    } 
} 

class Child1 extends Parent implements Cloneable { 
    public Child1() { 
     super("Child1"); 
    } 

    public Child1(String child1) { 
    } 
} 

class Child2 extends Parent implements Cloneable { 
    public Child2() { 
     super("Child2"); 
    } 

    public Child2(String child2) { 
    } 
}