在java中实例化子类

时间:2014-04-27 18:47:41

标签: java abstract-class subclass

我有一个像这样的抽象类:

public abstract class MyAbstractClass {

    protected String greeting;

    public void run() {
        doSomething();
    }

    public abstract void doSomething();
}

...和一个像这样的子类:

public class MyClass extends MyAbstractClass {

    public MyClass() {
        this.greeting = "Hello, World!";
    }

    public void doSomething() {
        System.out.println(greeting);
    }

    public static void main(String[] args) {
        MyAbstractClass c = new MyClass();
        c.run();
    }
}

我将创建多个子类,所有子类都将具有仅实例化子类的相同main方法。有没有更简洁的方式来编写这个,所以我不需要在每个具有不同子类名称的子类中复制main方法?因此,如果我创建一个名为MyOtherClass的新子类,我不需要将主方法放入MyAbstractClass c = new MyOtherClass();

我想我可以反过来这样做,我从抽象类中运行main并在那里实例化子类,但是每次我想要更改哪个子类被实例化时我显然需要在new之后更改班级名称。我想我正在寻找的是一种在抽象类中定义main方法的方法,当我运行子类时,它实例化子类的副本而不是抽象类。如果这是有道理的......

2 个答案:

答案 0 :(得分:2)

这似乎非常适合factory method pattern。尝试这样的事情:

public abstract class MyAbstractClass {

    protected String greeting;

    public void run() {
        doSomething();
    }

    public abstract void doSomething();

    public abstract MyAbstractClass makeClass();

}

public class MyClass1 extends MyAbstractClass {

    public MyClass1() {
        this.greeting = "Hello, World!";
    }

    @Override
    public void doSomething() {
        System.out.println(greeting);
    }

    @Override
    public MyAbstractClass makeClass() {
        return new MyClass1();
    }

}

然后,只要您需要创建特定实例,只需在您认为最方便的地方的makeClass()方法的单个实现中调用main(),例如在MyAbstractClass中:

MyAbstractClass mac = new MyClass1();
MyAbstractClass obj = mac.makeClass();

最后一行将返回一个适当的实例,具体取决于用于实例化具体对象的类。

答案 1 :(得分:2)

这是动态类加载可能有用的地方。如果所有子类都同意使用no-arg构造函数,则可以简单地使用main方法和main方法,并传递该类以用作参数:

java com.foo.bar.Main com.foo.bar.MyFrouteenthSubclass

主要方法看起来像这样:

public static void main(String[] args) throws Exception {
    String className = args[0];
    MyAbstractClass object = (MyAbstractClass) Class.forName(className).newInstance();
    object.run();
}

您还可以为所有子类指定一个名称,并在Map<String, MyAbstractClass>中存储每个子类的实例,并简单地使用类的名称作为参数调用主类:

java com.foo.bar.Main fourteen