PHP 编程/类
类是由三种称为成员的项组成的结构,即
- 常量;
- 称为“属性”的变量;
- 称为“方法”的函数。
它们中的每一个都以可见性声明,可见性可以是显式的(从“私有”、“保护”和“公共”),也可以是隐式的(即省略声明,仅允许用于默认值为“公共”的方法)。
对象是类的实例,在其中可以调用其类的所有方法(如果有),并可以为其类的成员(如果有)提供新的值,覆盖默认值。
一个简单的类可以定义如下
<?php
/* Start the class */
class Html {
/*
Declare a public member named "br" with a default value of "<br />" (the
XHTML line break)
*/
public $br = '<br />';
/*
Declare a public (by default) method named "printLn" requiring an argument
named "message"
*/
function printLn ($message) {
/*
Echo the "message" argument followed by the value of the "br" member (accessed
through the use of the "$this" keyword (that represents the current object),
the "->" operator (used to access members) and the member's name ''without''
the "$" character.
*/
echo $message . $this->br;
}
}
?>
但是,仅仅因为你创建了一个类并不意味着你可以使用其中的任何东西。类是一个抽象的实体。它是一种表示“以下是如何创建”的方法Html-类型的对象,以及它们的作用。” 为了使用类的成员,你必须创建一个该类的实例。
也就是说,你必须实际创建一个“Html”对象并使用它。
定义完类之后,你将要尝试它。对象是类的实例。在 PHP 中使用对象如下
<?php
$myPage = new Html; // Creates an instance of the Html class
$myPage->printLn('This is some text'); // Prints "This is some text<br />"
?>
这段代码中的新概念是
new
关键字 — 用于创建一个新的对象实例,在本例中是类Html
的一个对象。->
运算符 — 用于访问实例化对象的成员或方法,在本例中是方法printLn()
现在,换行符的表示形式是在类的成员中定义的,这使你能够更改它。请注意,更改仅会影响一个实例,而不是整个类。以下是一个示例(请注意,“<br>” 是一个 HTML 换行符,“<br />” 是一个 XHTML 换行符)
<?php
$myPage = new Html; // Creates an instance of the Html class
$myOldHtmlPage = new Html; // Creates another instance of the Html class
$myOldHtmlPage->br = "<br>"; // Changes the value of the "br" member of the "$myOldHtmlPage" instance to the old HTML value
$myOldHtmlPage->printLn('This is some text'); // Prints "This is some text<br>", the new value of the member is used
$myPage->printLn('This is some text'); // Prints "This is some text<br />", the default value of the member is kept
?>
但是,请注意,最好避免修改实例的成员:为了允许实例进行可能的约束验证,应该改为在类中添加(并在处理实例时使用)“get_br” 和 “set_br” 方法来获取和设置成员的值,同时允许实例执行测试,并可能拒绝更改。
类中项的作用域定义了谁可以调用它(对于方法)或读取/更改它的值(对于属性)。
作用域定义对于属性是强制性的,对于方法是可选的,其中“公共”是未指定任何内容时的默认值。
公共项可以在任何地方访问。
在类中定义的保护项可以被实例化此类或此类的子类的对象访问。
在类中定义的私有项可以被实例化该类的对象访问。
它们使用 const
声明(而不是在过程编程中使用 define()
),可以选择性地后面跟着一个默认值
const MY_CONSTANT_1 = 0;
它们可以通过反射检索
$myClass1::getConstants();
尽管将类属性声明为公共会使它们更容易使用,但一般不建议这样做。如果你决定在类的未来版本中对公共属性执行任何类型的检查,或者将其存储在另一个附加属性中以用于缓存目的,你将无法做到这一点,因为其余代码仍将使用公共属性而没有任何检查。
因此,人们应该更喜欢(除了特殊情况)不允许对属性进行公共访问,并提供简单的“get_foo”和“set_foo”方法来返回或覆盖它们,从而在需要时保留添加复杂性的可能性。
它们可以通过反射检索
$myClass1::getProperties();
由于方法提供了对象与外部世界的实际接口,因此大多数方法都应该公开访问。
更准确地说,任何旨在从外部调用的方法都应该是公共的。但是,仅用于内部使用且不是接口一部分的方法不应该是公共的。一个典型的例子是一个对象抽象与数据库的连接,同时提供一个缓存系统。应该存在不同的公共方法来允许与外部世界的交互,但是,例如,将原始 SQL 请求发送到数据库的方法不应该是公共的,因为任何调用它的外部代码都会绕过缓存,并可能导致无用的负载或(更糟)数据丢失,因为数据库的数据可能已过期(如果缓存中发生了延迟更改)。
它们可以通过反射检索
$myClass1::getMethods();
上面的示例没有说明类和对象的情况。为什么为了访问函数而去创建所有这些额外的结构呢?
让我们举一个可以显示这种方法如何有用的例子
<?php
class Html {
private $source = "";
public function printLn ($message) {
echo $this->source .= $message . "<br />";
}
public function show () {
echo $this->source;
}
}
$elvis = new Html();
$goth = new Html();
$elvis->printLn("Welcome to my Elvis Fan Page! Uh-huh, uh-huh, uh-huh.");
$goth->printLn("Entree the Goth Poetry Labyrinth of Spoooky Doooommmm...");
$elvis->show();
?>
一些需要注意的地方
- 语句echo $this->source .= $message ."<br />";首先更改私有属性的值$source然后打印更改后的值。更改后的值已保存。
- 不同的副本$source属性存在于每个实例中Html类。
- 的printLn和show函数引用的是同一个副本$source它被调用用于他们的对象。 (当我调用$elvis的printLn函数时,它会改变$elvis的$source变量和语句$elvis->show();打印改变后的值$source).
- 使用标准变量和方法,将会有更大的风险将错误的内容发送到错误的页面。这对于我的网站访客来说可能是极其混乱的。
现在我们开始看到如何使用类和对象来节省时间和麻烦。我们现在可以轻松地同时管理两个潜在的网页,将正确的内容打印到每个页面。完成后,我们只需调用一个页面的show函数将该页面的 html 源代码发送到输出流。
我可以通过向管理类添加变量和函数,为所有对象添加更多功能,并且可以根据需要添加更多对象,只需声明它们即可。事实上,我的程序越复杂,使用面向对象编程来管理一切就越容易。