Java Inheritance переместить общий метод получения в родительский - PullRequest
0 голосов
/ 11 сентября 2018

У меня есть детские классы, которые используют композицию с классами, которые также являются детьми. Вместо того, чтобы иметь похожий метод получения в каждом дочернем классе, как я могу переместить метод получения класса композиции к родительскому.

public class child1 extends Parent {
   private CoolObjectTypeAAA coolObject;
   //coolObject getter
}

public class child2 extends Parent {
   private CoolObjectTypeBBB coolObject;
   //coolObject getter
}

public class CoolObjectTypeAAA extends CoolObject {
}

public class CoolObjectTypeBBB extends CoolObject {
}

public abstract class Parent {
    //would like to have a single CoolObject getter here in parent that returns the appropriate cool object of each child.
}

Возможно ли это, или мне просто нужно иметь одинаковый метод получения в каждом дочернем классе?

Ответы [ 2 ]

0 голосов
/ 11 сентября 2018

Как насчет этого:

abstract class Parent<T extends CoolObject> {
    protected T mCoolObject;
    public Parent(T coolObject) {
        mCoolObject = coolObject;
    }

    public T getCoolObject() {
        return mCoolObject;
    }
}

class Child1 extends Parent<CoolObjectTypeAAA> {
    public Child1(CoolObjectTypeAAA coolObject) {
        super(coolObject);
    }
    public void demoType() {
        // This type checks as the return type of getCoolObject() has been refined to CoolObjectTypeAAA
        CoolObjectTypeAAA co = this.getCoolObject();
    }
}

class Child2 extends Parent<CoolObjectTypeBBB> {
    public Child2(CoolObjectTypeBBB coolObject) {
        super(coolObject);
    }
    public void demoType() {
        // This type checks as the return type of getCoolObject() has been refined to CoolObjectTypeBBB
        CoolObjectTypeBBB co = this.getCoolObject();
    }
}

abstract class CoolObject { }

class CoolObjectTypeAAA extends CoolObject { }

class CoolObjectTypeBBB extends CoolObject { }

По сути, вы заставляете подкласс указывать какой-либо конкретный подтип CoolObject, который он использует, чтобы он мог уточнить тип возвращаемого значения получателя, но вы можете реализовать его в суперклассе.

0 голосов
/ 11 сентября 2018

Я бы посоветовал взглянуть на абстрактный шаблон фабрики , так как это, кажется, то, чего вы пытаетесь достичь. Правильно реализованный, он включает в себя несколько абстрактных классов и множество подклассов, но это не так страшно, как кажется.

То, что вы пытаетесь сделать, в основном выглядит как компактная версия этого, но, как правило, это не очень хороший подход, так как это приводит к трудностям в отслеживании ОО-кода спагетти, который перемещается назад и вперед между родителем и подклассом.

Помните, что вы уже определили Родителя как абстрактного по причине.

Я подозреваю, что ваша цель - максимизировать повторное использование кода, обычно, когда я вижу такой код, это потому, что есть некоторый распространенный код инициализации "CoolObject", который вы не хотите дублировать в дочерних классах.

В этом случае, как правило, лучше написать общий частный или защищенный инициализатор «CoolObject» в родительском объекте, но все же создать специальный тип CoolObject в дочерних классах, а затем инициализировать его с помощью метода родительского класса, прежде чем возвращать его из ребенок.

В этом случае, поскольку он является геттером, не может быть ничего, кроме возврата частного объекта. Если это так, то лучше всего определить общий метод получения как абстрактный в Parent, а затем переопределить в каждом дочернем элементе. Основная проблема заключается в том, что везде, где вы используете этот код, вам необходимо постоянно вводить тип конкретного CoolObject, который вы ожидаете.

Из-за этого, вероятно, что в будущем, даже если вы предоставите либо абстрактный получатель CoolObject, либо конкретный получатель CoolObject в Parent, вы все равно захотите иметь конкретные реализации получателей для определенных типов CoolObject.

При проектировании чего-то подобного следует помнить о том, как это будет использоваться.

Если цель состоит в том, чтобы предоставить абстракцию для различных типов CoolObject, то вы в основном используете шаблон стратегии. В этом случае возможность приведения переменных к подтипу CoolObject не требуется. В этом случае возможен гетеретический тип (абстрактный или конкретный).

Имея два конкретных дочерних класса Parent, однако, вы не чувствуете, что это то, к чему вы стремитесь. Опять же, я бы посоветовал взглянуть на абстрактный шаблон фабрики , так как это больше похоже на то, что вы пытаетесь сделать.

...