2013-02-23 2 views
6

Я пытаюсь реализовать и переопределить метод с разными типами возвращаемых данных, не будучи вынужденным использовать тип возвращаемого значения.Различные типы возвращаемых данных абстрактного метода в java без литья

public abstract class A { 
public abstract Object getValue(String content); 
} 

public class B extends A { 
public String getValue(String content) {...} 
} 

public class C extends A { 
public int getValue(String content) {...} 
} 


public class D extends A { 
public boolean getValue(String content) {...} 
} 

// Main loop: 
for (A a : allAs) 
{ 
// I want to use the method getValue() and corresponding to the type return a String, int or boolean without casting the return type 
} 

Мой вопрос: Можно ли возвращать различные типы без принуждения бросить? Как выглядит абстрактный метод для решения проблемы?

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

+0

Вы не можете переопределить по типам возврата. –

+0

И эта программа не будет компилироваться –

ответ

13

В вашем примере классы C и D не компилируются. Переопределенные методы в них нарушают Liskov substitution principle, так как их возвращаемый тип несовместим с их родительским классом. То, что вы хотите сделать, может быть выполнено с помощью дженериков, если вы готовы отказаться от использования примитивов в качестве возвращаемого типа.

abstract class A<T> { 
    public abstract T getValue(String content); 
} 

class B extends A<String> { 
    public String getValue(String content) { } 
} 

class C extends A<Integer> { 
    public Integer getValue(String content) { } 
} 

class D extends A<Boolean> { 
    public Boolean getValue(String content) { } 
} 
+0

Спасибо. Этот код может работать. Однако возвращаемый тип getValue() является «объектом», поэтому я должен его использовать. – erwingun2010

+0

@ erwingun2010 Если ваш метод возвращает тип 'Object', вы можете создать свой класс неправильно. Сделайте это: 'A bInstance = new B();' Если вы не добавите тип в объявление A, ваши абстрактные методы вернут 'Object'. – fiskeben

3

То, что вы описываете, не возможно вообще. Однако, если подкласс возвращает «более узкий» подтип возврата метода суперкласса, это называется «ковариантным типом возврата» и разрешен в Java с JDK 1.5. Однако, основываясь на вашем примере, я не думаю, что ковариантное возвращение - это то, что вы ищете.

Я предполагаю, что вы хотите

for (A a : allAs) 
{ 
    String b = a.getValue(); 
    int c = a.getValue(); 
} 

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

+0

Это именно то, что я хочу. Я все еще не понимаю, почему компилятор не может знать во время компиляции, тип возвращаемого значения верный. Когда я инициализирую allAs, я использую => allAs.add (новый B()); allAs.add (новый C()); – erwingun2010

+0

В примере, который я показал, оба оператора внутри цикла ссылаются на экземпляр _single_ 'A', который не может быть одновременно« B »и« C ». Как компилятор должен знать, что это такое, поскольку это не происходит до выполнения? –

0

В вашем примере, определение class B нормально, так как String подкласс Object. Остальные два не будут компилироваться, поскольку они являются примитивными типами. Вы можете заменить их Integer, а Boolean вернется, чтобы решить это.

Что касается вашего основного цикла, если вы повторяете их в качестве ссылок на A, вы сможете использовать только определение метода A, которое возвращает Object.

2

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

public abstract class A<T> { 
    public abstract T getValue(String content); 
} 

public class B extends A<String> { 
    public String getValue(String content) {...} 
} 

etc ... int не работает как тип возврата для этого, но Integer будет.

Я не печатаю на компилятор, так что может быть опечатки ...

Как отметил Джим и Крис, если вы цикл над As, вы можете получить только результат «А», который является Объект.

+0

Спасибо. Конечно, я должен использовать примитивы String, Boolean, Integer, .... – erwingun2010

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