2012-05-31 2 views
3

Из простого любопытства можно ли присвоить переменную двум типам?Можно ли присвоить переменную двум типам?

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

Animal a = new Dog(); 

Если динамический тип должен наследовать статический тип:

public class Dog extends Animal {...} 

Но можно гарантировать, что динамический тип расширяет/реализует несколько типов ?

Для того, чтобы Dog должен расширить класс Animal и реализовать интерфейс?

Я бы себе представить, что-то вроде:

Animal [implements Happy] a = new Dog(); 

Я совершенно уверен, что это просто сумасшедший разговор, но возможно ли это? А если нет, какая ближайшая альтернатива?

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

Один из способов я могу думать о том, что во время выполнения определения литьем его каждый раз, когда вы используете его:

try { 
    @SuppressWarnings("unused") 
    Animal a = (Happy) new Dog(); 
} catch (ClassCastException e) { 
    //Is not of type Happy 
} 

//Using a method from the Happy-interface 
try { 
    ((Happy)a).smile(); 
} catch (ClassCastException e) { 
    //Is not of type Happy 
} 
+3

На самом деле вам не нужно полагаться на литье, возможно, было бы проще и чище использовать 'instanceof Happy' после определения a. –

ответ

5

Нет, это не представляется возможным непосредственно. Вы можете придумать некоторые обходные пути, например:

abstract class HappyAnimal extends Animal implements Happy 

И затем используйте этот тип. Конечно, ваши классы должны продлевать HappyAnimal, они не будут работать, если они продлят Animal и реализуют Happy напрямую.

+0

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

3

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

<A extends Animal & Happy> //put in class/method declaration 

... 

A a = new Dog(); 

Это позволит вам сделать проверку типа во время компиляции, без использования любые дополнительные классы abstract.

+0

Также хороший ответ. +1 - Хотя я даю принятый ответ Томашу за то, что вы быстро. Разве кто-то из вас, ребята, хочет сделать общий ответ? –

+0

Хм, теперь, когда я думаю об этом, разве это не 'AA extends Animal, Happy>'? –

+0

@AskeBisgaard - Нет, это правильный синтаксис для нескольких границ. Попробуйте. –

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