Чат PHP-разработчиков
Инкапсуляция в PHP

Инкапсуляция в PHP

В этом уроке мы узнаем о первом из трёх китов ООП - инкапсуляции. Инкапсуляция (лат. in capsula; от capsula «коробочка») — размещение в оболочке, изоляция, закрытие чего-либо с целью исключения влияния на окружающее. О том, как это используется в объектно-ориентированном программировании, вы узнаете по ходу этого урока.

Свойства объектов

Вернёмся к нашей прошлой теме. Те, кто видел котиков, знают, что некоторые признаки у котиков отличаются: цвет, вес, громкость мяуканья и т.д. Такие признаки есть у всех объектов, в том числе и в наших. И в ООП они называются свойствами объектов. Давайте приведем примеры таких свойств для котиков:

  • имя;
  • цвет;
  • вес.

Давайте теперь создадим более похожий на реального котика класс:

Код доступен только после покупки курса ООП в PHP.

Всё это: $name, $color, $weight - свойства будущих объектов этого класса. Перед именем свойства всегда ставится модификатор доступа. В нашем случае - это public. Это слово говорит о том, что данное свойство будет доступно всем, кто работает с объектами данного класса. Есть и другие модификаторы доступа, но о них чуть ниже.

И снова сам по себе этот код сейчас ничего не выведет. Это опять - просто шаблон.

Итак, мы сделали некоторый шаблон, который вполне себе описывает котиков. Давайте теперь создадим новый объект этого класса.

Код доступен только после покупки курса ООП в PHP.

Так мы создали объект с типом Cat и вывели его с помощью var_dump().

Код доступен только после покупки курса ООП в PHP.

Как видим, в переменной лежит объект (object), и у него есть три свойства, и у всех значения - null. Давайте это исправим. Дадим нашему котику имя, покрасим и наполним его чем-нибудь, чтобы он сколько-нибудь весил. Делается это так:

Код доступен только после покупки курса ООП в PHP.

Оператор -> (стрелочка, состоящая из двух знаков - "тире" и "больше") используется для доступа к свойствам объекта. В данном коде мы обратились к каждому свойству отдельно и присвоили им значения. Если теперь мы выведем $cat1 с помощью var_dump(), то получим следующее:

Код доступен только после покупки курса ООП в PHP.

Как видим, это уже не ерунда какая-то, а белый Снежок, который весит три с половиной кило.

Теперь мы можем обратиться к свойству этого кота и узнать его имя.

Код доступен только после покупки курса ООП в PHP.

И получим в результате "Снежок".

Можем создать несколько котов и задать им разные свойства:

Код доступен только после покупки курса ООП в PHP.

Результат получится вполне ожидаемый:

Код доступен только после покупки курса ООП в PHP.

Два разных объекта со своими значениями свойств.

Это довольно похоже на работу с массивами, как будто записываем значение по ключу.

То, что внутри объектов есть свойства - это уже проявление инкапсуляции. У объекта есть свойства, он их внутри себя содержит - вот и "капсула".

Методы объектов

Но одними только свойствами объекты не ограничиваются. Они могут иметь методы - это функции, принадлежащие конкретным объектам. Их мы описываем внутри класса, после чего эти функции становятся связаны с объектами этого класса.

Методы объявляются следующим образом:

Код доступен только после покупки курса ООП в PHP.

public - модификатор доступа к методу, говорящий о том, что его могут вызвать все, кто пользуется объектом, sayHello - имя метода, а далее идут аргументы (в нашем случае их нет), а далее - тело метода, в котором мы просто выводим строку 'Мяу!';

Как мы видим, в целом методы объектов не сильно отличаются от обычных функций. При их описании мы только добавляем модификатор доступа.

Вызвать метод мы можем у созданного объекта. Давайте создадим нового кота и попросим его с нами поздороваться. Для вызова метода объекта используется такой же оператор как и для доступа к свойствам объекта ->

Код доступен только после покупки курса ООП в PHP.

Этот код выведет строку 'Мяу!'. Вот так вот, с нами поздоровался виртуальный кот!

Переменная $this

Да только методы - это не такие уж и простые функции. Внутри методов доступна специальная переменная $this, и в ней хранится... наш текущий созданный объект. БДЫЩЬ! Мозг взорвался :)

