Настройка частной собственности в суперклассе из класса Child - PullRequest
0 голосов
/ 24 августа 2018

У меня есть следующие классы

  • Абстрактный класс утка
    Этот класс имеет flyBehavoir типа FlyBehavoir
    Функция для выполнения полета preformFly()
    Функция для установки flyBehavoir setFlyBrhavoir(FlyBehavoir $flyBehavoir)
  • Класс DonaldDuck расширяет Duck
    в этом классе, у меня есть метод __construct, внутри этого конструктора я создаю экземпляр newПоведение мухи FlyWithWings.

Проблема в том, что когда мне нужно изменить flyBehavoir во время выполнения с помощью метода setFlyBrhavoir() и установить его на FlyWithRocket, оно не меняется, пока flyBehavoir является частным, если я сделаю это общедоступным, он работает нормально.как я могу это сделать?

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

ниже моей попытки

 <?php

//abstract class that defines what it takes to be a duck
//inside Duck we will have $flyBehavoir object of FlyBehavoir Type 
abstract class Duck{
    private  $flyBehavoir; 

    public function preformFly(){
        $flyBehavoir.fly();
    }
    public function setFlyBehavoir(FlyBehavoir $flyBehavoir){
        $this->flyBehavoir =  $flyBehavoir;
    }
}

//creating type FlyBehavoir 
interface FlyBehavoir{
    function fly();
}

//this concrete class of type FlyBehavoir  this will provide our ducks with the functionality they need to fly
class FlyWithWings implements FlyBehavoir{
    public function fly(){
        echo "I am Flying with my own Wings<br>";
    }
}

//this concrete class of type FlyBehavoir  this will provide our ducks with the functionality they need to fly
class FlyWithRocket implements FlyBehavoir{
    public function fly(){
        echo "I am the fastest duck ever, see my rockets wings <br>";
    }
}


// creating our first duck and given it the ability to fly with wings
class DonaldDuck extends Duck{

    public function __construct(){
        $this->flyBehavoir =  new FlyWithWings;
    }

}


$donaldDuck = new DonaldDuck( ) ;

$donaldDuck->flyBehavoir->fly();
//changing behavoir in run time 
$donaldDuck->setFlyBehavoir(new FlyWithRocket);
$donaldDuck->flyBehavoir->fly();


Output
I am Flying with my own Wings
I am Flying with my own Wings

1 Ответ

0 голосов
/ 24 августа 2018

Свойство private недоступно в дочерних классах.

class DonaldDuck extends Duck {
    public function __construct(){
        $this->flyBehavoir = new FlyWithWings;
    }
}

Для всех намерений и целей этот класс формально вообще не объявляет flyBehaviour, поэтому $this->flyBehaviour в конструкторе создаетновая public недвижимость.Вы можете ясно видеть это при var_dump использовании объекта:

object(DonaldDuck)#1 (2) {
  ["flyBehavoir":"Duck":private]=>
  NULL
  ["flyBehavoir"]=>
  object(FlyWithWings)#2 (0) {
  }
}

Свойство private родителя является а) отдельным, б) private к нему и в) null, поскольку никто не установилэто еще.В противном случае вы также не сможете получить доступ к $donaldDuck->flyBehavoir->fly() из-за отсутствия класса!

Если у вас есть свойство private, вам нужно разрешить действовать только коду того же класса:

class DonaldDuck extends Duck {
    public function __construct(){
        $this->setFlyBehaviour(new FlyWithWings);
    }
}

$donaldDuck = new DonaldDuck();
$donaldDuck->setFlyBehavoir(new FlyWithRocket);
$donaldDuck->preformFly();

Это работает, как вы ожидаете, так как вы используете правильно привилегированные методы для доступа к свойству.Если вы хотите получить доступ к свойству непосредственно в дочерних классах, оно должно быть protected (что не позволит вам получить к нему доступ из-за пределов класса, однако для этого оно должно быть public).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...