PHP Abstract Class Array Защищенные свойства

Я немного новичок в использовании абстрактных классов и ООП, поэтому, пожалуйста, потерпите меня.
Я пытаюсь составить список сотрудников и клиентов, но у меня возникают проблемы с печатью массива объектов в моем классе StoreList, поскольку все они защищены.
То, что я хочу сделать, это распечатать значения в storeArray в красивый список.
Прямо сейчас он выводит все из класса Gets from Abstract, что делает массив устаревшим.
Я включу весь код ниже, но так как это довольно долго, я хотел бы задать вопрос здесь.
Это то, что массив выдает, когда я 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 общедоступными, все работает нормально, но тогда Gets устареет, верно?
Должен ли я просто оставить Gets и сделать их общедоступными, или есть другой способ?
Извините, если это своего рода глупый вопрос, но я действительно пытаюсь обернуть голову вокруг этого и терпеть неудачу в этом.

Любая помощь и советы (Также на обновление & удалить функции) будет очень признателен!

Это весь код, который у меня есть сейчас.

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()
{

}
}

2

Решение

Решение состоит в том, чтобы фактически использовать методы получения (getUserWhatever()) что вы пошли на проблему определения. Сохраняя их такими, какие они есть protected видимость, невозможно изменить их, кроме как с setUserWhatever() методы, которые вы определили, так что вы можете выполнить дополнительную проверку (например, предотвратить непустые значения) и выбросить исключения для недопустимых данных, например. Поэтому полезно, чтобы они не изменялись напрямую вне класса, так как public свойства будут.

В вашем Storelist класс, вы определили $storeArray собственность с public видимость, что означает, что вы можете прочитать его вне класса в index.php, Так как вы добавляете Employee или же Customer объекты в этом массиве, эти объекты по-прежнему индивидуально адресуются своими ключами массива на $list->storeArray, Например, чтобы изменить фамилию, вы можете использовать

// Set the 3rd user's last name
$list->storeArray[2]->setUserLastName('Jones');

Точно так же возможно использование $this внутри Storelist учебный класс:

// Inside Storelist
$this->storeArray[2]->setUserLastName('Jones');

Так что вы уже в значительной степени на ходу с расположением этих классов. Есть еще одна вещь, которую я мог бы предложить; так как вы уже создали методы для добавления 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 свойство, так что вы можете только напишите ему с его методами установки. Затем вам также необходимо создать метод получения, который возвращает массив.

class Storelist
{
// This becomes protected
protected $storeArray = [];

// So you need a getter:
public function getStoreArray()
{
return $this->storeArray;
}
// etc...
}

Чтобы изменить массив из index.php тогда вы больше не можете напрямую читать его элементы. Вместо этого вы вызываете его метод получения:

// 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+)

0

Другие решения

Других решений пока нет …