На деле всё не так уж и сложно. Мы можем с помощью этой переменной обращаться к другим методам и свойствам данного объекта. Например, давайте научим кота здороваться по-человечески. Пусть он будет называть своё имя. Для этого нам нужно переписать метод sayHello() следующим образом:

Код доступен только после покупки курса ООП в PHP.

И теперь, когда мы создадим новый объект кота, и попросим его с нами поздороваться, то $this->name вернёт значение свойства name у текущего объекта.

Код доступен только после покупки курса ООП в PHP.

Данный код выведет следующее:

Код доступен только после покупки курса ООП в PHP.

Вот так всё просто. Надеюсь, этот наглядный пример помог вам понять, что $this - это просто текущий объект, и что $this есть только у созданного объекта.

И методы, и переменная $this - тоже инкапсуляция! Но и на этом ещё не всё :)

Модификаторы доступа

Сейчас у нас с вами все свойства и методы объектов являются публичными - из любого места в коде, где этот объект доступен, мы можем получить доступ к этим свойствам и методам. Для того чтобы сделать свойство или метод публичным используется ключевое слово public.

Однако, есть и другие модификаторы доступа, и в этом уроке мы с вами изучим ещё один модификатор - private. Он позволяет сделать свойства и методы объекта приватными, после этого они будут доступны только внутри этого объекта.

Например, давайте изменим модификатор для свойства name:

Код доступен только после покупки курса ООП в PHP.

Давайте теперь попытаемся изменить это свойство у объекта:

Код доступен только после покупки курса ООП в PHP.

Мы получим ошибку:
Ошибка при попытке доступа к приватному свойству

Однако, мы можем написать публичный метод, который позволит задать данное свойство с помощью него. Назовём его setName(). Он будет брать переданную в него строку и устанавливать это значение в свойство name.

Код доступен только после покупки курса ООП в PHP.

Теперь давайте зададим имя коту с помощью этого метода:

Код доступен только после покупки курса ООП в PHP.

Теперь всё успешно отработало, и кот даже сказал своё имя с помощью метода sayHello(). Однако если бы мы попытались просто вывести его имя вот так:

Код доступен только после покупки курса ООП в PHP.

то мы бы снова получили ошибку доступа.

Как вы могли заметить с помощью метода setName мы позволяем задать в свойство name только строку. Ни число, ни массив, ни что-то ещё, а именно - строку. Это хороший подход - это позволяет использовать различного рода валидации. Ведь внутри метода вы можете выполнить какие-то проверки, прежде чем положить значение в свойство. Это позволяет избежать ситуаций, когда в свойства можно засунуть любую ерунду. Такие методы как setName(), задающие значения свойствам объекта называются сеттерами.

Чтобы получить напрямую значение приватного свойства у объекта можно написать другой публичный метод, который будет просто возвращать значение этого свойства. Напишем метод getName().

Код доступен только после покупки курса ООП в PHP.

Теперь мы можем просто получить имя кота извне:

Код доступен только после покупки курса ООП в PHP.

Такие методы, в свою очередь, именуются геттерами.

Модификаторы доступа - это ещё одно проявление инкапсуляции.

Конструктор

А теперь давайте возьмём и сломаем одного кота :)

Для этого мы не будем давать ему имя, и вызовем метод getName().

Код доступен только после покупки курса ООП в PHP.

Что произойдёт? Правильно - ошибка!

Ведь мы описали, что getName() всегда должна отдавать строку. А в нашем объекте возвращается null.

Можно ли как-то гарантировать, что в свойстве name всегда будет строка? Можно. Для этого существует конструктор - это метод, который вызывается при создании объекта этого класса. В принципе, это такой же метод, как и все другие, он может иметь различные аргументы. Но он обязательно вызывается автоматически при создании объекта класса, в котором он описан.

Метод-конструктор должен называться __construct. Именно так и никак иначе.

Давайте создадим конструктор для нашего кота, который будет иметь обязательный аргумент $name с типом строка.

Код доступен только после покупки курса ООП в PHP.

Конструктор принято объявлять в начале класса, после объявления свойств, но перед другими методами.

Теперь чтобы создать кота с именем Снежок мы должны передать аргумент при создании нового объекта:

Код доступен только после покупки курса ООП в PHP.

И вот что сейчас произошло: аргумент, переданный в круглые скобки, был передан в метод __construct(). Там это значение установилось в свойство объекта name.

Если мы сейчас попробуем узнать имя этого кота, то мы его получим.

Код доступен только после покупки курса ООП в PHP.

А давайте теперь мы попробуем по-старинке создать кота без имени, не передавая аргументов при создании объекта.

Код доступен только после покупки курса ООП в PHP.

Мы получим ошибку.
Ошибка об отсутствии нужного количества аргументов конструктора

Здесь написано, что в конструкторе ожидается 1 обязательный аргумент, а мы не передали ни одного.

Таким образом, мы получили класс котов, объекты которого нельзя создать без имени. И именно так и должно быть в мире - у всех котиков должны быть имена. Согласитесь, такой мир был бы гораздо лучше чем тот, в котором мы живём. Ну так вот в программировании, мы способны построить такие миры, какие сами пожелаем. И это круто :)

Подводя итог, можно сказать что инкапсуляция - это возможность объектов содержать в себе свойства и методы. Так мы делаем их зависимыми друг от друга внутри этой "капсулы".

Это был первый кит ООП - инкапсуляция. До встречи на следующем уроке, а пока за домашку.

Домашнее задание
  • Дополните метод sayHello(), чтобы котики после того, как назвали своё имя, говорили о том, какого они цвета.
  • Сделайте свойство color приватным и добавьте в конструктор ещё один аргумент, через который при создании котика будет задаваться его цвет.
  • Сделайте геттер, который будет позволять получить свойство color.
  • Подумайте, стоит ли давать возможность менять котикам цвета после их создания? Если вам хватило совести сказать да - добавьте ещё и сеттер для этого свойства. Это вам в наказание - хорошие люди котов не перекрашивают.
  • Создайте теперь белого Снежка и рыжего Барсика и попросите их рассказать о себе.
Читайте также
Комментарии (50)


SlipKnot

Домашка:

<?php

class Cat
{
    private $name;
    private $color;
    public $weight;
    public function __construct (string $name, string $color) /*теперь при создании нового кота
                                                                мы должны указать имя и цвет*/
    {
        $this->name = $name;
        $this->color = $color;
    }
    public function sayHello()
    {
    echo 'Дратути, меня зовут ' . $this->name . ', моя шерстка цвета ' . $this->color . '<br>';
    } /* дополнение к методу приветствия */
    public function setName(string $name)
    {
        $this-> name = $name;
    }
    public function setColor(string $color) //метод для присвоения цвета шерсти кота
    {
        $this-> color = $color;
    }
    public function  getName():string
    {
        return $this->name;
    }
    public function getColor():string // получаем значения цвета шерсти
    {
        return $this->color;
    }
}
$cat1 = new Cat('Снежок', 'белый');
$cat1-> sayHello(); //Дратути, меня зовут Снег, моя шерстка цвета белый
$cat1-> setName('Снег');
$cat1->setColor('серый');
$cat2 = new Cat ('Барсик', 'рыжий');
$cat2->sayHello(); //Дратути, меня зовут Барсик, моя шерстка цвета рыжий
$cat1->sayHello(); //Дратути, меня зовут Снег, моя шерстка цвета серый
ivashkevich

Отлично! Всё-таки перекрасили :D

Galay
<?php
class Cat 
    {
        private $name;
        private $color;
        public function __construct(string $name, string $color){
            $this->name = $name;
            $this->color = $color;
        }

        public function sayHello() {
            echo "Привет, меня зовут {$this->name}, мой цвет - $this->color.";
        }
        public function getColor(): string {
            return $this->color;
        }
        public function setColor(string $color) {
             $this->color = $color;
        }

    }
    $cat1 = new Cat('Барсик','рыжий');
    // $cat1 -> name = 'Барсик';
    // $cat1 -> color = 'рыжий';
    echo '<br>';
    echo $cat1->sayHello();
    $cat2 = new Cat('Снежок','белый');
    // $cat1 -> name = 'Снежок';
    // $cat1 -> color = 'белый';
    echo '<br>';
    echo $cat2->sayHello();
    echo '<br>';
    $cat1->setColor('черный');
    echo $cat1->getColor();

и еще ругается на public function getColor(): string
Parse error: syntax error, unexpected ':', expecting ';' or '{' in codetester_source.php on line 14
а другой сервер не ругается. Почему?

