sources
This commit is contained in:
parent
1d0a2964cf
commit
151d77ee54
11 changed files with 340 additions and 0 deletions
|
@ -105,6 +105,8 @@ unittest
|
|||
|
||||
Обратите внимание на небольшую хитрость. В приведенном коде использовано выражение `w.defaultName`, а не `Widget.defaultName`. Для обращения к статическому члену класса всегда можно вместо имени класса использовать имя экземпляра класса. Это возможно, потому что при обработке выражения слева от точки сначала выполняется разрешение имени и только потом идентификация объекта (если потребуется). Выражение w в любом случае вычисляется: будет оно использовано или нет.
|
||||
|
||||
[Исходный код](src/chapter-6-1/)
|
||||
|
||||
[В начало ⮍](#6-1-классы) [Наверх ⮍](#6-классы-объектно-ориентированный-стиль)
|
||||
|
||||
## 6.2. Имена объектов – это ссылки
|
||||
|
@ -214,6 +216,8 @@ if (‹условие›)
|
|||
|
||||
Сравним ссылочную семантику с семантикой значений а-ля `int`. У семантики значений есть свои преимущества, среди которых выделяется логический вывод: в выражениях всегда можно заменять равные значения друг на друга, при этом результат не изменяется. (А к ссылкам, использующим для изменения состояния объектов вызовы методов, такой подход неприменим.) Другое важное преимущество семантики значений – скорость. Но даже если вы воспользуетесь динамической щедростью полиморфизма, от ссылочной семантики никуда не деться. Некоторые языки пытались предоставить возможность использовать и ту, и другую семантику и заслужили прозвище «нечистых» (в противоположность чисто объектно-ориентированным языкам, использующим ссылочную семантику унифицированно для всех типов). D нечист и очень гордится этим. Во время разработки необходимо принять решение: если вы желаете работать с некоторым типом в рамках объектно-ориентированной парадигмы, следует выбрать тип `class`; иначе придется использовать тип `struct` и поступиться всеми удобствами ООП, присущими ссылочной семантике.
|
||||
|
||||
[Исходный код](src/chapter-6-2/)
|
||||
|
||||
[В начало ⮍](#6-2-имена-объектов-это-ссылки) [Наверх ⮍](#6-классы-объектно-ориентированный-стиль)
|
||||
|
||||
## 6.3. Жизненный цикл объекта
|
||||
|
@ -239,6 +243,8 @@ unittest
|
|||
|
||||
При вычислении выражения `new Test` конструируется объект типа `Test` с состоянием по умолчанию, то есть экземпляр класса `Test`, каждое из полей которого инициализировано своим значением по умолчанию. Любой тип `T` обладает статически известным значением по умолчанию, обратиться к которому можно через свойство `T.init` (значения свойств `.init` для базовых типов приведены в табл. 2.1). Если вы хотите инициализировать некоторые поля значениями, отличными от соответствующих значений свойства `.init`, укажите при определении этих полей статически известные инициализирующие значения, как показано в предыдущем примере для поля `a`. Выполнение теста модуля при этом не порождает исключений, так как это поле явно инициализируется константой `0.4`, а поле `b` не трогали, а значит, оно неявно инициализируется значением выражения `double.init`, то есть NaN («нечисло»).
|
||||
|
||||
[Исходный код](src/chapter-6-3/)
|
||||
|
||||
[В начало ⮍](#6-3-жизненный-цикл-объекта) [Наверх ⮍](#6-классы-объектно-ориентированный-стиль)
|
||||
|
||||
### 6.3.1. Конструкторы
|
||||
|
@ -303,6 +309,8 @@ class NoGo
|
|||
|
||||
Обычные правила перегрузки функций (раздел 5.5) применимы и к конструкторам: класс может определять любое количество конструкторов, но каждый из них должен обладать уникальной сигнатурой (отличающейся числом или типом параметров, хотя бы на один параметр).
|
||||
|
||||
[Исходный код](src/chapter-6-3-1/)
|
||||
|
||||
[В начало ⮍](#6-3-1-конструкторы) [Наверх ⮍](#6-классы-объектно-ориентированный-стиль)
|
||||
|
||||
### 6.3.2. Делегирование конструкторов
|
||||
|
@ -722,6 +730,8 @@ unittest
|
|||
|
||||
Если бы занявший место экземпляра класса `Contact` экземпляр класса `Friend` вел себя *в точности* так же, как и экземпляр ожидаемого класса, отпали бы все (или почти все) причины использовать класс `Friend`. Одно из основных средств, предоставляемых объектной технологией, – возможность классам-наследникам переопределять функции классов-предков и таким образом модульно настраивать поведение сущностей среды. Как можно догадаться, переопределение задается с помощью ключевого слова `override` (класс `Friend` переопределяет метод `bgColor`), которое обозначает, что вызов `c.bgColor()` (где вместо c ожидается объект типа `Contact`, но на самом деле используется объект типа `Friend`) всегда инициирует вызов версии метода, предлагаемой классом `Friend`. Друзья всегда остаются друзьями, даже если компилятор думает, что это обыкновенные контакты.
|
||||
|
||||
[Исходный код](src/chapter-6-4/)
|
||||
|
||||
[В начало ⮍](#6-4-методы-и-наследование) [Наверх ⮍](#6-классы-объектно-ориентированный-стиль)
|
||||
|
||||
### 6.4.1. Терминологический «шведский стол»
|
||||
|
@ -902,6 +912,8 @@ void workWith(TextWidget tw)
|
|||
|
||||
Чтобы максимизировать количество доступной статической информации о типах, D вводит средство, известное как *ковариантные возвращаемые типы*. Звучит довольно громко, но смысл ковариантности возвращаемых типов довольно прост: если родительский класс возвращает некоторый тип `C`, то переопределенной функции разрешается возвращать не только `C`, но и любого потомка `C`. Благодаря этому средству можно позволить методу `TextWidget.duplicate` возвращать `TextWidget`. Не менее важно, что теперь вы можете прибавить себе веса в дискуссии, вставив при случае фразу «ковариантные возвращаемые типы». (Шутка. Если серьезно, даже не пытайтесь.)
|
||||
|
||||
[Исходный код](src/chapter-6-4-5/)
|
||||
|
||||
[В начало ⮍](#6-4-5-ковариантные-возвращаемые-типы) [Наверх ⮍](#6-классы-объектно-ориентированный-стиль)
|
||||
|
||||
## 6.5. Инкапсуляция на уровне классов с помощью статических членов
|
||||
|
@ -1140,6 +1152,8 @@ unittest
|
|||
|
||||
Обратите внимание: вместе с именем класса возвращено и имя модуля, в котором класс был определен. По умолчанию модуль получает имя файла, в котором он расположен, но это умолчание можно изменить с помощью объявления с ключевым словом `module` (см. раздел 11.8).
|
||||
|
||||
[Исходный код](src/chapter-6-8-1/)
|
||||
|
||||
[В начало ⮍](#6-8-1-string-tostring) [Наверх ⮍](#6-классы-объектно-ориентированный-стиль)
|
||||
|
||||
### 6.8.2. size_t toHash()
|
||||
|
@ -1882,6 +1896,8 @@ class Outer
|
|||
}
|
||||
```
|
||||
|
||||
[Исходный код](src/chapter-6-11/)
|
||||
|
||||
[В начало ⮍](#6-11-вложенные-классы) [Наверх ⮍](#6-классы-объектно-ориентированный-стиль)
|
||||
|
||||
### 6.11.1. Вложенные классы в функциях
|
||||
|
@ -2244,6 +2260,8 @@ class StorableShape : Shape
|
|||
}
|
||||
```
|
||||
|
||||
[Исходный код](src/chapter-6-13-1/)
|
||||
|
||||
[В начало ⮍](#6-13-1-переопределение-методов-в-сценариях-множественного-порождения-подтипов) [Наверх ⮍](#6-классы-объектно-ориентированный-стиль)
|
||||
|
||||
## 6.14. Параметризированные классы и интерфейсы
|
||||
|
@ -2325,6 +2343,8 @@ unittest
|
|||
|
||||
Как только вы создадите экземпляр параметризированного класса, он превратится в обычный класс, так что `StackImpl!int` – это такой же класс, как и любой другой. Именно этот конкретный класс реализует `Stack!int`, поскольку в формочку для вырезания `StackImpl(T)` под видом `T` вставили `int` по всему телу этого класса.
|
||||
|
||||
[Исходный код](src/chapter-6-14/)
|
||||
|
||||
[В начало ⮍](#6-14-параметризированные-классы-и-интерфейсы) [Наверх ⮍](#6-классы-объектно-ориентированный-стиль)
|
||||
|
||||
### 6.14.1. И снова гетерогенная трансляция
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue