Это хорошо, чтобы вернуть абстрактный класс из интерфейса - PullRequest
2 голосов
/ 18 июля 2011

У меня есть интерфейс с именем ABC. У меня также есть абстрактный класс PQR, и есть 3 класса, которые расширяют этот абстрактный класс.

Например:

abstract class PQR {
    //...
}

interface ABC {
    //other methods....
    PQR returnRightClass();
}

class X extends PQR {
}

class Y extends PQR {
}

class Z extends PQR {
}

Теперь есть классы, которые реализуют интерфейс ABC. Итак, что я должен сделать, чтобы получить правильный класс от X, Y и Z?

Ответы [ 4 ]

2 голосов
/ 18 июля 2011

Вы можете вернуть абстрактный класс. Нет закона о возвращении интерфейсов или абстрактных классов, это зависит от вашего программного обеспечения:

Один из способов вернуть x, y, z - использовать Factory Pattern .

Пример (псевдокод):

public class PQRFactory {

    public PQR getPQR(condition) {

        switch (condition) {
            case condition_x :
                return new x();
            break;

            case condition_y :
                return new y();
            break;

            case condition_z :
                return new z();
            break;

            default : return null;
        }
    }
}

Если вы не хотите использовать condition, вы можете использовать шаблон Builder , чтобы делать то, что отправил @JVerstry.

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

Пример (псевдокод):

public abstract class AbstractABC implements ABC {

    protected PQRFactory factory;

    protected AbstractABC() {
        factory = new PQRFactory();
    }

    protected AbstractABC(PQRFactory factory) {
        this.factory = factory;
    }

}

public class ABCImpl1 extends AbstractABC() {

    //Override constructors needed to construct this class
}

Надеюсь, это поможет.

2 голосов
/ 18 июля 2011

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

Теперь есть классы, которые реализуют интерфейс ABC. И что я должен сделать, чтобы получить правильный класс от х, у, г?

Просто убедитесь, что каждая реализация returnRightClass() в каждом классе, реализующем ABC, возвращает правильный экземпляр PQR (x, y или z).

EDIT

Чтобы ответить на ваш вопрос:

public MyClassX implements ABC {

    public PQR returnRightClass() {
        return new x();
    }

}

Или

public MyClassY implements ABC {

    public PQR returnRightClass() {
        return new y();
    }

}

или

public MyClassZ implements ABC {

    public PQR returnRightClass() {
        return new z();
    }

}
1 голос
/ 18 июля 2011

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

1 голос
/ 18 июля 2011

Хорошо использовать abstract или interface для значения return.

вы можете использовать оператор instanceof для сопоставления типов.

как в некоторых случаях

PQR myObj = new z();

(myObj instanceof z) // returns true
(myObj instanceof x) // returns false
(myObj instanceof y) // returns false
...