ivashkevich

Там где ругается - старая версия PHP.

echo $cat1->sayHello();

Вы тут вызываете echo, и внутри метода вызываете echo. Либо в методе возвращайте строку через return, либо тут не нужно делать echo, и оставить его только внутри метода.

Galay

Странно, я тоже подумал версия старая, но проверил - 7.2
Вобщем не понятно, ну да ладно.. Про echo понял, действительно. Видимо не серьезная ошибка, интерпритатор не ругается.
Артем, а на ООП мало кто домашку в ответах выкладывает?

ivashkevich

Да, пока мало кто выкладывает, только-только начали покупать вообще)

g--nokoder

Домашка


<?php
    Class Cat{
        private $name;
        private $color;
        public $weight;

        public function __construct($name, $color){
            $this->name = $name;
            $this->color = $color;
            return $this;
        }

        public function setName($name){
            $this->name = $name;
        }
        public function getName($name){
            $this->name = $name;
            return $this->name;
        }

        public function getColor($color){
            $this->color = $color;
            return $this->color;
        }
        public function sayHello(){
            echo "Привет! Меня зовут ".$this->name." и мой цвет ".$this->color." и мой вес ".$this->weight."<br>";
        }
    }

    $cat1 = new Cat("Снежок", "белый");
    $cat1->weight = "3 кг";

    $cat2 = new Cat("Барсик", "рыжый");
    $cat2->weight = "3,5 кг";

    echo $cat1->sayHello();
    echo $cat2->sayHello();
?>
ivashkevich
  1. Перед аргументами методов нужно указывать их тип.
  2. return в конструкторе не нужен.
  3. Геттеры не должны ничего изменять у объекта, в нашем случае даже не должны принимать никаких аргументов.
  4. Свойство weight стоит тоже сделать приватным и задаваться через сеттер, а доступ извне должен обеспечиваться через геттер.
computerix
<?php
class Cat
{
    private $name;
    private $color;

    public function __construct(string $name, string $color)
    {
        $this->name = $name;
        $this->color = $color;
    }

    public function sayHello()
    {
        echo 'Привет! Меня зовут ' . $this->name . ',' . 'Мой цвет '. $this->color . '.';
    }

    public function setName(string $name)
    {
        $this->name = $name;
    }

    public function setColor(string $color)
    {
        $this->color = $color;
    }

    public function getName(): string
    {
        return $this->name;
    }

    public function getColor(): string
    {
        return $this->color;
    }
}
$cat1 = new Cat('Снежок','белый');
$cat1->sayHello(); 
$cat2 = new Cat('Барсик','рыжий');
$cat2->sayHello();
?>
ArtemijeKA

Случайно два сообщения написал) ДЗ:

ArtemijeKA

1

public function sayHello()
    {
        echo 'Привет! Меня зовут ' . $this->name . '.';
        echo '<br>';
        echo 'Мой цвет ' . $this->color . ').';
    }

2

public function __construct(string $name, string $color)
    {
        $this->name = $name;
        $this->color = $color;
    }

3

public function getColor(): string // возвращяемое значение будет строкой
    {
        return $this->color;
    }

4

*Не думаю что стоит)*

5

$cat1 = new Cat('Снежок', 'белый');
$cat2 = new Cat('Барсик', 'рыжий');

$cat1->sayHello();
$cat2->sayHello();

6 Спасибо!

jeeree
class Cat
{
    public function __construct(string $name, $color, float $weight)
    {
        $this->name = $name;
        $this->color = $color;
        $this->weight = $weight;
    }
    private $name;
    private $color;
    private $weight;

    public function sayHello()
    {
        echo 'Дароу! My name is ' . $this->name . ', i have ' .
            $this->color . ' color and i weight ' . $this->weight . ' kilograms.','<br>';
    }
    public function setName(string $name)
    {
        $this->name = $name;
    }
    public function setColor(string $color)
    {
        $this->color = $color;
    }
    public function setWeight(float $weight)
    {
        $this->weight = $weight;
    }
    public function getName(): string
    {
        return $this->name;
    }
    public function getColor(): string
    {
        return $this->color;
    }public function getWeight(): float
{
    return $this->weight;
}
}
$cat1 = new Cat('Тупой и пакостный ИШАК', 'white', "5.3");
$cat1->sayHello();
jeeree

