Гость
Форумы / Java [игнор отключен] [закрыт для гостей] / Наследование / 18 сообщений из 18, страница 1 из 1
29.12.2019, 18:41
    #39909629
Stupid_BOT
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наследование
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
package local.temp;

public class Main
{
  public static void main(String[] args) {
    System.out.println(new Derived().getZ());
  }
}

class Derived extends Base
{
  private String z = "Derived Z";
}

abstract class Base
{
  private String z;

  public String getZ() {
    return z; //Breakpoint here
  }
}


$ java --version
java 11.0.5 2019-10-15 LTS
Java(TM) SE Runtime Environment 18.9 (build 11.0.5+10-LTS)
Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.5+10-LTS, mixed mode)

Если поставить точку останова в методе local.temp.Base::getZ, то дебаггер показывает значение z="Derived Z".
Ожидаю в консоли "Derived Z", но выводится "null".

Объясните, пожалуйста, почему так получается. Или ткните в раздел документаци.
...
Рейтинг: 0 / 0
29.12.2019, 19:52
    #39909643
Сергей Лалов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наследование
Stupid_BOT,

Потому что это так не работает. Где у вас ссылка на родительский класс и реализация метода абстрактного класса в классе Derivied?
...
Рейтинг: 0 / 0
29.12.2019, 20:05
    #39909647
Stupid_BOT
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наследование
Сергей Лалов,
спасибо за ответ.

Не понял, о какой ссылке "на родительский класс" ты говоришь.
Метод getZ не абстрактный, реализация есть в базовом классе. Переопределять его в дочернем классе мне не надо.

P.S.: если у класса Base убрать модификатор abstract, то результат не изменится.
...
Рейтинг: 0 / 0
29.12.2019, 20:10
    #39909648
Сергей Лалов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наследование
Stupid_BOT


P.S.: если у класса Base убрать модификатор abstract, то результат не изменится.


И не будет.

Вот по первой части твоего вопроса:
https://younglinux.info/java/interface

Поправил ссылку.
...
Рейтинг: 0 / 0
29.12.2019, 20:43
    #39909654
Stupid_BOT
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наследование
Сергей Лалов,
спасибо за бесполезную ссылку.
Убрал из кода модификатор abstract, чтобы он тебя не будоражил.
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
package local.temp;

public class Main
{
  public static void main(String[] args) {
    System.out.println(new Derived().getZ());
  }
}

class Derived extends Base
{
  private String z = "Derived Z";
}

class Base
{
  private String z;

  public String getZ() {
    return z; // Брэкпоинт в этом месте показывает z="Derived Z"
  }
}



Я ожидаю, что вызов new Derived().getZ() вернёт значение поля z из дочернего класса, а он возвращает значение из родительского класса. Почему так происходит, мне не понятно.
...
Рейтинг: 0 / 0
29.12.2019, 21:05
    #39909658
Сергей Лалов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наследование
Stupid_BOT,

)) Плохо читал ссылку.
...
Рейтинг: 0 / 0
29.12.2019, 22:07
    #39909673
Stupid_BOT
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наследование
Сергей Лалов,
я внимательно читал.
Там есть описание того, что такое абстракный класс и интерфейс, для чего оно может пригодиться, как наследовать аббстрактные классы и что такое реализация интерфейса.
Там нет описания того, при каких условиях метод вызванный в контексте объекта дочернего класса возврашает значение поля из родительского класса, а не из дочернего.
...
Рейтинг: 0 / 0
30.12.2019, 01:55
    #39909696
iOracleDev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наследование
Stupid_BOT
Я ожидаю, что вызов new Derived().getZ() вернёт значение поля z из дочернего класса, а он возвращает значение из родительского класса. Почему так происходит, мне не понятно.

Потому что это метод родительского класса, родительский класс ничего не знает и не должен знать о переменных дочернего.
...
Рейтинг: 0 / 0
30.12.2019, 03:19
    #39909701
Stupid_BOT
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наследование
iOracleDev,
но метод же вызывается в контексте экземпляра дочернего класса.
...
Рейтинг: 0 / 0
30.12.2019, 07:20
    #39909710
