2015-11-04 4 views
0

почему мы можем отливать из суперкласса вниз к подклассу, как так:Разница между классом downcasting vs downcasting Интерфейс в Java?

Object o = getStringObject(); 
String str = (String) o; 

, но затем использовать тот же принцип, чтобы бросить интерфейс вниз к югу от типа Э.Г.?

InterfaceType anInterface; 
anInterface = (InterfaceType) SubClassVar; 

так что ПРИМЕР 1 все в порядке и денди. Что я не понимаю, так это то, что если интерфейс является супертипом класса, который его реализует, то как у нас нет исключения ClassCastException, когда мы понижаем класс до интерфейса, если внутри иерархии интерфейс выше? Я где-то читал, что есть разница между кастингом через классы и интерфейсы, но, конечно, им не хотелось объяснять, почему, поэтому я остался в открытом доступе. Спасибо, Stack!

+2

Я смущен. Вы говорите, что 'SubClassVar' является' InterfaceType'? Тогда для актера использовать нечего. –

+0

@SotiriosDelimanolis SubClassVar - это класс, который реализует InterfaceType – 3alto

+0

@SotiriosDelimanolis Возможно, мне нужна дополнительная информация, но если вы разрабатываете для android, это шаблон коммуникатора, используемый для разговора между активностью и фрагментом. – 3alto

ответ

2

Технически вы перешли на интерфейс, потому что он выше в иерархии, чем (предполагаемый?) Исполнитель этого интерфейса, SubClassVar. Кроме того, это просто не требуется, потому что реализация интерфейса может быть обсуждена в терминах этого интерфейса в любом случае без синтаксиса.

Вы можете сжать интерфейс так же, как и с подклассом. Вот пример:

interface I1 {} 
interface I2 extends I1 {} 

class I2Impl implements I2 {} 

class Main { 
    public static void main(String[] args) { 
     I1 test = new I2Impl(); 
     I2 test2 = (I2)test; 
     I2Impl test3 = (I2Impl) test2; 
    } 
} 
0

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

Бросок между двумя типами не допускается, если очевидно, что ни один объект не может принадлежать двум типам одновременно; или в другом слове, пересечение двух типов пусто. Например, мы не можем отличать между String и Integer; а также String и Runnable. Однако Number и Runnable могут быть переданы друг другу, потому что, возможно, в обоих типах может быть объект.

Кроме того, сопоставление идентичности a==b допускается только в том случае, если A и B могут быть переброшены друг к другу, для того же обоснования. == не разрешен, если компилятор знает, что они не могут быть одним и тем же объектом. см JLS

Точный алгоритм очень сложен - http://docs.oracle.com/javase/specs/jls/se8/html/jls-5.html#jls-5.5.1 Заметим, что алгоритм является симметричным - А может привести к типу B, если и только если B может быть приведен к А. Текст спецификации не очень хорошо и, вероятно, содержит ошибки (см. это question)

«Недостаток» - это когда тип цели является подтипом; «upcast» - это когда тип цели является супертипом. Ускорение обычно не нужно, однако есть cases, когда это необходимо.