Классы и объекты

Материал из Deeptown Manual
Перейти к: навигация, поиск

Содержание


Основой всей платформы Gide является объектно-ориентированный принцип. Для виртуальной машины Gide не существует понятия целого числа, строки или массива. Все, чем она оперирует - это объекты.

Язык K++ в полной мере использует тот же самый принцип. Для него нет отличия между типом int (целое число) и MyWeirdClass (какой-то класс, определенный пользователем): везде, где можно использовать int, можно использовать MyWeirdClass и наоборот. Например, ничто не мешает унаследовать свой класс от класса int, равно как ничто не мешает определить математические операторы для класса MyWeirdClass и использовать объекты этого класса в арифметических выражениях.

Понятие класса

Под классом понимается некоторая абстрактная сущность, задающая поведение объектов. Класс представляет собой набор следующих элементов:

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

Класс может иметь одного или нескольких родителей; об этом подробнее см. ниже.

Все поля, методы и свойства класса могут находиться в различных областях видимости:

  • private - видимость только внутри методов данного класса;
  • protected - видимость внутри методов данного класса и его дочерних классов;
  • public - видимость для всех.

Вот пример объявления класса:

<source lang="kpp"> class MyWeirdClass {

   var m_x = 0;  // поле m_x, изначально проинициализированное нулем
   const m_y = 1; // поле m_y, которое нельзя изменять
   // методы класса
   public const function int get_mul() { return m_x * m_y; }
   public function void set_mul(int x) { m_x = x / m_y; }
   // свойство класса
   public property mul read get_mul write set_mul;

} </source>

Понятие объекта

Под объектом подразумевается экземпляр того или иного класса, т.е. сущность, поведение которой задается соответствующим классом.

Для создания объекта того или иного класса служит оператор new: <source lang="kpp">

   var myWeirdObject = new MyWeirdClass;

</source>

Наследование

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

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

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

Вот пример кода:

<source lang="kpp"> class Box // коробка {

   // из чего сделана коробка?
   public const function string material() { return "Картон"; }
   // что в коробке?
   public const function string contents() { return "Пусто"; }

}

class BoxWithPotatoes extends Box // коробка с картошкой {

   public const function string contents() { return "Картошка"; }

}

function OutputBox(const Box b) {

   STDOUT.print("Материал: " + b.material() + ", содержит: " + b.contents() + "\n");

}

function main() {

   var b1 = new Box;
   var b2 = new BoxWithPotatoes;
   OutputBox(b1); // Материал: Картон, содержит: Пусто
   OutputBox(b2); // Материал: Картон, содержит: Картошка

} </source>

Замечание о множественном наследовании 
Существует одно ограничение при использовании множественного наследования: его нельзя применять для наследования от классов стандартной библиотеки. Это ограничение связано с архитектурой платформы Gide.

Методы

Метод - это некоторая функция, управляющая поведением объекта данного класса.

При объявлении метода могут быть указаны следующие ключевые слова, в указанном порядке:

private, protected или public 
определяет область видимости метода;
static 
метод является статическим, см. ниже;
const 
метод не изменяет объект;
function или constructor 
о конструкторах см. ниже;
const 
метод возвращает результат, который нельзя изменять;

После этого идет тип, возвращаемый методом. Если он опущен - возвращается динамическая переменная; если вместо типа указано ключевое слово void - метод не возвращает результата.

За типом идет имя метода, затем - перечисление аргументов в скобках. Подробнее об этом можно прочитать в разделе Функции.

Тело метода может быть объявлено как непосредственно в теле класса, так и вынесено за его пределы. Например:

<source lang="kpp"> class MyClass {

   public const function string F1() { return "smth"; }
   public const function string F2();

};

function string MyClass::F2() {

   return F1();

} </source>

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

В теле метода доступны все поля, методы и свойства данного класса и его предков. Например, в коде, приведенном выше, метод F2 вызывает метод F1 для того же объекта.

Статические методы

Статический метод класса - это метод, относящиеся к данному классу, но не объекту этого класса. Т.е. это некоторая вспомогательная для данного класса функция.

При объявлении статического метода нужно указать ключевое слово static.

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

Пример: <source lang="kpp"> class MyClass {

   public static function string Info() { return "Я MyClass!"; }

};

function f() {

   // Вызов статического метода:
   var myClassInfo = MyClass.Info();

} </source>

Конструкторы

Конструктор класса - это метод, инициализирующий объект класса.

С точки зрения языка, конструктор - это статический метод класса, возвращающий экземпляр данного класса.

Таким образом, следующие объявления в рамках класса MyClass эквивалентны: <source lang="kpp"> public constructor Create(); public static MyClass Create(); </source>

Тело конструктора чаще всего выглядит следующим образом: сначала создается экземпляр класса при помощи оператора new, затем производятся некоторые действия, инициализующие этот объект, и, наконец, этот объект возвращается в качестве результата: <source lang="kpp"> class MyClass {

   var int m_X;
   public constructor Create(const int x = 0)
   {
       var self = new MyClass;
       self.m_X = x;
       return self;
   }

}

function f() {

   var myObj = MyClass.Create(7);

} </source>

Поля

Поле класса - это некоторый объект, используемый объектом данного класса.

Объявление поля начинается с одного из трех ключевых слов:

var 
объявление "обычного" поля;
const 
данное поле является константой и не может быть изменено;
mutable 
значение данного поля не влияет на состояние объекта, и его можно менять даже в методах, объявленных константными.

За ключевым словом следует тип поля и его имя; тип может быть опущен.

После имени может стоять знак "=" и выражение, инициализирующее значение данного поля.

Примеры: <source lang="kpp"> var int m_x; const m_y = 0; var m_stream = new stream; </source>

Тип поля определяется по следующим правилам:

  • если тип указан явно, ничего определять не надо;
  • если тип не указан, но при объявлении использован инициализатор - типом становится тип результата инициализатора;
  • в противном случае, для поля устанавливается динамический тип.

Важное замечание: В K++ доступ к полям имеет только объект класса - т.е. фактически все поля находятся в закрытой (private) области видимости. Для предоставления доступа к полям следует использовать свойства (см. ниже).

Свойства

Расширения

Персональные инструменты
Пространства имён

Варианты
Действия
Навигация
информация
документация
Инструменты