Править]виртуальный конструктор

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

«Виртуальными конструкторами» называют похожий, но другой механизм, присутствующий в некоторых языках — например, он есть в Delphi, но нет в C++ и Java. Этот механизм позволяет создать объект любого заранее неизвестного класса при двух условиях:

§ этот класс является потомком некоего наперёд заданного класса (в данном примере это класс TVehicle);

§ на всём пути наследования от базового класса к создаваемому цепочка переопределения не обрывалась. При переопределении виртуального метода синтаксис Delphi требует ключевое слово overload, чтобы старая и новая функции с разными сигнатурами могли сосуществовать, override для переопределения функции либо reintroduce для задания новой функции с тем же именем — последнее недопустимо.

type TVehicle = class constructor Create; virtual; end; TAutomobile = class (TVehicle) constructor Create; override; end; TMotorcycle = class (TVehicle) constructor Create; override; end; TMoped = class (TMotorcycle) // обрываем цепочку переопределения - заводим новый Create constructor Create(x : integer); reintroduce; end;

В языке вводится так называемый классовый тип. Этот тип в качестве значения может принимать название любого класса, производного от TVehicle.

type CVehicle = class of TVehicle;

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

var cv : CVehicle; v : TVehicle; cv := TAutomobile;v := cv.Create;

Заметьте, что код

cv := TMoped;v := cv.Create;

является некорректным — директива reintroduce разорвала цепочку переопределения виртуального метода, и в действительности будет вызван конструктор TMotorcycle.Create (а значит, будет создан мотоцикл, а не мопед!)

См. также Фабрика (шаблон проектирования)

Править]Синтаксис

[править]С++

Имя конструктора должно совпадать с именем класса. Допускается использовать несколько конструкторов с одинаковым именем, но различными параметрами.

class ClassWithConstructor { public: /* Инициализация внутреннего объекта с помощью конструктора */ ClassWithConstructor(float parameter): object(parameter) {}/* вызов конструктора AnotherClass(float); */ private: AnotherClass object;};

Править]Python

В языке Python конструктором является метод класса с именем __init__ . Кроме того не следует забывать, что первым аргументом любого метода должен быть указатель на контекст класса self.

Править]Пример

class ClassWithConstructor: def __init__(self): """This method is constructor.""" pass

Править]Delphi

В Delphi, в отличие от C++, для объявления конструктора служит ключевое слово constructor. Имя конструктора может быть любым, но рекомендуется называть конструктор Create.

Править]Пример

TClassWithConstructor = class public constructor Create; end;

Править]Java

Некоторые отличия между конструкторами и другими методами Java:

§ конструкторы не имеют чётко определённого типа возвращаемых данных;

§ конструкторы не могут напрямую вызываться (необходимо использовать ключевое слово new);

§ конструкторы не могут быть synchronized, final, abstract, native и static типов;

§ конструкторы всегда выполняются в том же потоке.

Править]Пример

public class Example { // Конструктор по умолчанию public Example() { this(1); } // Перегрузка конструктора public Example(int input) { data = input; } private int data;}// код, иллюстрирующий создание объекта описанным выше конструкторомExample e = new Example(42);

Править]JavaScript

В JavaScript в качестве конструктора выступает обычная функция, используемая в качестве операнда оператора new. Для обращения к созданному объекту используется ключевое словоthis.

Править]Пример

function Example(initValue) { this.myValue = initValue;} Example.prototype.getMyValue = function() { return this.myValue; }// код, иллюстрирующий создание объекта описанным выше конструкторомvar exampleObject = new Example(120);

Править]Visual Basic .NET

Конструкторы в Visual Basic .NET используют обычный метод объявления с именем New.

Править]Пример

Class Foobar Private strData As String ' Constructor Public Sub New(ByVal someParam As String) strData = someParam End SubEnd Class' некий код' иллюстрирующий создание объекта описанным выше конструкторомDim foo As New Foobar(".NET")

[править]C#

Править]Пример

class myClass{ private int mA; private string mB; public myClass(int a, string b) { mA = a; mB = b; }}// код, иллюстрирующий создание объекта описанным выше конструкторомmyClass c = new myClass(42, "string");

Править]Эйфель

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

§ Процедуры создания не имеют никакого явного типа результата возврата (по определению процедуры[Примечание 1]).

