【问题标题】:Setting private property in super Class from Child class从子类设置超类中的私有属性
【发布时间】:2019-01-30 22:04:49
【问题描述】:

我有以下课程

  • 抽象类鸭子
    此类具有 flyBehavoir 类型的 FlyBehavoir
    执行飞行的功能preformFly()
    设置flyBehavoirsetFlyBrhavoir(FlyBehavoir $flyBehavoir)的函数
  • 类 DonaldDuck 扩展了 Duck
    在这个类中,我有一个__construct 方法,在这个构造函数中,我实例化了新的飞行行为FlyWithWings

问题是,当我需要在运行时通过setFlyBrhavoir() 方法更改flyBehavoir 并将其设置为FlyWithRocket 时,只要flyBehavoir 是私有的,如果我将其公开,它就不会更改它工作正常。我该怎么做?

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

低于我的尝试

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

【问题讨论】:

  • 除非我误解了问题,否则您在问题中已经提到了解决方案:您需要使用setter而不是直接访问属性。
  • 这就是private 的意思……你想要的是protected
  • 使用公共/受保护而不是私有。
  • jeroen 如果你检查代码,我正在使用 setter,
  • deceze protected give another error (!) 致命错误:未捕获的错误:无法访问 /home/yazfarqj/dev/headFirstDesignPatrenBook/ch1/duck3.php 中的受保护属性 DonaldDuck::$flyBehavoir 第 48 行

标签: php oop


【解决方案1】:

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

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

出于所有意图和目的,此类根本没有正式声明flyBehaviour,因此构造函数中的$this-&gt;flyBehaviour 创建了一个新的public 属性。 var_dumping 对象时可以清楚地看到这一点:

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

父级的 private 属性是 a) 独立的,b) private 和 c) null 因为还没有人设置它。否则你也无法在没有课程的情况下访问$donaldDuck-&gt;flyBehavoir-&gt;fly()

如果你有一个private 属性,你只需要让同一个类的代码作用于它:

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

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

这正如您所期望的那样工作,因为您使用正确的特权方法来访问该属性。如果您想直接在子类中访问该属性,则它需要是 protected(但它不会让您从类外部访问它,它必须是 public)。

【讨论】:

  • 令人惊叹的清晰解释先生,非常感谢您,它现在像水晶一样清晰。
猜你喜欢
  • 1970-01-01
  • 2021-03-13
  • 1970-01-01
  • 2017-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-09
  • 2013-03-24
相关资源
最近更新 更多