PHP 抽象 Class 数组保护属性
PHP Abstract Class Array Protected Properties
我在使用 Abstract 类 和 OOP 方面有些陌生,所以请多多包涵。
我正在尝试制作员工和客户的列表,但我 运行 在打印 StoreList class 中的对象数组时遇到了一些麻烦,因为它们都受到保护。
我想要做的是将 storeArray 中的值打印到一个漂亮的列表中。
现在它从抽象 class 中打印出所有内容,使数组过时。
我将在下面包含所有代码,但由于它很长,我想在这里问这个问题。
这是数组在 var_dump 上 index.php 或 Storelistclass.php
时输出的内容
array (size=5)
0 =>
object(Employee)[1]
protected 'userId' => string '1' (length=1)
protected 'userFirstName' => string 'Joe' (length=3)
protected 'userLastName' => string 'Longo' (length=5)
protected 'userTitle' => string 'Employee' (length=8)
1 =>
object(Customer)[2]
protected 'userId' => string '1' (length=1)
protected 'userFirstName' => string 'Bruce' (length=5)
protected 'userLastName' => string 'Stark' (length=5)
protected 'userTitle' => string 'Customer' (length=8)
2 =>
object(Customer)[3]
protected 'userId' => string '2' (length=1)
protected 'userFirstName' => string 'Tony' (length=4)
protected 'userLastName' => string 'Wayne' (length=5)
protected 'userTitle' => string 'Customer' (length=8)
3 =>
object(Customer)[4]
protected 'userId' => string '3' (length=1)
protected 'userFirstName' => string 'Oliver' (length=6)
protected 'userLastName' => string 'Wilson' (length=6)
protected 'userTitle' => string 'Customer' (length=8)
4 =>
object(Customer)[5]
protected 'userId' => string '4' (length=1)
protected 'userFirstName' => string 'Slade' (length=5)
protected 'userLastName' => string 'Queen' (length=5)
protected 'userTitle' => string 'Customer' (length=8)
无论我在哪里尝试通过数组对 运行 进行 foreach 循环,我都会收到错误消息:
无法访问受保护的 属性.
foreach($this->storeArray as $data)
{
echo $data->userFirstName;
}
当我在 User 抽象中创建属性时 class public 它工作得很好,但是 Gets 会过时吗?
我应该放弃 Gets 并使它们成为 public ,还是有其他方法?
抱歉,如果这是一个愚蠢的问题,但我真的很想解决这个问题,但失败了。
任何帮助和提示(也包括更新和删除功能)将不胜感激!
这是我现在所有的代码。
index.php:
<?php
include("classes/Userclass.php");
include("classes/Customerclass.php");
include("classes/Employeeclass.php");
include("classes/Storelistclass.php");
$employeeOne = new Employee("1","Joe","Longo","Employee");
$customerOne = new Customer("1","Bruce","Stark","Customer");
$customerTwo = new Customer("2","Tony","Wayne","Customer");
$customerThree = new Customer("3","Oliver","Wilson","Customer");
$customerFour = new Customer("4","Slade","Queen","Customer");
$list = new Storelist($employeeOne);
$list->addCustomer($customerOne);
$list->addCustomer($customerTwo);
$list->addCustomer($customerThree);
$list->addCustomer($customerFour);
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<!--<link href="includes/stylesheet.css" rel="stylesheet" type="text/css"/>-->
<title>Store List</title>
</head>
<body>
<h1>Test Get Customer</h1>
<p>
<?php
echo $customerOne->getUserTitle()." #". $customerOne->getUserId() ."'s First name is ". $customerOne->getUserFirstName() ." and Last name is ". $customerOne->getUserLastName() ."<br/>";
echo $customerTwo->getUserTitle()." #". $customerTwo->getUserId() ."'s First name is ". $customerTwo->getUserFirstName() ." and Last name is ". $customerTwo->getUserLastName() ."<br/>";
?>
</p>
<h1>Test Get Employee</h1>
<p>
<?php
echo $employeeOne->getUserTitle()." #". $employeeOne->getUserId() ."'s First name is ". $employeeOne->getUserFirstName() ." and Last name is ". $employeeOne->getUserLastName() ."<br/>";
?>
</p>
<h1>Storelist Foreach</h1>
<p>
<?php
$listtest = $list->buildList();
echo $listtest;
?>
</p>
Customerclass.php:
class Customer extends User
{
public function userSayHi()
{
return "Hello , could i get some help?";
}
}
Employeeclass.php:
<?php
class Employee extends User
{
public function userSayHi()
{
return 'Hello , how may i help u?';
}
}
Userclass.php
<?php
abstract class User
{
protected $userId;
protected $userFirstName;
protected $userLastName;
protected $userTitle;
public function __construct($id, $firstName, $lastName, $title)
{
$this->userId = $id;
$this->userFirstName = $firstName;
$this->userLastName = $lastName;
$this->userTitle = $title;
}
//Gets
public function getUserId()
{
return $this->userId;
}
public function getUserFirstName()
{
return $this->userFirstName;
}
public function getUserLastName()
{
return $this->userLastName;
}
public function getUserTitle()
{
return $this->userTitle;
}
//Sets
public function setUserId($uId)
{
$this->userId = $uId;
}
public function setUserFirstName($ufirstName)
{
$this->userFirstName = $ufirstName;
}
public function setUserLastName($ulastName)
{
$this->userLastName = $ulastName;
}
public function setUserTitle($uTitle)
{
$this->userTitle = $uTitle;
}
public abstract function userSayHi();
}
Storelistclass.php
<?php
require_once("Customerclass.php");
require_once("Employeeclass.php");
class Storelist
{
public $storeArray = [];
public function __construct(Employee $employee)
{
array_push($this->storeArray, $employee);
}
public function addCustomer(Customer $customer)
{
array_push($this->storeArray, $customer);
//return $this->storeArray;
}
public function buildList()
{
foreach($this->storeArray as $storeData)
{
echo "First Name: ".$storeData->getUserFirstName()."<br/>";
echo "Last Name: ".$storeData->getUserLastName()."<br/>";
echo "Is a: ".$storeData->getUserTitle()."<br/>";
echo "<br/>";
}
/*
//ERROR : Cannot access protected property Employee::$userFirstName
foreach($this->storeArray as $storeData)
{
echo "First Name: ".$storeData->userFirstName."<br/>";
echo "Last Name: ".$storeData->userLastName."<br/>";
echo "Is a: ".$storeData->userTitle."<br/>";
echo "<br/>";
}
*/
}
public function delete()
{
}
public function update()
{
}
}
解决方案是实际使用您费心定义的 getter 方法 (getUserWhatever()
)。通过使它们保持 protected
可见性,除了使用您定义的 setUserWhatever()
方法之外无法修改它们,因此您可以进行额外的验证(例如防止非空值)例如,对无效数据抛出异常。因此,它们不能像 public
属性那样从 class 外部直接可变是很有用的。
在您的 Storelist
class 中,您定义了 $storeArray
属性 具有 public
可见性,这意味着您可以在 [=] 之外阅读它52=] 在 index.php
中。由于您要向该数组添加 Employee
或 Customer
对象,因此这些对象仍可通过其在 $list->storeArray
上的数组键单独寻址。例如,要修改姓氏,您可以使用
// Set the 3rd user's last name
$list->storeArray[2]->setUserLastName('Jones');
同样,在 Storelist
class:
中使用 $this
也是可能的
// Inside Storelist
$this->storeArray[2]->setUserLastName('Jones');
因此,您对这些 classes 的布局已经基本步入正轨。我还可以建议一件事;因为您已经创建了通过方法调用将 Customer
或 Employee
对象添加到 Storelist::$storeArray
的方法,而不是直接修改数组:
// You're doing this:
$list = new Storelist($employeeOne);
$list->addCustomer($customerOne);
// And not this (directly modifying storeArray):
$list = new Storelist($employeeOne);
$list->storeArray[] = $customerOne
...然后考虑将 Storelist::$storeArray
定义为 protected
属性 以便您可以 仅 使用其 setter 方法。然后你还需要创建一个 getter 方法来 returns 数组。
class Storelist
{
// This becomes protected
protected $storeArray = [];
// So you need a getter:
public function getStoreArray()
{
return $this->storeArray;
}
// etc...
}
从index.php
修改数组之后,就不能再直接读取它的元素了。相反,你调用它的 getter 方法:
// You can't do this:
$list->storeArray[2]->setUserLastName('Jones');
// Instead do it via the getter:
$list->getStoreArray()[2]->setUserLastName('Jones');
(注意,上面的 ()[2]
语法需要 PHP 5.4+)
我在使用 Abstract 类 和 OOP 方面有些陌生,所以请多多包涵。
我正在尝试制作员工和客户的列表,但我 运行 在打印 StoreList class 中的对象数组时遇到了一些麻烦,因为它们都受到保护。
我想要做的是将 storeArray 中的值打印到一个漂亮的列表中。
现在它从抽象 class 中打印出所有内容,使数组过时。
我将在下面包含所有代码,但由于它很长,我想在这里问这个问题。
这是数组在 var_dump 上 index.php 或 Storelistclass.php
array (size=5)
0 =>
object(Employee)[1]
protected 'userId' => string '1' (length=1)
protected 'userFirstName' => string 'Joe' (length=3)
protected 'userLastName' => string 'Longo' (length=5)
protected 'userTitle' => string 'Employee' (length=8)
1 =>
object(Customer)[2]
protected 'userId' => string '1' (length=1)
protected 'userFirstName' => string 'Bruce' (length=5)
protected 'userLastName' => string 'Stark' (length=5)
protected 'userTitle' => string 'Customer' (length=8)
2 =>
object(Customer)[3]
protected 'userId' => string '2' (length=1)
protected 'userFirstName' => string 'Tony' (length=4)
protected 'userLastName' => string 'Wayne' (length=5)
protected 'userTitle' => string 'Customer' (length=8)
3 =>
object(Customer)[4]
protected 'userId' => string '3' (length=1)
protected 'userFirstName' => string 'Oliver' (length=6)
protected 'userLastName' => string 'Wilson' (length=6)
protected 'userTitle' => string 'Customer' (length=8)
4 =>
object(Customer)[5]
protected 'userId' => string '4' (length=1)
protected 'userFirstName' => string 'Slade' (length=5)
protected 'userLastName' => string 'Queen' (length=5)
protected 'userTitle' => string 'Customer' (length=8)
无论我在哪里尝试通过数组对 运行 进行 foreach 循环,我都会收到错误消息: 无法访问受保护的 属性.
foreach($this->storeArray as $data)
{
echo $data->userFirstName;
}
当我在 User 抽象中创建属性时 class public 它工作得很好,但是 Gets 会过时吗?
我应该放弃 Gets 并使它们成为 public ,还是有其他方法?
抱歉,如果这是一个愚蠢的问题,但我真的很想解决这个问题,但失败了。
任何帮助和提示(也包括更新和删除功能)将不胜感激!
这是我现在所有的代码。
index.php:
<?php
include("classes/Userclass.php");
include("classes/Customerclass.php");
include("classes/Employeeclass.php");
include("classes/Storelistclass.php");
$employeeOne = new Employee("1","Joe","Longo","Employee");
$customerOne = new Customer("1","Bruce","Stark","Customer");
$customerTwo = new Customer("2","Tony","Wayne","Customer");
$customerThree = new Customer("3","Oliver","Wilson","Customer");
$customerFour = new Customer("4","Slade","Queen","Customer");
$list = new Storelist($employeeOne);
$list->addCustomer($customerOne);
$list->addCustomer($customerTwo);
$list->addCustomer($customerThree);
$list->addCustomer($customerFour);
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<!--<link href="includes/stylesheet.css" rel="stylesheet" type="text/css"/>-->
<title>Store List</title>
</head>
<body>
<h1>Test Get Customer</h1>
<p>
<?php
echo $customerOne->getUserTitle()." #". $customerOne->getUserId() ."'s First name is ". $customerOne->getUserFirstName() ." and Last name is ". $customerOne->getUserLastName() ."<br/>";
echo $customerTwo->getUserTitle()." #". $customerTwo->getUserId() ."'s First name is ". $customerTwo->getUserFirstName() ." and Last name is ". $customerTwo->getUserLastName() ."<br/>";
?>
</p>
<h1>Test Get Employee</h1>
<p>
<?php
echo $employeeOne->getUserTitle()." #". $employeeOne->getUserId() ."'s First name is ". $employeeOne->getUserFirstName() ." and Last name is ". $employeeOne->getUserLastName() ."<br/>";
?>
</p>
<h1>Storelist Foreach</h1>
<p>
<?php
$listtest = $list->buildList();
echo $listtest;
?>
</p>
Customerclass.php:
class Customer extends User
{
public function userSayHi()
{
return "Hello , could i get some help?";
}
}
Employeeclass.php:
<?php
class Employee extends User
{
public function userSayHi()
{
return 'Hello , how may i help u?';
}
}
Userclass.php
<?php
abstract class User
{
protected $userId;
protected $userFirstName;
protected $userLastName;
protected $userTitle;
public function __construct($id, $firstName, $lastName, $title)
{
$this->userId = $id;
$this->userFirstName = $firstName;
$this->userLastName = $lastName;
$this->userTitle = $title;
}
//Gets
public function getUserId()
{
return $this->userId;
}
public function getUserFirstName()
{
return $this->userFirstName;
}
public function getUserLastName()
{
return $this->userLastName;
}
public function getUserTitle()
{
return $this->userTitle;
}
//Sets
public function setUserId($uId)
{
$this->userId = $uId;
}
public function setUserFirstName($ufirstName)
{
$this->userFirstName = $ufirstName;
}
public function setUserLastName($ulastName)
{
$this->userLastName = $ulastName;
}
public function setUserTitle($uTitle)
{
$this->userTitle = $uTitle;
}
public abstract function userSayHi();
}
Storelistclass.php
<?php
require_once("Customerclass.php");
require_once("Employeeclass.php");
class Storelist
{
public $storeArray = [];
public function __construct(Employee $employee)
{
array_push($this->storeArray, $employee);
}
public function addCustomer(Customer $customer)
{
array_push($this->storeArray, $customer);
//return $this->storeArray;
}
public function buildList()
{
foreach($this->storeArray as $storeData)
{
echo "First Name: ".$storeData->getUserFirstName()."<br/>";
echo "Last Name: ".$storeData->getUserLastName()."<br/>";
echo "Is a: ".$storeData->getUserTitle()."<br/>";
echo "<br/>";
}
/*
//ERROR : Cannot access protected property Employee::$userFirstName
foreach($this->storeArray as $storeData)
{
echo "First Name: ".$storeData->userFirstName."<br/>";
echo "Last Name: ".$storeData->userLastName."<br/>";
echo "Is a: ".$storeData->userTitle."<br/>";
echo "<br/>";
}
*/
}
public function delete()
{
}
public function update()
{
}
}
解决方案是实际使用您费心定义的 getter 方法 (getUserWhatever()
)。通过使它们保持 protected
可见性,除了使用您定义的 setUserWhatever()
方法之外无法修改它们,因此您可以进行额外的验证(例如防止非空值)例如,对无效数据抛出异常。因此,它们不能像 public
属性那样从 class 外部直接可变是很有用的。
在您的 Storelist
class 中,您定义了 $storeArray
属性 具有 public
可见性,这意味着您可以在 [=] 之外阅读它52=] 在 index.php
中。由于您要向该数组添加 Employee
或 Customer
对象,因此这些对象仍可通过其在 $list->storeArray
上的数组键单独寻址。例如,要修改姓氏,您可以使用
// Set the 3rd user's last name
$list->storeArray[2]->setUserLastName('Jones');
同样,在 Storelist
class:
$this
也是可能的
// Inside Storelist
$this->storeArray[2]->setUserLastName('Jones');
因此,您对这些 classes 的布局已经基本步入正轨。我还可以建议一件事;因为您已经创建了通过方法调用将 Customer
或 Employee
对象添加到 Storelist::$storeArray
的方法,而不是直接修改数组:
// You're doing this:
$list = new Storelist($employeeOne);
$list->addCustomer($customerOne);
// And not this (directly modifying storeArray):
$list = new Storelist($employeeOne);
$list->storeArray[] = $customerOne
...然后考虑将 Storelist::$storeArray
定义为 protected
属性 以便您可以 仅 使用其 setter 方法。然后你还需要创建一个 getter 方法来 returns 数组。
class Storelist
{
// This becomes protected
protected $storeArray = [];
// So you need a getter:
public function getStoreArray()
{
return $this->storeArray;
}
// etc...
}
从index.php
修改数组之后,就不能再直接读取它的元素了。相反,你调用它的 getter 方法:
// You can't do this:
$list->storeArray[2]->setUserLastName('Jones');
// Instead do it via the getter:
$list->getStoreArray()[2]->setUserLastName('Jones');
(注意,上面的 ()[2]
语法需要 PHP 5.4+)