2009-05-21 156 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) { 
    } 
}