I have the following classes
- Abstract class duck
This class haveflyBehavoir
of typeFlyBehavoir
Function to perform flyingpreformFly()
Function to setflyBehavoir
setFlyBrhavoir(FlyBehavoir $flyBehavoir)
- Class DonaldDuck extends Duck
in this class, I have a__construct
method, inside this constructor, I instantiate new fly behaviorFlyWithWings
.
The problem is when I need to change flyBehavoir
in the runtime via setFlyBrhavoir()
method and set it to FlyWithRocket
it does not change as long as flyBehavoir
is private if I make it public it works fine. how can I do that?
thought that we can change any property in the superclass from the child class, as long as I access this private property vis setter.
below my attempt
//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
";
}
}
//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
";
}
}
// 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
Answer
A private
property is not accessible in child classes.
class DonaldDuck extends Duck {
public function __construct(){
$this->flyBehavoir = new FlyWithWings;
}
}
For all intents and purposes, this class does not formally declare flyBehaviour
at all, so $this->flyBehaviour
in the constructor creates a new public
property. You can see that clearly when var_dump
ing the object:
object(DonaldDuck)#1 (2) {
["flyBehavoir":"Duck":private]=>
NULL
["flyBehavoir"]=>
object(FlyWithWings)#2 (0) {
}
}
The parent's private
property is a) separate, b) private
to it and c) null
since nobody has set it yet. Otherwise it would also not be possible for you to access $donaldDuck->flyBehavoir->fly()
from without the class!
If you have a private
property, you need to only let code of the same class act on it:
class DonaldDuck extends Duck {
public function __construct(){
$this->setFlyBehaviour(new FlyWithWings);
}
}
$donaldDuck = new DonaldDuck();
$donaldDuck->setFlyBehavoir(new FlyWithRocket);
$donaldDuck->preformFly();
This works as you expect, since you're using the correctly privileged methods to access the property. If you want to access the property directly in child classes, it needs to be protected
(which then won't let you access it from outside the class though, it would have to be public
for that).
No comments:
Post a Comment