我正在使用类和对象类结构进行编程,但不是在复杂的层面上——只是关于类和函数,然后在一个地方进行实例化。
至于__construct
和__destruct
,请简单告诉我:构造函数和析构函数的目的是什么?
我知道学校级别的理论解释,但我期望得到一些真实世界中的例子,例如我们何时需要使用它们。
请提供一个例子。
谢谢
我正在使用类和对象类结构进行编程,但不是在复杂的层面上——只是关于类和函数,然后在一个地方进行实例化。
至于__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);
}
}
为了保证函数处于有效状态,必须在调用getLength
之前先调用setInnerString
。通过使用构造函数,可以强制所有实例在调用getLength
时都处于良好状态:
class StringWrapper {
private $str;
public function __construct($str) {
$this->str = (string) $str;
}
public function getLength() {
return strlen($this->str);
}
}
你也可以保留 setInnerString
方法,允许在实例化后更改字符串。
当一个对象即将从内存中释放时,会调用析构函数。通常,它包含清理代码(例如关闭对象持有的文件描述符)。在 PHP 中它们很少见,因为当脚本执行结束时,PHP 会清理脚本所持有的所有资源。
通过例子学习:
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');
哪种方法代码更少且看起来更整洁!
注意:如下回复所述,构造函数/析构函数用于各种用途,包括:变量的初始化/去初始化(特别是值是变量时),内存分配/释放,不变式(可能被超越)以及更清晰的代码。 我还想指出,“更清晰的代码”不仅仅是“甜头”,而且提高了可读性、可维护性等。
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 Example
{
private $database;
private $storage;
public function __construct($database)
{
$this->database = $database;
$this->storage = new SplObjectStorage;
}
}
示例
中,$database
是一个协作者。它具有自己的生命周期和目的,并且可能是共享实例。您不会在构造函数中创建它。另一方面,SplObjectStorage
是Example
的一个重要部分。它具有完全相同的生命周期,并且不与其他对象共享。因此,在构造函数中new
它是可以的。我发现当我在考虑构造函数之前想到new
关键字时,最容易理解:它仅告诉我的变量将被给予其数据类型的新对象,根据我调用的构造函数和传递给它的参数,我可以定义到达时对象的状态。
没有新对象,我们将生活在null
的世界中,并遭遇崩溃!
从C++的角度来看,析构函数是最明显的:如果您没有一个析构方法来删除所有指向的内存,那么在程序退出后它将继续使用,导致客户端操作系统出现泄漏和延迟,直到下一次重新启动。
我确定这里有足够多的信息,但另一个角度总是有帮助的,这是我注意到的!
构造函数是类的一种函数,当创建类的对象时自动执行,我们不需要单独调用该构造函数。我们可以将构造函数称为魔术方法,因为在 PHP 中,魔术方法以双下划线字符开头。