Конструктор не бывает виртуальным в смысле виртуального метода — для того, чтобы механизм виртуальных методов работал, нужно запустить конструктор, который автоматически настроит таблицу виртуальных методов данного объекта.
«Виртуальными конструкторами» называют похожий, но другой механизм, присутствующий в некоторых языках — например, он есть в 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.
Править]Пример
[править]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 POINT create 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; }}[править]Упрощенные конструкторы (с псевдокодом)
Конструкторы всегда являются частью реализации классов. Класс (в программировании) описывает спецификации основных характеристик набора объектов, являющихся членами класса, а не отдельные характеристики какого-либо объекта из них. Рассмотрим простую аналогию. Возьмем в качестве примера набор (или класс, используя его более общее значение) учеников некоторой школы. Таким образом мы имеем:
Тем не менее, класс Student — всего лишь общий шаблон (прототип) наших школьников. Для его использования программист создает каждого школьника в виде объекта или сущности (реализации) класса. Этот объект является тем реальным фрагментом данных в памяти, чьи размер, шаблон, характеристики и (в некоторой мере) поведение определяются описанием класса. Обычный способ создания объектов — вызов конструктора (классы в общем случае могут иметь отдельные конструкторы). Например,
class Student { Student (String studentName, String Address, int ID) { //... здесь храним вводимые данные и прочие внутрнние поля... } //...}
[править]