2013-10-08 3 views
2

Предварительная информация.Как создать метод с возвращаемым типом как любой подтип суперкласса

public abstract class Person {} 
public class A extends Person{} 
public class B extends Person{} 
public class C extends Person{} 

public X getPersonByType(String type){ 
    //This Method will return either A or B or C based on type 
    //what should X be ?  
} 

Мне нужно создать метод, который принимает в String и возвращает объект, который является подтипом Person.

Дополнительная информация. Каждый из классов A B C имеет атрибуты открытых списков. Они не могут быть перенесены в класс Person, поскольку для этого требуется их уникальное имя (JPA для многих таблиц).

Теперь, если возможно, мне бы не хотелось, чтобы он возвращал person, так как я не смог бы получить доступ к атрибуту ролей (человек не знает об этом). Я также предпочел бы решение (если это возможно), которое не требует, чтобы я использовал или использовал instanceOf (если возможно).

P.S попытался <? extends Person>, но Eclipse, дал мне ошибку "тип возвращаемого метода недостающую"

+9

Задать ему вопрос 'Person'. –

+0

см. [Generics] (http://docs.oracle.com/javase/tutorial/extra/generics/index.html) и [подстановочные знаки] (http://docs.oracle.com/javase/tutorial/extra/generics /wildcards.html) – Justin

+1

@gangqinlaohu: Нет никаких признаков того, что дженерики здесь уместны. –

ответ

1

Вы должны вернуть Person X. Как Person является абстрактным типом это не может быть экземпляр. Вы можете иметь Person X как reference, который должен указывать на объект любой конкретной реализации Person, которые являются AB & C в вашем случае. Это красота run time polymorphism. Основываясь на вашем входе во время выполнения, он создаст object любого из классов A, B или C и воспользуемся ссылкой X, чтобы указать на этот объект. Я предлагаю вам пройти через Factory Design Pattern, что даст вам больше информации о том, как этот тип проектных работ в реальном жизненном сценарии.

+0

Хорошее предложение. Я уже думал об использовании Generics, но это приятное простое решение. Thx, это сработало. – SpartanElite

1

X должен быть Person.

с Person является абстрактным классом и не может быть создан, он всегда будет возвращать один из ваших подтипов.

Если вам нужно знать, что getPersonByType вернулся из метода вызова, вы можете использовать оператор instanceof

3

public Person getPersonByType(String type) должен работать нормально, потому что все ваши возвращаемые типы продлить Person.

Вы можете также добавить дополнительный параметр класса, если вы хотите, чтобы избежать instanceof проверки после вызова этого метода:

public <T extends Person> T getPersonByType(String type, Class<T> type) { 
    ... 
    // cast result to T 
} 

Используя этот способ, которым Вы смогли бы присвоить тип возвращаемого к подклассу непосредственно:

C c = getPersonByType("c", C.class); 

Помните, что это может привести к ошибке ClassCastExceptions, если вы передадите параметр String и Class, которые не соответствуют друг другу.

+0

Правильное объявление: 'public T getPersonByType (тип String, класс type) {...}' – JMess

+0

@JMess, спасибо, обновил мой ответ – micha

1
public Person getPersonByType(String type){ 
// analyze type and return appropriate instance... 
    if ("A instance".equals(type)) { 
     return new A(); 
    } 
... 

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