2016-03-11 3 views
0

Я хочу предоставить всем классам реализации метод по умолчанию, который инициализирует родительские поля со значениями по умолчанию. Так что я не должен переопределить эти инициализации в пределах каждого класса Impl:Как вернуть объект из родительского класса с типом класса 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. Возможно ли, чтобы этот способ был неявным объектом объекта Child? Итак, метод defaultParent всегда возвращает тип класса реализации?

Возможно, с java 8, функциональными интерфейсами или подобным?

+0

но ... почему вы не используете конструктор? –

+0

Поскольку конструктор всегда будет инициализировать поля. Обычно я не хочу, чтобы они были инициализированы, только в некоторых случаях, когда я вызываю 'defaultParent()'. – membersound

+0

Но таким образом вы инициализируете отдельный объект. Если вы хотите инициализировать поля родителя в иерархии классов, вы должны использовать стандартный путь построения. –

ответ

2

Вот один из способов сделать это с 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 { 

} 

Вы можете вызвать статический метод, как это:

Child c = Parent.defaultParent(Child::new); 

Или вы можете просто использовать перегрузку конструктора вместо статического завода метод:

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); 
    } 
} 
+0

Именно то, что я искал. Большой! – membersound

1

Для чего предназначены конструкторы.

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); } 
} 

Все остальное это просто фантазии метод инициализации, который уступает конструкторами, потому что вы не можете, например, больше не присваивать значения 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"; 
    } 
} 
+0

Хм, хотя мне нравится идея метода init в родительском. Таким образом, я мог бы называть 'new Child() initDefault()' at will, все инициализированные поля по умолчанию. Без java 8 функций. – membersound

Смежные вопросы