【发布时间】:2011-01-13 11:09:42
【问题描述】:
我在从一本书中理解 PHP 类时遇到了严重的问题。他们似乎非常困难。它们的目的是什么以及它们是如何工作的?
【问题讨论】:
我在从一本书中理解 PHP 类时遇到了严重的问题。他们似乎非常困难。它们的目的是什么以及它们是如何工作的?
【问题讨论】:
我知道您要求的是资源,而不是解释,但这是我理解的类的基本实现:
把类想象成建筑的模板。建筑物应该是什么样子的基本草图。当你要实际构建它时,你会改变一些东西,让它看起来像你的客户想要的(属性在 class 的情况下)。现在您必须设计建筑物内的事物的行为方式(方法)。我将通过一个简单的例子来展示它。
建筑类:
/**
* Constructs a building.
*/
class Building
{
private $name;
private $height;
public function __construct( $name, $height )
{
$this->name = $name;
$this->height = $height;
}
/**
* Returns name of building.
*
* @return string
*/
public function getName( )
{
return $this->name;
}
public function elevatorUp( )
{
// Implementation
}
public function elevatorDown( )
{
// Implementation
}
public function lockDoor( )
{
// Implementation
}
}
调用类:
// Empire State Building
$empireStateBuilding = new Building( "Empire State Building", 381 );
echo $empireStateBuilding->getName( );
$empireStateBuilding->lockDoor( );
// Burj Khalifa
$burjKhalifa = new Building( "Burj Khalifa", 828 );
echo $burjKhalifa->getName( );
$burjKhalifa->lockDoor( );
只需复制它,在本地主机上运行它并尝试进行一些更改。如有任何问题,尽管问我。如果您觉得这没有用,只需使用以前海报的链接,这些都是非常可靠的教程。
【讨论】:
简而言之,类是对象的蓝图。一个对象在你的应用程序中封装了概念上相关的状态和责任,并且通常提供一个编程接口来与这些交互。这促进了代码重用并提高了可维护性。
想象一把锁:
namespace MyExample;
class Lock
{
private $isLocked = false;
public function unlock()
{
$this->isLocked = false;
echo 'You unlocked the Lock';
}
public function lock()
{
$this->isLocked = true;
echo 'You locked the Lock';
}
public function isLocked()
{
return $this->isLocked;
}
}
立即忽略namespace、private 和public 声明。
Lock 类是应用程序中所有锁的蓝图。锁可以锁定或解锁,由属性 $isLocked 表示。由于它只能具有这两种状态,因此我使用布尔值(true 或false)来指示适用的状态。我可以通过它的 方法 lock 和 unlock 与 Lock 进行交互,这将相应地改变状态。 isLocked 方法将为我提供锁的当前状态。现在,当您从此蓝图创建一个对象(通常也称为 instance)时,它将封装唯一状态,例如
$aLock = new Lock; // Create object from the class blueprint
$aLock->unlock(); // You unlocked the Lock
$aLock->lock(); // You locked the Lock
让我们创建另一个锁,同样封装它自己的状态
$anotherLock = new Lock;
$anotherLock->unlock(); // You unlocked the Lock
但因为每个对象/实例都封装了自己的状态,所以第一个锁保持锁定状态
var_dump( $aLock->isLocked() ); // gives Boolean true
var_dump( $anotherLock->isLocked() ); // gives Boolean false
现在,保持锁定或解锁的全部责任都封装在 Lock 类中。您不必在每次想要锁定某些东西时都重新构建它,如果您想更改锁的工作方式,您可以在锁的蓝图中更改它,而不是所有类拥有一个锁,例如一扇门:
class Door
{
private $lock;
private $connectsTo;
public function __construct(Lock $lock)
{
$this->lock = $lock;
$this->connectsTo = 'bedroom';
}
public function open()
{
if($this->lock->isLocked()) {
echo 'Cannot open Door. It is locked.';
} else {
echo 'You opened the Door connecting to: ', $this->connectsTo;
}
}
}
现在,当您创建一个 Door 对象时,您可以为其分配一个 Lock 对象。由于 Lock 对象负责处理某物是锁定还是解锁的所有责任,因此 Door 不必关心这一点。事实上,任何可以使用 Lock 的对象都不必关心,例如 Chest
class Chest
{
private $lock;
private $loot;
public function __construct(Lock $lock)
{
$this->lock = $lock;
$this->loot = 'Tons of Pieces of Eight';
}
public function getLoot()
{
if($this->lock->isLocked()) {
echo 'Cannot get Loot. The chest is locked.';
} else {
echo 'You looted the chest and got:', $this->loot;
}
}
}
如您所见,宝箱的职责与门的职责不同。一个箱子里装着战利品,而一扇门将房间隔开。您可以将锁定或解锁状态编码到两个类中,但是使用单独的 Lock 类,您不必并且可以重用 Lock。
$doorLock = new Lock;
$myDoor = new Door($doorLock);
$chestLock = new Lock;
$myChest new Chest($chestLock);
宝箱和门现在有了各自独特的锁。如果锁是可以同时存在于多个地方的魔法锁,就像在量子物理学中一样,您可以将相同的锁分配给箱子和门,例如
$quantumLock = new Lock;
$myDoor = new Door($quantumLock);
$myChest new Chest($quantumLock);
当你unlock()$quantumLock 时,门和箱子都会被解锁。
虽然我承认量子锁是一个不好的例子,但它说明了共享对象的概念,而不是在所有地方重建状态和责任。一个真实世界的例子可能是一个数据库对象,您使用该数据库传递给类。
请注意,上面的示例没有显示如何使用lock() 和unlock() 方法到达箱子或门的锁。我将此作为练习留给您(或其他人添加)。
还可以查看When to use self over $this? 以更深入地了解类和对象以及如何使用它们
对于一些额外的资源检查
【讨论】:
如果可以的话,从另一个角度提供一个观点(基于个人经验)。在您真正理解这一切之前,您需要感受到“OOP 的需要”——恕我直言,学习资源应该在此之后出现。
在编写以过程式风格编写的相对较大的软件时,基本上“需要”陷入结构性困难(与面向对象相反,如果有人不同意该术语,请见谅)。到那时,他/她可以尝试将代码重组为对象以更好地组织它,并且自然而然地详细了解 OOP。同样,这是我的个人经历,它让我比任何书都更快地理解。
只有我的两分钱。
【讨论】: