6 июл. 2015 г.

Классы. Практика на понимание создания объектов.

Теперь, на основе предыдущих знаний еще чуть расширим свое сознание о том как и в какой очередности происходит создание объектов в памяти и инициализация полей значениями. Рассмотрим простой пример:

CC001Вывод этой программы уже должен быть вам понятен:

CC002

Смысл этой программы показать, что оператор new создает объект в памяти сразу после своего вызова и инициализирует все поля значениями по умолчанию.

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

Как видно из вывода программы при создании объекта Sub, сперва были вызваны инициализационные блоки и инициализатор поля суперкласса. Затем был запущен конструктор суперкласса, но поскольку метод display() переопределен в подклассе Sub, то он нам вывел значение поля set объекта данного подкласса. Данный вывод подсвечен желтым в скрине. Далее происходит вывод значения поля set суперкласса. Затем отрабатывают инициализационные блоки подкласса и инициализация поля set подкласса. Далее отрабатывает конструктор подкласса в котором выводится значение поля set подкласса.

9 комментариев:

  1. >затем происходит инициализация полей значениями которые указаны при их определении

    т.е. String set = "MySuperString" при создании экземпляра Sub не участвует?

    ОтветитьУдалить
    Ответы
    1. Конечно участвует. Я чуток переделаю этот пример чтобы стало более понятно.

      Удалить
  2. class Test1{
    String a = "test1";

    Test1(){
    System.out.println(a);
    }

    }

    class Test2 extends Test1 {

    String a = "test2";

    Test2() {
    System.out.println(a);
    }
    }
    public class Main {

    public static void main(String[] args) {
    // write your code here
    new Test2();
    }
    }

    Вот такой код у меня выдал:
    test1
    test2

    Прочитав эту заметку, я ожидал null вместо test1. Где я ошибаюсь?

    ОтветитьУдалить
    Ответы
    1. У вас нет замещенного метода как у меня.

      Удалить
    2. Поясните, пожалуйста, откуда Sub set = null получается.

      Удалить
    3. Объяснение выделено желтым в тексте статьи.

      Удалить
    4. Спасибо, стало гораздо понятнее. Интересная ситуация получается. То есть если конструктор родительского класса вызывает метод, переопределенный в потомке, можно наступить на нефиговые грабли :) Как с такой ситуацией бороться? Сделать метод, вызываемый конструктором, методом класса?

      Удалить
    5. Интересно, вы читали предыдущую статью? http://pr0java.blogspot.ru/2015/07/blog-post_62.html

      Удалить
    6. Да, сорри, прочитал уже после того как оставил комментарий. Не сразу понял, что у вас в блоге последовательное изложение, а не набор standalone заметок :)

      Удалить