все таки не совсем врубаюсь зачем мы прописывали сеттеры и геттеры, если все параметры задаются через конструктор, и для чего их можно использовать
пойду дальше по курсу, мб позже до меня дойдёт)

ArtemijeKA

Для того чтобы потом в дальнейшем через эти методы получать и задавать новые значения. Сеттеры как правило содержат в себе всяческие обработчики и валидаторы для новых значений, что бы не Бог весь что туда не засунулось - как-то так вроде. В геттерах тоже данные наверно как-то обрабатывать можно в зависимости от заданных аргументов геттеру.

ivashkevich

Все верно =)

DmitryGavrilov
<?php

class Cat {
    private $name;
    private $color;

    public function __construct(string $name, string $color) {

        $this->name = $name;
        $this->color = $color;
    }

    public function SayHello(){
        echo 'Привет! Меня зовут ' . $this->name . '.' . '<br>' . 'мой цвет ' . $this->color . '.';

    }

    public function setName(string $name) {
        $this->name = $name;
    }

    public function setColor (string $color) {
        $this->color = $color;
    }

    public function getName(): string {
        return $this->name;

    }

    public function getColor() : string  {
        return $this->color;
    }
}

$cat1 = new Cat('Маленький пушистый монстр', 'Ультрамарин');
$cat1->setName('Пушистый монстр');
$cat1->setColor('Ультрафиолетовый');
echo  $cat1->SayHello();

?>
ivashkevich

Супер! Только имена методов всегда с маленькой буквы.

DmitryGavrilov

Будет сделано Джеди-Мастер

Benya
<?php

class Cat
{
    private $name;
    private $color;

    public function __construct(string $name, string $color)
    {
        $this->name = $name;
        $this->color = $color;
    }

    public function sayHello()
    {
        echo 'Привет! Меня зовут ' . $this->name . ','  . ' у меня  ' . $this->color . ' цвет' . '<br>';
    }

    public function setName(string $name)
    {
        $this->name = $name;
    }

    public function setColor(string $color)
    {
        $this->color = $color;
    }

    public function getName(): string
    {
        return $this->name;
    }

    public function getColor(): string
    {
        return $this->color;
    }
}

$cat1 = new Cat('Буся', 'желтый');
$cat1->sayHello();
$cat1 = new Cat('Снежек', 'белый');
$cat1->sayHello();
$cat1 = new Cat('Барсик', 'рыжый');
$cat1->sayHello();
SBTesla
<?php

class Cat {

     private $name;
     private $color;
     private $weight;

     public  function __construct(string $name, string $color, string $weight){
          $this ->name = $name;
          $this -> color = $color;
          $this -> weight = $weight;
     }

     public function sayHello () {
          echo 'Превет! меня зовут ' . $this -> name . ' моя шерстка  ' . $this -> color . ' и  вешу я столько: ' . $this ->weight . '<br>';
     }
     public function  setName(string $name)
     {
          $this ->name = $name;
     }
     public function setColor(string $color)
     {
          $this->color = $color;
     }
     public function setWeight(float $weight)
     {
          $this->weight = $weight;
     }

     public function getName():string {
          return $this -> name;
     }
     public function getColor():string
     {
          return $this-> color;
     }
     public function getWeight():float
     {
          return $this-> weight;
     }

}
// создаем первый обьект
$cat1 = new Cat ('снежок', 'белый', '10');
$cat1->sayHello();
// создаем 2 обьект
$cat2 = new Cat('барсик', 'синий', '20');
$cat2->sayHello();

поправил

ivashkevich

Потому что название конструктора начинается с двух подчеркиваний. Замечания:

  1. Слишком много очевидных комментариев.
  2. Коммент "передаем в обьект нужные нам параметры" не имеет никакого отношения к коду, над которым он написан
  3. Коммент "пердаем в параметр обьектов строку с свойствами" вообще бессмысленный - у объектов есть свойства, в которые можно что-то присвоить. У них нет никаких параметров.
  4. Коммент "получаем напрямую свойства приватного обьекта" - не бывает никаких приватных объектов! Где вы взяли эти формулировки?
  5. Конструкции вида $x->y не должны иметь никаких пробелов!
EWA

Конструктор котиков)

