Php 从子类设置超类中的私有属性

Php 从子类设置超类中的私有属性,php,oop,Php,Oop,我有以下课程 抽象类duck 此类具有flyBehavoir类型的flyBehavoir 执行飞行的函数prefly() 用于设置flyBehavoir的函数 DonaldDuck类扩展Duck 在这个类中,我有一个\u构造方法,在这个构造函数中,我实例化了新的飞行行为FlyWithWings 问题是当我需要在运行时通过setFlyBrhavoir()方法更改flyBehavoir,并将其设置为FlyWithRocket只要flyBehavoir是私有的,它就不会更改,如果我将其公开,它工作

我有以下课程

  • 抽象类duck
    此类具有
    flyBehavoir
    类型的
    flyBehavoir

    执行飞行的函数
    prefly()

    用于设置flyBehavoir的函数
  • DonaldDuck类扩展Duck
    在这个类中,我有一个
    \u构造
    方法,在这个构造函数中,我实例化了新的飞行行为
    FlyWithWings
问题是当我需要在运行时通过
setFlyBrhavoir()
方法更改
flyBehavoir
,并将其设置为
FlyWithRocket
只要
flyBehavoir
是私有的,它就不会更改,如果我将其公开,它工作正常。我该怎么做

我们可以从子类更改超类中的任何属性,只要我访问这个私有属性vissetter

低于我的努力

 <?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

A
private
属性在子类中不可访问

class DonaldDuck extends Duck {
    public function __construct(){
        $this->flyBehavoir = new FlyWithWings;
    }
}
出于所有目的,此类根本没有正式声明
flyBehavior
,因此构造函数中的
$this->flyBehavior
将创建一个新的
public
属性。当
var\u dump
ing对象时,您可以清楚地看到:

object(DonaldDuck)#1 (2) {
  ["flyBehavoir":"Duck":private]=>
  NULL
  ["flyBehavoir"]=>
  object(FlyWithWings)#2 (0) {
  }
}
父级的
private
属性是a)单独的,b)它的
private
属性和c)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();

这与您期望的一样,因为您使用的是正确的特权方法来访问属性。如果您想直接在子类中访问该属性,它需要受到
保护
(这样就不允许您从类外访问它,因此它必须是
公共

在子类中无法访问
私有
属性

class DonaldDuck extends Duck {
    public function __construct(){
        $this->flyBehavoir = new FlyWithWings;
    }
}
出于所有目的,此类根本没有正式声明
flyBehavior
,因此构造函数中的
$this->flyBehavior
将创建一个新的
public
属性。当
var\u dump
ing对象时,您可以清楚地看到:

object(DonaldDuck)#1 (2) {
  ["flyBehavoir":"Duck":private]=>
  NULL
  ["flyBehavoir"]=>
  object(FlyWithWings)#2 (0) {
  }
}
父级的
private
属性是a)单独的,b)它的
private
属性和c)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();

这与您期望的一样,因为您使用的是正确的特权方法来访问属性。如果您想直接在子类中访问该属性,它需要受到
保护
(这样就不允许您从类外访问它,因此它必须是
公共的

除非我误解了这个问题,您已经在问题中提到了解决方案:您需要使用setter而不是直接访问属性。这就是
private
的意思…您希望
受保护
而不是。请使用public/protected而不是private。jeroen我正在使用setter如果您检查代码,deceze protected会给出另一个错误(!)致命错误:未捕获错误:无法访问第48行/home/yazfarqj/dev/headFirstDesignPatrenBook/ch1/duck3.php中的受保护属性DonaldDuck::$flyBehavoir,除非我误解了问题,您已经在问题中提到了解决方案:您需要使用setter而不是直接访问属性。这就是
private
的意思…您希望
受保护
而不是。请使用public/protected而不是private。jeroen我正在使用setter如果您检查代码,deceze protected会给出另一个错误(!)致命错误:未捕获错误:无法访问受保护的属性DonaldDuck::$flyBehavoir in/home/yazfarqj/dev/headFirstDesignPatrenBook/ch1/duck3.php第48行惊人清晰的解释先生非常感谢现在像水晶一样清晰。惊人清晰的解释先生非常感谢现在像水晶一样清晰。