4. Класс

Два объекта, обладающих одинаковым набором свойств, называются однотипными объектами.

Значения свойств определяют состояние объекта. Если свойство объекта не определено, то данное свойство просто отсутствует в данном объекте. То есть само определение значения свойства несёт в себе информацию.

Рассмотрим объекты 3.1 и 3.2.

{
    [id]=>1;
    [имя]=>”Объект1”;
    [параметр1]=>234.5;
}                                  (3.1)

{
    [id]=>2;
    [параметр2]=>678.3;
}                                  (3.2)

Это - два однотипных объекта, имеющих разное состояние.

Наиболее ярко это иллюстрирует следующая деталь. Обратите внимание, что имя объекта является его свойством. Объект может быть именован, а может не иметь имени, но это не делает его объектом другого типа. Отсутствие имени не позволяет ссылаться на него, и в этом – формализация данной возможности.

Но что, если у рассматриваемых объектов не будет определено свойство id? Как определить, являются эти объекты однотипными, или нет?

Для этого мы должны выполнить следующие действия:

• ввести специальный объект, формализующий тип объекта,

• явно определить тип данного объекта.

Объекты, формализующие типы объектов, называются классами. Лучшего места для определения типа данного объекта, чем сам объект, найти сложно. Таким образом, мы определяем, что объект, чей тип явно определён – это типизованный объект.

Объект до типизации

{
    [id]=>1;
    [имя]=>”Объект1”;
    [параметр1]=>234.5;
}

Типизованный объект

{
    [id]=>1;
    [тип]=>Класс1;
    [имя]=>”Объект1”;
    [параметр1]=>234.5;
}

Обратите внимание на следующий нюанс. Каждый объект имеет тип, даже если этот тип не формализован в виде класса и сам объект нетипизован. В этом суть концепции, делающая массив и структуру объектами. Всё, с чем мы имеем дело, суть объекты, в том числе - значения и имена свойств. Просто здесь мы условились называть объектами группы именованных значений.

ПРИМЕЧАНИЕ

Класс, как объект, тоже может быть типизован. Такая типизация в языке Smalltalk называется мета-классом. В языке С++ нет мета-классов, но есть статические члены (переменные и функции) классов, которые в WYCIWYC формализуются в классе класса.

Не знаю, позволяет ли Smalltalk создавать мета-мета-классы. WYCIWYC позволяет.

Объект может быть типизован разными типами, то есть быть одновременно объектом разных классов.

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

ПРИМЕЧАНИЕ

В этом одно из ограничений языка C++. В нём полиморфизм основан на наследовании классов. Поэтому невозможно создать объект, который был бы наследован от одного и того же класса несколько раз и при этом сам был бы наследником того же класса. Например:

class Array2: public Array, public Array {... };

Чтобы реализовать нечто подобное, Страуструп предлагает обходной метод: разделять классы на классы-интерфейсы и классы-реализации этих интерфейсов:

class Array2: public IArray {
    Array array1;
    Array array2; ... }

К сожалению, это помогает не всегда. К примеру, когда функциональность общего вида (например, сериализуемость класса) помещаешь в шаблоны классов. При этом неизбежно наталкиваешься на то, что один из классов уже является многократным потомком от данного шаблона, и эту неоднозначность не представляется возможным разрешить ни внутри шаблона, ни внутри класса, в котором она возникла.

Но проблема не в том, что эту задачу невозможно решить средствами C++, проблема в том, что решение получается громоздким, требующим наличия специальных деклараций в классах-потомках.

С другой стороны, это можно было бы решить вполне изящно, если бы была возможность создавать шаблоны шаблонов классов. WYCIWYC предоставляет и такую возможность.

Класс как объект выглядит примерно так:

Объект

{
    [id]=>1;
    [тип]=>Класс1;
    [имя]=>”Объект1”;
    [параметр1]=234.5;
}

Класс

{
    [тип]=>Класс;
    [имя]=>”Класс1”;
    [свойства]=> {
            [1]=>Свойство id;
            [2]=>Свойство параметр1;
            [3]=>Свойство тип;
            [4]=>Свойство имя;
    }
}

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

Автор: Андрей Шаройко <vanyamboe@gmail.com>