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
Aprivate
属性在子类中不可访问
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行惊人清晰的解释先生非常感谢现在像水晶一样清晰。惊人清晰的解释先生非常感谢现在像水晶一样清晰。