Basil A. Sidorov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наследование
Stupid_BOT
но метод же вызывается в контексте экземпляра дочернего класса.
Если слегка утрировать, то у методов нет контекстов, а есть иерархия наследования.
Далее.
Приватность это не просто так: ваши "String z" - одноимённые, но разные переменные.
Если "по иерархии наследования" дёргается метод родительского класса, то и работать он будет с приватной переменной родительского класса.
Поскольку Java запрещает сокрытие переменных, то, окажись ваши переменные "видимы одновременно", вы бы просто не смогли определить две одноимённые переменные.
...
Рейтинг: 0 / 0
30.12.2019, 08:16
    #39909712
Stupid_BOT
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наследование
Basil A. Sidorov,
спасибо за объяснение, но понятнее не стало.

> Если "по иерархии наследования" дёргается метод родительского класса, то и работать он будет с приватной переменной родительского класса.
Я ставлю брэкпоинт в методе getZ() и в дебаггере наблюдаю z="Derived Z", т.е. значение из дочернего класса. Вот этот момент ставит меня в тупик. Если бы метод работал с полем родительского класса, то в дебаггере было бы z=null.

> [skipped] окажись ваши переменные "видимы одновременно", вы бы просто не смогли определить две одноимённые переменные.
Да запросто. Изменил определения полей на public String z , - код скомпилировался и выполнился.
...
Рейтинг: 0 / 0
30.12.2019, 08:25
    #39909714
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наследование
Stupid_BOT,
А кауой смысл иметь две переменные с одним именем?
...
Рейтинг: 0 / 0
30.12.2019, 08:33
    #39909716
Stupid_BOT
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наследование
PetroNotC Sharp,
а какой смысл в полиморфизме?
Базовый класс содержит реализацию и значения полей по-умолчанию. В наследниках переопределяются значения полей.
...
Рейтинг: 0 / 0
30.12.2019, 08:38
    #39909717
Basil A. Sidorov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наследование
Stupid_BOT
Я ставлю брэкпоинт в методе getZ() и в дебаггере наблюдаю z="Derived Z", т.е. значение из дочернего класса. Вот этот момент ставит меня в тупик. Если бы метод работал с полем родительского класса, то в дебаггере было бы z=null.
У вас есть self.z и super.z. Метод (как и должно) работает с super.z, отладчик отображает self.z.
Бага это или "так и должно быть" - вопрос отдельный.Да запросто. Изменил определения полей на public String z , - код скомпилировался и выполнился.Тогда я неправ - в паре "предок - потомок" каждая переменная может быть квалицирована при помощи self или super.
...
Рейтинг: 0 / 0
30.12.2019, 08:41
    #39909719
Basil A. Sidorov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наследование
Stupid_BOT
Базовый класс содержит реализацию и значения полей по-умолчанию. В наследниках переопределяются значения полей.
А вот это - грубое заблуждение: поля данных поля потомка не могут изменять поля данных предка.
Потомок получает "наследие" предка "как есть" и не может "там" ничего модифицировать.
...
Рейтинг: 0 / 0
30.12.2019, 08:53
    #39909720
Stupid_BOT
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наследование
Basil A. Sidorov,

> вот это - грубое заблуждение: поля данных поля потомка не могут изменять поля данных предка.
Да я и не преследовал цели изменять поля данных предка.
Заблуждением была уверенность, что метод, определённый в предке и вызванный у экземпляра потомка будет работать с полями класса-потомка. Облом.

Спасибо за содержательную беседу.
...
Рейтинг: 0 / 0
30.12.2019, 09:00
    #39909722
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наследование
Stupid_BOT
PetroNotC Sharp,
а какой смысл в полиморфизме?

В методах а не полях Карл!
...
Рейтинг: 0 / 0
30.12.2019, 16:47
    #39909964
iOracleDev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наследование
Stupid_BOT
а какой смысл в полиморфизме?

Объектная переменная не хранит объект, она хранит ссылку на область памяти где лежат его данные, а также на класс к которому он относится, что позволяет применять соответствующие методы. Полиморфизм дает возможность присвоить переменной объявленной для суперкласса, ссылку на дочерний класс и даже вызвать методы дочернего класса для этой ссылочной переменной, если в переменную суперкласса записана ссылка на экземпляр объекта не имеющий вызываемого метода (метод существует но для других дочерних классов), будет ошибка, поэтому желательно перед использованием методов дочерних объектов делать обратное приведение типа к типу соответствующего дочернего объекта.
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Наследование / 18 сообщений из 18, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]