§ процедуры создания поименованы (имена ограничены допустимыми идентификаторами);

§ процедуры создания задаются по именам в тексте класса;

§ процедуры создания могут быть вызваны напрямую (как обычные процедуры) для повторной инициализации объектов;

§ каждый эффективный (то есть конкретный, не абстрактный) класс должен (явно или неявно) указать по крайней мере одну процедуру создания;

§ процедуры создания отвечают за приведение только что проинициализированного объекта в состояние, которое удовлетворяет инварианту класса[Примечание 2].

Хотя создание объекта является предметом некоторых тонкостей [Примечание 3], создание атрибута с типовым объявлением x: T, выраженном в виде инструкции создания create x.makeсостоит из следующей последовательности шагов:

§ создать новый непосредственный экземпляр типа T[Примечание 4];

§ выполнить процедуру создания make для вновь созданного экземпляра;

§ прикрепить вновь созданный объект к сущности x.

Править]Пример

В первом отрывке ниже определяется класс POINT. Процедура make кодируется после ключевого слова feature.

Ключевое слово create вводит список процедур, которые могут быть использованы для инициализации экземпляров класса. В данном случае список содержит default_create, процедуру с пустой реализацией, унаследованной из класса ANY, и процедуру make с реализацией в самом классе POINT.

class POINTcreate default_create, make feature make (a_x_value: REAL; a_y_value: REAL) do x := a_x_value y := a_y_value end x: REAL -- Координата X y: REAL -- Координата Y ...

Во втором отрывке класс, являющийся клиентом класса POINT, имеет объявления my_point_1 и my_point_2 типа POINT.

В коде подпрограммы my_point_1 создаётся с координатами (0.0; 0.0). Поскольку в инструкции создания не указана процедура создания, используется процедура default_create, унаследованная из класса ANY. Эта же строка могла бы быть переписана как create my_point_1.default_create. Только процедуры, указанные как процедуры создания могут использоваться в инструкциях создания (то есть в инструкциях с ключевым словом create).

Следующей идёт инструкция создания для my_point_2, задающая начальные значения для координат my_point_2.

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

my_point_1: POINT my_point_2: POINT ... create my_point_1 create my_point_2.make (3.0, 4.0) my_point_2.make (5.0, 8.0) ...

Править]ColdFusion

Править]Пример

Необходимо отметить, что в ColdFusion не существует метода-конструктора. Широкое распространение среди сообщества программистов на ColdFusion получил способ вызова метода 'init', выступающего в качестве псевдоконструктора.

<cfcomponent displayname="Cheese"> <!--- свойства ---> <cfset variables.cheeseName = "" /> <!--- псевдоконструктор ---> <cffunction name="init" returntype="Cheese"> <cfargument name="cheeseName" type="string" required="true" /> <cfset variables.cheeseName = arguments.cheeseName /> <cfreturn this /> </cffunction></cfcomponent>

Править]PHP

Править]Пример

В PHP (начиная с версии 5) конструктор — это метод __construct(), который автоматически вызывается ключевым словом new после создания объекта. Обычно используется для выполнения различных автоматических инициализаций, как например, инициализация свойств. Конструкторы также могут принимать аргументы, в этом случае, когда указано выражениеnew, необходимо передать конструктору формальные параметры в круглых скобках.

class Person{ private $name; function __construct($name) { $this->name = $name; } function getName() { return $this->name; }}

Тем не менее, конструктор в PHP версии 4 (и ранее) — метод класса с именем этого же класса.

class Person{ private $name; function Person($name) { $this->name = $name; } function getName() { return $this->name; }}

[править]Упрощенные конструкторы (с псевдокодом)

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

class Student { // описание класса учеников // ... прочий код ...}

Тем не менее, класс Student — всего лишь общий шаблон (прототип) наших школьников. Для его использования программист создает каждого школьника в виде объекта или сущности(реализации) класса. Этот объект является тем реальным фрагментом данных в памяти, чьи размер, шаблон, характеристики и (в некоторой мере) поведение определяются описанием класса. Обычный способ создания объектов — вызов конструктора (классы в общем случае могут иметь отдельные конструкторы). Например,

class Student { Student (String studentName, String Address, int ID) { // ... здесь храним вводимые данные и прочие внутрнние поля ... } // ...}

[править]

Наши рекомендации