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的实例时,我想要一个自动构造的“peer”,它也是Child1类型,并存储在peer属性中。同样对于Child2,具有Child2类型的对等。
问题在于,在父类中分配对等属性。我无法通过调用new Child1()
来构造一个新的Child类,因为它对Child2不起作用。我怎样才能做到这一点?我可以使用哪个关键字来引用子类?像new self()
?
答案 0 :(得分:8)
我不确定是否可以在不进入循环的情况下执行此操作。我相信使用工厂方法而不是构造函数来编写它会更清楚。
答案 1 :(得分: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 { }
似乎代码可能更简单。
答案 2 :(得分: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);
}
}
答案 3 :(得分: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());
}
}
这个使用默认构造函数,如果你想用非默认构造函数构造一个新的对等体,那么会涉及更多的技巧。请参阅类的javadoc。
编辑:修复无限递归:)
答案 4 :(得分:0)
请注意,如果父类中没有访问器,则无法获取对等对象(您无法实例化Parent),因此此设计仅作为概念证明才有意义。
答案 5 :(得分:0)
我建议用Factory模式替换整个事件,在那里你可以完全控制添加对象的内容,而不必在构造函数中执行。
答案 6 :(得分:0)
您的示例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) {
}
}
答案 7 :(得分:-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 { }
答案 8 :(得分:-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在父类中执行此操作(因此请询问'this'引用它是什么类并构造该类型的新类。它可能无法工作,具体取决于java构造函数的工作方式。在C ++中,构造函数中的“this”指针与构造函数类的类型相同