<html>
<head>
<title>Конструктор котиков</title>
<body>
<h2>Соберите котика</h2>
<form action="index.php" method="post">

<label>Кот 1 </label><select name="cat1">
<option value="Tuzik">Tuzik</option>
<option value="Barsik">Barsik</option>
<option value="Snejok">Snejok</option>
</select>
<select name="color1">
<option value="Белый">Белый</option>
<option value="Черный">Черный</option>
<option value="Желтый">Желтый</option>
</select>

<br><br>

<label>Кот 2 </label><select name="cat2">
<option value="Tuzik">Tuzik</option>
<option value="Barsik">Barsik</option>
<option value="Snejok">Snejok</option>
</select>
<select name="color2">
<option value="Белый">Белый</option>
<option value="Черный">Черный</option>
<option value="Желтый">Желтый</option>
</select>
<input type="submit" value="С О Б Р А Т Ь">
</form>
</body>
</head>
</html>
<?php
class Cat
{
private $name;
private $color;
public function __construct(string $name, string $color)
{
    $this->name = $name;
    $this->color = $color;
}
 public function sayHello()
    {
        echo 'Привет! Меня зовут ' . $this->name . ' и мой цвет ' . $this->color . '.';
    }
public function getName()
    {
        return $this->name;
    }
    public function getColor()
    {
        return $this->color;
    }

}
if($_POST){
$cat1 = new Cat($_POST['cat1'], $_POST['color1']);
$cat1-> sayHello();
echo '<br>';
$cat2 = new cat($_POST['cat2'], $_POST['color2']);
$cat2-> sayHello();
}
?>
ivashkevich

Хорошо, только значения по-умолчанию в классе не имеют смысла - они переопределяются сразу при создании объекта в конструкторе. У аргументов конструктора должны быть типы.

EWA

Спасибки. Подправил.

zebra

Домашка:

<?php 
class Cat {
    private $name;
    private $color;

    public function __construct(string $name, string $color) {
        $this->name = $name;
        $this->color = $color;  
    }

    public function sayHello() {
        echo 'Привет! Меня зовут ' . $this->name . ' ' . 'и мой цвет ' . $this->color;
    }

    public function setName(string $name) {
        $this->name = $name;
    }

    public function setColor(string $color) {
        $this->color = $color;
    }

    public function getName(): string { //явное указание типа возвращаемого значения
        return $this->name;
    }

    public function getColor(): string {
        return $this->color;
    }
}
$cat1 = new Cat('Снежок', 'белый');
$cat2 = new Cat('Барсик', 'рыжий');

$cat1->sayHello();
echo '<br>';
$cat2->sayHello();
// echo $cat1->getName();

?>
ivashkevich

Отличная домашка!
P.S. В PHP принято открывающую скобку тела функции переносить на следующую строку.

function func(): void
{ // вот сюда
Todd
<?php
class Cat {
    private $name;
    private $color;

    public function __construct(string $name, string $color) {
        $this->name = $name;
        $this->color = $color;
    }

    public function sayHello() {
        echo 'Привет! Меня зовут ' . $this->name . '. Мой цвет ' . $this->color . ' !';
    }

    public function setName(string $name) {
        $this->name = $name;
    }

    public function getName(): string {
        return $this->name;
    }

    public function setColor(string $color) {
        $this->color = $color;
    }

    public function getColor(): string {
        return $this->color;
    }
}

$cat1 = new Cat('Снежок', 'белый');
$cat2 = new Cat('Барсик', 'рыжий');

echo $cat1->sayHello();
echo $cat2->sayHello();
?>
ivashkevich

Хорошо. Для функций, которые ничего не возвращают стоит указывать return-type void. Открывающая скобка тела функции переносится на следующую строку (смотрите комментарий выше).

argon2i

Для функций, которые ничего не возвращают стоит указывать return-type void.
Это для каких конкретно?

ivashkevich

У которых после return ничего нет, либо у которых вообще отсутствует return =)

Moskva

Очень похоже на ООП из С++, помню в университете проходили целый семестр классы, были некоторые вопросы не понятны, сейчас вроде стало намного понятнее с геттерами и сеттерами.

