Допустим, у меня определены следующие интерфейс и классы:
public interface I { void a(); }
public class A implements I {
public void a() { System.out.println("A"); }
}
public class B implements I {
public void a() { System.out.println("B"); }
public void b() { System.out.println("C"); }
}
И затем я запускаю следующий код:
public class Main {
public static void main(String[] args) {
A a = new A();
B b = new B();
I i;
i = a;
i.a(); // prints "A"
i = b;
i.a(); // prints "B"
i.b(); // 1st problem: i can't seem to find method b. Why?
b = i; // 2nd problem: b can't be assigned to i although i references an object of class B?
b = (B)i; // why does this work fine...
a = (A)i; // 3rd problem: ...but this here doesn't?
}
}
Итак, вот мои вопросы:
Первая проблема
Почему нельзя вызвать i.b()
?
i
указывает на тот же объект, что и b
, объект класса B
, который имеетметод b
.
Так почему i.a()
вызывает правильный метод (тот, который выводит "B"), но i.b()
не разрешает вообще?
Имеет ли факт, что i
был объявлен как тип I
(интерфейс), какое-либо отношение к этому?Означает ли это, что в присваивании X x = new Y()
, где Y extends X
, можно вызывать только те методы x
, которые уже объявлены в X
, а не только для Y
?
SecondПроблема
Почему нельзя b
присвоить i
, хотя i
ссылается на объект класса B
?b
и i
уже ссылаются на один и тот же объект, не так ли?Так почему же это вызывает ошибку, если я пытаюсь присвоить b
i
- конечный результат которого должен быть идентичен состоянию программы до этого назначения, если я что-то не пропустил
Третья проблема
Почему я могу привести i
к типу B
сейчас, хотя я не мог присвоить b
к i
ранее, и почему не кастуетi
до A
работа?
Я предполагаю, что мое заблуждение каким-то образом коренится в неясном различении между ссылочными переменными и объектами, на которые они ссылаются, а также различиях между типами этихпеременные и объекты.Я просто не могу объяснить эти случаи, в частности, первая проблема меня сильно смущает.