Я работаю с классами и структурой класса объекта, но не на сложном уровне – просто классы и функции, затем, в одном месте, инстанцировании.
Относительно __construct
и __destruct
, скажите мне очень просто: какова цель конструкторов и деструкторов?
Я знаю школьный уровень теоретическое объяснение, но я ожидаю что-то как в реальном мире, как, в которых ситуациях мы должны использовать их.
Обеспечьте также пример.
С уважением
Я обнаружил, что это было легче всего понять, когда я думал о ключевом слове new
перед конструктором: оно просто сообщает моей переменной, что ей будет передан новый объект ее типа данных. В зависимости от того, какой конструктор я вызываю и что я в него передаю, я могу определить состояние объекта по прибытии.
Без нового объекта мы бы жили в стране null
и аварий!
Деструктор наиболее очевиден с точки зрения C++, где если у вас нет метода деструктора, удаляющего всю память, на которую указывает объект, она будет оставаться использованной после завершения программы, вызывая утечки и задержки в клиентской ОС до следующей перезагрузки.
Я уверен, что здесь более чем достаточно хорошей информации, но другой угол зрения всегда полезен, насколько я заметил!
Конструктор запускается во время создания экземпляра вашего класса. Итак, если у вас есть класс Person
:
class Person {
public $name = 'Bob'; // this is initialization
public $age;
public function __construct($name = '') {
if (!empty($name)) {
$this->name = $name;
}
}
public function introduce() {
echo "I'm {$this->name} and I'm {$this->age} years old\n";
}
public function __destruct() {
echo "Bye for now\n";
}
}
Чтобы продемонстрировать:
$person = new Person;
$person->age = 20;
$person->introduce();
// I'm Bob and I'm 20 years old
// Bye for now
Мы можем переопределить значение по умолчанию, установленное с инициализацией через аргумент конструктора:
$person = new Person('Fred');
$person->age = 20;
$person->introduce();
// if there are no other references to $person and
// unset($person) is called, the script ends
// or exit() is called __destruct() runs
unset($person);
// I'm Fred and I'm 20 years old
// Bye for now
Надеюсь, это поможет продемонстрировать, где находятся конструктор и деструктор вызваны, для чего они полезны?
__ construct ()
может по умолчанию члены класса с ресурсами или более сложными структурами данных. __ destruct ()
может освобождать ресурсы, такие как дескрипторы файлов и баз данных. Конструктор - это функция, которая выполняется после инициализации объекта (выделение памяти, копирование свойств экземпляра и т. Д.). Его цель - привести объект в допустимое состояние.
Часто для того, чтобы объект был в рабочем состоянии, требуются некоторые данные. Цель конструктора - принудительно передать эти данные объекту во время создания экземпляра и запретить любые экземпляры без таких данных.
Рассмотрим простой класс, который инкапсулирует строку и имеет метод, возвращающий длину этой строки. Одна из возможных реализаций:
class StringWrapper {
private $str;
public function setInnerString($str) {
$this->str = (string) $str;
}
public function getLength() {
if ($this->str === null)
throw new RuntimeException("Invalid state.");
return strlen($this->str);
}
}
Чтобы быть в допустимом состоянии, эта функция требует вызова setInnerString
перед getLength
.Используя конструктор, вы можете заставить все экземпляры быть в хорошем состоянии при вызове getLength
:
class StringWrapper {
private $str;
public function __construct($str) {
$this->str = (string) $str;
}
public function getLength() {
return strlen($this->str);
}
}
Вы также можете оставить setInnerString
, чтобы разрешить изменение строки после создания.
Деструктор вызывается, когда объект собирается освободить из памяти. Как правило, он содержит код очистки (например, закрытие файловых дескрипторов, которые хранятся в объекте). Они редко встречаются в PHP, потому что PHP очищает все ресурсы, удерживаемые скриптом, когда выполнение скрипта завершается.
Конструктор класса определяет, что происходит, когда вы создаете экземпляр объекта из этого класса. Деструктор класса определяет, что происходит, когда вы уничтожаете экземпляр объекта.
См. Руководство PHP по конструкторам и деструкторам :
PHP 5 позволяет разработчикам объявлять методы конструкторов для классов. Классы, у которых есть метод конструктора, вызывают этот метод для каждого вновь созданного объекта, поэтому он подходит для любой инициализации, которая может потребоваться объекту перед его использованием.
и
PHP 5 вводит концепцию деструктора, аналогичную концепции других объектно-ориентированных языков, таких как C ++. Метод деструктора будет вызываться, как только будут удалены все ссылки на конкретный объект, или когда объект будет явно уничтожен, или в любом порядке в последовательности завершения работы.
На практике вы используете конструктор, чтобы перевести объект в минимально допустимое состояние. Это означает, что вы назначаете аргументы, переданные конструктору, свойствам объекта. Если ваш объект использует какие-то типы данных, которые нельзя назначить напрямую как свойство, вы создаете их здесь, например
class Example
{
private $database;
private $storage;
public function __construct($database)
{
$this->database = $database;
$this->storage = new SplObjectStorage;
}
}
Обратите внимание, что для того, чтобы ваши объекты оставались тестируемыми, конструктор не должен выполнять никакой реальной работы :
Работа в конструкторе, такая как: создание / инициализация сотрудников, взаимодействие с другими службами и логика чтобы настроить собственное состояние, удаляет швы, необходимые для тестирования, заставляя подклассы / макеты наследовать нежелательное поведение. Слишком большая работа в конструкторе препятствует созданию или изменению соавторов в тесте.
В приведенном выше примере
, база данных $
является соавтором. Он имеет собственный жизненный цикл и цель и может быть общим экземпляром. Вы бы не создавали это внутри конструктора. С другой стороны, SplObjectStorage
является неотъемлемой частью Example
. У него такой же жизненный цикл, и он не используется совместно с другими объектами. Таким образом, это нормально новый
его в ctor.
Таким же образом вы используете деструктор для очистки после вашего объекта. В большинстве случаев в этом нет необходимости, потому что это автоматически выполняется PHP. Вот почему вы увидите гораздо больше ctors, чем dtors в дикой природе.
Учитесь на примере:
class Person {
public $name;
public $surname;
public function __construct($name,$surname){
$this->name=$name;
$this->surname=$surname;
}
}
Почему это полезно? Потому что вместо:
$person = new Person();
$person->name='Christian';
$person->surname='Sciberras';
вы можете использовать:
$person = new Person('Christian','Sciberras');
Это меньше кода и выглядит чище!
Примечание. Как правильно указано в ответах ниже, конструкторы / деструкторы используются для самых разных целей, включая: де / инициализацию переменных (особенно, когда значение является переменным), де / выделение памяти, инварианты (могут быть превзойден) и более чистый код. Я также хотел бы отметить, что «более чистый код» - это не просто «сахар», он повышает удобочитаемость, ремонтопригодность и т. Д.