<?php   
    class Cat // создание класса кот
    {
        private $name; 
        private $color;
        public $weight;
        //конструктур принято объявлять в начале класса
        public function __construct(string $name, string $color)
        {
            $this->name = $name;
            $this->color = $color;
        }
        public function sayHi()
        {
            echo 'Привет! Меня зовут ' . $this->name . ', ' .'моя шерсть цвета: '.  $this->color . '.' . '<br>';
        }
        public function setName(string $name)
        {
            $this->name = $name;
        }
        public function getName(): string
        {
            return $this->name;
        }
        public function setColor(string $color)
        {
            $this->color = $color;
        }
        public function getColor(): string
        {
            return $this->color;
        }

    }
    $cat1 = new Cat('Снежок', 'белый');
    $cat1->setName('Снежок'); //можем изменить значение
    $cat1->setColor('Черный'); //можем изменить значение
    $cat1->sayHi();

    $cat2 = new Cat('Барсик', 'Рыжий');
    $cat2->setName('Котяра'); //можем изменить значение
    $cat2->setColor('Белый'); //можем изменить значение
    $cat2->sayHi();

 ?>
ivashkevich

Хорошо, но public $weight; - лишнее.

demyanovpaul@yandex.ru

Дополните метод sayHello(), чтобы котики после того, как назвали своё имя, говорили о том, какого они цвета.
Сделайте свойство color приватным и добавьте в конструктор ещё один аргумент, через который при создании котика будет задаваться его цвет.
Сделайте геттер, который будет позволять получить свойство color.
Подумайте, стоит ли давать возможность менять котикам цвета после их создания? Если вам хватило совести сказать да - добавьте ещё и сеттер для этого свойства. Это вам в наказание - хорошие люди котов не перекрашивают.
Создайте теперь белого Снежка и рыжего Барсика и попросите их рассказать о себе.

<?php
class Cat
{
    private $name;
    private $color;
    private $weight;

    public function __construct(string $name, string $color, string $weight)
    {
        $this->name = $name;
        $this->color = $color;
        $this->weight = $weight;
    }

    public function sayHello()
    {
        echo 'Привет! Меня зовут, ' . $this->name . '.<br>';
        echo 'У меня цвет ' . $this->color . '.<br>';
        echo 'Я вешу ' . $this->weight . '.<br>';
    }

    public function setName(string $name)
    {
        $this->name = $name;
    }

    public function getName(): string
    {
        return $this->name;
    }

    public function setColor(string $color)
    {
        $this->color = $color;
    }

    public function getColor(): string
    {
        return $this->color;
    }

    public function setWeight(float $weight)
    {
        $this->weight = $weight;
    }

    public function getWeight(): float
    {
        return $this->weight;
    }
}

$cat = new Cat('Снежок', 'white', 3.5);
$cat->sayHello();

$cat2 = new Cat('Барсик', 'red', 6.2);
$cat2->sayHello();
bildep
<?php

class Cat
{
    private $name;
    private $color;
    public $weight;

    public function __construct(string $name, string $color)
    {
        $this->name = $name;
        $this->color =$color;
    }

    public function sayHello()
    {
        echo 'Привет! Меня зовут ' . $this->name . '.';
        echo ' Мой цвет ' . $this->color . '.';
    }

    public function setName(string $name)
    {
        $this->name = $name;
    }

    public function getName(): string
    {
        return $this->name;
    }

    public function getColor(): string
    {
        return $this->color;
    }
}

$cat1 = new Cat('Снежок', 'белый');
$cat1->sayHello();

$cat2 = new Cat('Барсик', 'рыжий');
$cat2->sayHello();
ilyaOrlov
<?php
class Cat {
    private $name;
    private $color;
    public $weight;
    public function __construct(string $name, string $color) {
        $this -> name = $name;
        $this -> color = $color;
    }
    public function sayHello() {
        if ((substr($this -> color, -4, 2)) == 'ы') {
            $i = 'ого';
        } elseif ((substr($this -> color, -4, 2)) == 'и') {
            $i = 'его';
        }
        echo 'Привет! Меня зовут ' . $this -> name . '! И я ' . substr($this -> color, 0, -4) . $i . ' цвета.';
    }
    public function setName(string $name) {
        $this -> name = $name;
    }
    public function getName(): string {
        return $this -> name;
    }
    public function setColor(string $color) {
        $this -> color = $color;
    }
    public function getColor(): string {
        return $this -> color;
    }
}
$cat1 = new Cat('Снежок', 'белый');
$cat2 = new Cat('Барсик', 'рыжий');
$cat1 -> sayHello(); // Привет! Меня зовут Снежок! И я белого цвета.
echo '<br>';
$cat2 -> sayHello(); // Привет! Меня зовут Барсик! И я рыжего цвета.
?>
ivashkevich

