Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何从父类返回Impl类类型的对象?_Java - Fatal编程技术网

Java 如何从父类返回Impl类类型的对象?

Java 如何从父类返回Impl类类型的对象?,java,Java,我想为所有实现类提供一个默认方法,用默认值初始化父字段。因此,我不必在每个Impl类中重新定义这些初始化: public abstract class Parent { private String name; public static Parent defaultParent() { Parent parent = new Parent(); //fill default field values parent.name =

我想为所有实现类提供一个默认方法,用默认值初始化父字段。因此,我不必在每个Impl类中重新定义这些初始化:

public abstract class Parent {
    private String name;

    public static Parent defaultParent() {
        Parent parent = new Parent();
        //fill default field values
        parent.name = "default name";
        return parent;
    }
}

public class Child extends Parent {

}
现在我可以调用
Child.defaultParent()
。但这将返回一个类型为
Parent
的对象。有没有可能通过这种方式使对象成为
子对象
隐式对象?所以
defaultParent
方法总是返回实现类的类型


可能使用java 8、功能接口或类似的工具?

这里有一种使用java 8的方法:

public abstract class Parent {
    private String name;

    public static <T extends Parent> T defaultParent(Supplier<T> constructor) {
        T parent = constructor.get();
        //fill default field values
        parent.name = "default name";
        return parent;
    }
}

public class Child extends Parent {

}
或者,您可以使用构造函数重载而不是静态工厂方法:

public abstract class Parent {
    private String name;

    public Parent(boolean useDefaults) {
        if (useDefaults) {
            //fill default field values
            this.name = "default name";
        }
    }
}

public class Child extends Parent {
    public Child(boolean useDefaults) {
        super(useDefaults);
    }

    public Child() {
        super(false);
    }
}

使用Java 8有一种方法:

public abstract class Parent {
    private String name;

    public static <T extends Parent> T defaultParent(Supplier<T> constructor) {
        T parent = constructor.get();
        //fill default field values
        parent.name = "default name";
        return parent;
    }
}

public class Child extends Parent {

}
或者,您可以使用构造函数重载而不是静态工厂方法:

public abstract class Parent {
    private String name;

    public Parent(boolean useDefaults) {
        if (useDefaults) {
            //fill default field values
            this.name = "default name";
        }
    }
}

public class Child extends Parent {
    public Child(boolean useDefaults) {
        super(useDefaults);
    }

    public Child() {
        super(false);
    }
}

这就是构造器的用途

abstract class Parent {
    private String name;
    protected Parent(String name) {
        this.name = name;
    }
    protected Parent() {
        this("default name");
    }
}
class DefaultChild extends Parent {
   public DefaultChild() { super(); }
}
class CustomChild extends Parent {
   public CustomChild(String value) { super(value); }
}
其他一切都只是一个花哨的init方法,它不如构造函数,因为例如,您不再可以为
final
字段赋值

abstract class Parent {
    private String name;
    protected void init() {
        this.name= "default name";
    }
    // or
    protected static void init(Parent parent) {
        parent.name = "default name";
    }
}

这就是构造器的用途

abstract class Parent {
    private String name;
    protected Parent(String name) {
        this.name = name;
    }
    protected Parent() {
        this("default name");
    }
}
class DefaultChild extends Parent {
   public DefaultChild() { super(); }
}
class CustomChild extends Parent {
   public CustomChild(String value) { super(value); }
}
其他一切都只是一个花哨的init方法,它不如构造函数,因为例如,您不再可以为
final
字段赋值

abstract class Parent {
    private String name;
    protected void init() {
        this.name= "default name";
    }
    // or
    protected static void init(Parent parent) {
        parent.name = "default name";
    }
}

但是…为什么不使用构造函数呢?因为构造函数总是初始化字段。我通常不希望对它们进行初始化,只是在某些情况下,我调用
defaultParent()
。但这样,您就初始化了单独的对象。如果要初始化类层次结构中父级的字段,必须使用标准构造路径。为什么不重载构造函数?@endriu_l初始化单独的对象可以,但它应该是
Child
类型。但是…为什么不使用构造函数?因为构造函数总是会初始化字段。我通常不希望对它们进行初始化,只是在某些情况下,我调用
defaultParent()
。但这样,您就初始化了单独的对象。如果要初始化类层次结构中父级的字段,必须使用标准构造路径。为什么不重载构造函数?@endriu_l初始化一个单独的对象可以,但它应该是
Child
类型。这正是我想要的。伟大的正是我想要的。伟大的嗯,虽然我喜欢在父级中使用
init
方法。这样我就可以随意调用
newchild().initDefault()
,初始化所有默认字段。没有Java8 functions.Hm,但我喜欢在父级中使用
init
方法。这样我就可以随意调用
newchild().initDefault()
,初始化所有默认字段。没有Java8函数。