- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我在从一本书中理解 PHP 类时遇到了严重的问题。他们似乎非常困难。它们的目的是什么以及它们是如何工作的?
最佳答案
简而言之,类是对象的蓝图。一个对象在你的应用程序中封装了概念上相关的状态和责任,并且通常提供一个编程接口(interface)来与这些交互。这促进了代码重用并提高了可维护性。
想象一把锁:
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
表示。由于它只能具有这两种状态,因此我使用 bool 值(true
或 false
)来指示适用的状态。我可以通过它的 methods 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?更深入地解释类和对象以及如何使用它们
对于一些额外的资源检查
关于php - PHP 中的类是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2206387/
我想做的是让 JTextPane 在 JPanel 中占用尽可能多的空间。对于我使用的 UpdateInfoPanel: public class UpdateInfoPanel extends JP
我在 JPanel 中有一个 JTextArea,我想将其与 JScrollPane 一起使用。我正在使用 GridBagLayout。当我运行它时,框架似乎为 JScrollPane 腾出了空间,但
我想在 xcode 中实现以下功能。 我有一个 View Controller 。在这个 UIViewController 中,我有一个 UITabBar。它们下面是一个 UIView。将 UITab
有谁知道Firebird 2.5有没有类似于SQL中“STUFF”函数的功能? 我有一个包含父用户记录的表,另一个表包含与父相关的子用户记录。我希望能够提取用户拥有的“ROLES”的逗号分隔字符串,而
我想使用 JSON 作为 mirth channel 的输入和输出,例如详细信息保存在数据库中或创建 HL7 消息。 简而言之,输入为 JSON 解析它并输出为任何格式。 最佳答案 var objec
通常我会使用 R 并执行 merge.by,但这个文件似乎太大了,部门中的任何一台计算机都无法处理它! (任何从事遗传学工作的人的附加信息)本质上,插补似乎删除了 snp ID 的 rs 数字,我只剩
我有一个以前可能被问过的问题,但我很难找到正确的描述。我希望有人能帮助我。 在下面的代码中,我设置了varprice,我想添加javascript变量accu_id以通过rails在我的数据库中查找记
我有一个简单的 SVG 文件,在 Firefox 中可以正常查看 - 它的一些包装文本使用 foreignObject 包含一些 HTML - 文本包装在 div 中:
所以我正在为学校编写一个 Ruby 程序,如果某个值是 1 或 3,则将 bool 值更改为 true,如果是 0 或 2,则更改为 false。由于我有 Java 背景,所以我认为这段代码应该有效:
我做了什么: 我在这些账户之间创建了 VPC 对等连接 互联网网关也连接到每个 VPC 还配置了路由表(以允许来自双方的流量) 情况1: 当这两个 VPC 在同一个账户中时,我成功测试了从另一个 La
我有一个名为 contacts 的表: user_id contact_id 10294 10295 10294 10293 10293 10294 102
我正在使用 Magento 中的新模板。为避免重复代码,我想为每个产品预览使用相同的子模板。 特别是我做了这样一个展示: $products = Mage::getModel('catalog/pro
“for”是否总是检查协议(protocol)中定义的每个函数中第一个参数的类型? 编辑(改写): 当协议(protocol)方法只有一个参数时,根据该单个参数的类型(直接或任意)找到实现。当协议(p
我想从我的 PHP 代码中调用 JavaScript 函数。我通过使用以下方法实现了这一点: echo ' drawChart($id); '; 这工作正常,但我想从我的 PHP 代码中获取数据,我使
这个问题已经有答案了: Event binding on dynamically created elements? (23 个回答) 已关闭 5 年前。 我有一个动态表单,我想在其中附加一些其他 h
我正在尝试找到一种解决方案,以在 componentDidMount 中的映射项上使用 setState。 我正在使用 GraphQL连同 Gatsby返回许多 data 项目,但要求在特定的 pat
我在 ScrollView 中有一个 View 。只要用户按住该 View ,我想每 80 毫秒调用一次方法。这是我已经实现的: final Runnable vibrate = new Runnab
我用 jni 开发了一个 android 应用程序。我在 GetStringUTFChars 的 dvmDecodeIndirectRef 中得到了一个 dvmabort。我只中止了一次。 为什么会这
当我到达我的 Activity 时,我调用 FragmentPagerAdapter 来处理我的不同选项卡。在我的一个选项卡中,我想显示一个 RecyclerView,但他从未出现过,有了断点,我看到
当我按下 Activity 中的按钮时,会弹出一个 DialogFragment。在对话框 fragment 中,有一个看起来像普通 ListView 的 RecyclerView。 我想要的行为是当
我是一名优秀的程序员,十分优秀!