Отлично! Прочитайте еще про mb_substr и про utf-8 в PHP тогда сразу)

Waldemar

Что-то не пойму, как сюда вставить скан кода))
Пока вставлю текстом:

<?php

class Cat
{
    private $name;
    private $color;

    public function __construct(string $name, string $color)
    {
        $this->name = $name;
        $this->color = $color;
    }

    public function sayHello()
    {
        echo 'Привет! Меня зовут ' . $this->name . ' и мой цвет '. $this->color . '.<br>';
    }

    public function setName(string $name)
    {
        $this->name = $name;
    }

    public function getName(): string
    {
        return $this->name;
    }

    public function getColor(): string
    {
        return $this->color;
    }

}

$cat1 = new Cat('Снежок', 'белый');
$cat2 = new Cat('Барсик', 'рыжий');

$cat1->sayHello();
$cat2->sayHello();
ivashkevich

Всё отлично. Для методов, которые ничего не возвращают лучше указывать тип :void. Для форматирования кода используйте самую первую кнопку в редакторе комментария.

Waldemar

Про void немного непонятно. В моём примере у каких методов надо его добавить?

ivashkevich

setName или sayHello - методы, у которых после return ничего не указано, или вообще отсутствует return.

Pavel-Tonk
<?php 
class Cat {
    private $name;
    private $color;
    private $age;
    public function __construct(string $name, string $color, string $age = '11.12.18') 
    {
        $this->name = $name;
        $this->color = $color;
        $this->age = $age;
    }
    public function setName(string $name):void 
    {
        $this->name = $name;
    }
    public function setColor(string $name):void 
    {
        $this->color = $color;
    }
    public function getName():string 
    {
        return $this->name;
    }
    public function getColor():string 
    {
        return $this->color;
    }
    public function getAge():string 
    {
        return $this->age;
    }
    public function sayHello():void
    {
        echo '<p>Мяу! Меня зовут - '.$this->name.'. Мой окрас - '.$this->color.'. Я родился - '.$this->age.'</p>';
    }
}
$cat1 = new Cat('Барсик','рыжий',date("d.m.Y"));
$cat1->sayHello();
$cat2 = new Cat('Cнежок','белый', date("d.M.y", mktime(0, 0, 0, 12, 10, 2018)));
$cat2->sayHello();

Решил вместо массы использовать дату рождения. У меня пара вопросов возникла после прочтения замечаний выше:

  1. Правильно ли я использовал :void?
  2. Нужен ли :void для конструктора?
  3. У меня не получилось записать дефолтное значение аргументу конструктора $age = date("d.m.Y"). Это потому что я не так делаю или так априори синтаксис не позволяет?
ivashkevich

Привет, все отлично.

  1. Да
  2. Для конструктора не нужно
  3. Синтаксис позволяет. Видимо, что-то не так делал.
lordbear53@gmail.com
<?php

class Cat
{
    private $name;
    private $color;
    public $weight;
    public function __construct (string $name, string $color)
    {
        $this->name = $name;
        $this->color = $color;
    }
    public function sayHello()
    {
        echo 'Хелоу, меня зовут ' . $this->name . ', как видишь мой цвет  ' . $this->color . '.' . '<br>';
    }
    public function setName(string $name)
    {
        $this-> name = $name;
    }
    public function setColor(string $color)
    {
        $this-> color = $color;
    }
    public function  getName():string
    {
        return $this->name;
    }
    public function getColor():string
    {
        return $this->color;
    }
}
$cat1 = new Cat('Снежок', 'белый');
$cat1-> sayHello();
$cat1-> setName('Трактор'); //Потомучто громко мурчит =)
$cat1->setColor('Черный');

$cat2 = new Cat ('Барсик', 'рыжий');
$cat2->sayHello();
$cat1->sayHello();
ivashkevich

Трактор так трактор) Отлично!

Популярное за сутки
Сейчас читают
Логические задачи с собеседований