@Artem0071
Безработный mr. Junior

Область видимости метода?

Есть рабочий код. Почему в классе C создаем объект класса B и мы можем обратиться к его методу a()? Ведь метод a - protected и должен быть виден только потомкам, а тут его можно вызвать как обычный public

Код:
<?php

abstract class A
{
	public function __construct()
    {
    }
    
    protected function a()
    {
        return 'a';
    }
}

class B extends A
{
	public function __construct()
    {
    }
}

class C extends A
{
	public function __construct()
    {
    }
    
    public function b()
    {
        return (new B())->a();
    }
}

var_dump((new C())->b());
  • Вопрос задан
  • 138 просмотров
Решения вопроса 2
Maksclub
@Maksclub Куратор тега PHP
maksfedorov.ru
В пхп классо-ориентированный дизайн —потому "внутри класса" доступно даже приватное состояние другого объекта, если у него тот же тип. То есть инкапсуляция в «схеме» объекта — в классе, а не у самого объекта

Пример:

class Bro {
     public function __construct(
           private string $name,
     ){}

     public function changeBro(Bro $bro) {
           $bro->name = 'я думал ты бро, а ты не бро';
     }
}

$maks = new Bro('Макс');
$roma = new Bro('Рома');

$roma->changeBro($maks);

// теперь у Макса имя другое :)


такая архитектура языка, объекты разные, а доступ есть
К слову, это удобная фича… можно сравнить с видимостью в контексте одного package в го :)

Ну а касательно иерархии типов вам выше накинули — ребёнок всегда является корректным родительским типом, это называю ковариативностью. Любой тигр — кошачьи, а кошачьи — животное, всегда — согласно иерархии типов
Ответ написан
Комментировать
@HellWalk
Все работает корректно.

Вы создали класс A с методом a() доступным только для потомков
Затем создали класс B наследующегося от A
Затем создали класс C наследующегося от A с публичным методом b(), к которому и обращаетесь извне. А уже внутри класса-наследника обращаетесь к protected-методу.

Ошибка будет, если попытаться сделать так:

var_dump((new B())->a());

Вне классов, т.е. после вашего var_dump((new C())->b());
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы