2016-05-22 1 views
0

Я долго размышлял об этом упражнении, и я не могу окунуться в суть вопроса. В разделе рассказывается о расширенных классах и порядке, в котором происходят события, когда объект построен из расширенного класса.Учебное пособие по программированию на языке Java 4-е издание 3.3

Когда объект создается, память выделяется для всех его полей, в том числе, унаследованные от суперкласса, и эти поля установлены по умолчанию начальные значения для соответствующих типов (ноль для всех числовых типов, ложных для boolean, '\ u0000' для char и null для ссылок на объекты). После этого конструкция имеет три фазы :

  1. Вызовите конструктор суперкласса.
  2. Инициализация полей с использованием их инициализаторов и любых блоков инициации.
  3. Выполнить тело конструктора.

...

Упражнение 3.3: Если бы это было важно установить эти маски, используя значения из расширенного класса во время строительства, как вы могли бы работать вокруг этих проблем?

Код:

class X { 
    protected int xMask = 0x00ff; 
    protected int fullMask; 

    public X() { 
     fullMask = xMask; 
    } 

    public int mask(int orig) { 
     return (orig & fullMask); 
    } 
} 

class Y extends X { 
    protected int yMask = 0xff00; 

    public Y() { 
     fullMask |= yMask; 
    } 
} 
+0

Что вы думаете? – duffymo

+0

Что подразумевается под упражнением? – London

+0

Понимание порядка выполнения действий при создании дочерних классов.Моим наивным ответом было бы «переместить yMask до суперкласса». – duffymo

ответ

2

Я думаю, что упражнение предназначено для иллюстрации того, что происходит, когда вы инстанцируете Y, т.е. Y y = new Y();. Я не думаю, что они объясняют все это хорошо, потому что в пункте 2 не описываются какие поля это означает (класс или суперкласс). Если поместить код в отладчик и останавливаться на различных заявлениях, вы найдете следующий порядок выполнения, когда выполняется вышеприведенное утверждение:

  1. конструктор Y в вызове, то есть, контроль исполнения переходит к началу Y-х конструктор
  2. Вызывается конструктор X
  3. Выполняются переменные инициализации X, поэтому xMask получает 0x00ff.
  4. Выполнение конструктора X, поэтому fullMask получает значение xMask.
  5. Выполняются инициализационные переменные Y, поэтому yMask получает 0xff00;
  6. Выполняются инструкции конструктора Y, поэтому fullMask получает fullMask или yMask.

Таким образом, это будет ожидаемое поведение - независимо от того, что X делает с переменными и т. Д., До того, как Y получит какой-либо контроль; Y не должен «знать», как реализуется X, он просто должен использовать X, как он (надеюсь) документирован, чтобы вести себя.

Надеюсь, это поможет. Мне не нравится характеристика книги такого поведения как «проблемы»; Я не вижу здесь «проблемы». Чтобы написать Y, который расширяет X, вам нужно знать внешнюю видимую часть поведения X, которая влияет на вас. В этом случае X дает fullmask определенное значение, которое вы используете в своем Y-конструкторе.