继承在PHP中不起作用
我有这样的结构:继承在PHP中不起作用,php,class,inheritance,abstract,Php,Class,Inheritance,Abstract,我有这样的结构: abstract class Android { public function __construct() { } public abstract function cost(); public function get_model(){ return "unkown model"; } } class HTC extends Android { public function __construct(
abstract class Android {
public function __construct() {
}
public abstract function cost();
public function get_model(){
return "unkown model";
}
}
class HTC extends Android {
public function __construct() {
parent::__construct();
$this->model= "HTC";
}
public function get_model() {
return $this->model;
}
public function cost() {
return 500;
}
}
abstract class FeaturesDecorator extends Android {
public function __construct() {
parent::__construct();
}
public abstract function get_description();
}
class VideoCamera extends FeaturesDecorator {
private $android;
public function __construct($android) {
parent::__construct();
$this->android=$android;
}
public function get_description() {
return $this->android->get_model()." plus a video camera, ";
}
public function cost() {
return 200 + $this->android->cost();
}
}
class BigScreenSize extends FeaturesDecorator {
private $android;
public function __construct($android) {
parent::__construct();
$this->android=$android;
}
public function get_description() {
return $this->android->get_model()." plus a big size screen, ";
}
public function cost() {
return 100 + $this->android->cost();
}
}
应用以下模式后:
$android2 = new HTC();
$android2 = new BigScreenSize($android2);
$android2 = new LongLastingBattery($android2);
echo "<br/><br/>You have bought ".$android2->get_description()." for $".$android2->cost();
$android2=新HTC();
$android2=新的大屏幕尺寸($android2);
$android2=新的长效电池($android2);
echo“
您已经用$android2->cost()购买了“$android2->get_description()”;
我明白了
你花650美元买了一个无名品牌加上一个耐用的电池
再次:
我想知道为什么我从
get_model()
调用get_description()。因此,第一次添加装饰时,$android2
将是Android
类型,而不是之前的HTC
也许你的意思是:
abstract class FeaturesDecorator extends HTC {
// ...
}
这将为您的示例提供正确的输出
编辑您可以将模型
成员变量移动到Android
类;也应该起作用:
abstract class Android {
protected $model = "unknown model";
public function get_model() {
return $this->model;
}
}
通过这种方式,模型
直接存储在Android
中,可以从所有子类中进行设置,并且可以从包含对Android
对象引用的任何其他类中检索
$android1=new HTC();
$android2=new BigScreenSize($android1);
$android3=new VideoCamera($android2);
在$android2和$android3上执行var_转储将为您提供它们持有的对象(必须更改为videocamera,因为您提供的代码中没有电池类),android3持有的是bigscreensize对象,而不是htc,因此“未知”。如果你想获得你的结果(“HTC”),你必须(首先让$android成为公共的而不是私有的)并且
或者按照你的例子(仍然在课堂上公开$android)
应用这些更改可以让我:
你花了800美元买了HTC plus大屏幕
最后,我仍然保留我最初的想法,即你应该修改你所采取的方法。可能会添加一个方法,从其父级获取$model并在构造函数中使用它。这样可以跟踪模型并使用本地属性。(在上面的示例中,摄像机在执行get_description()时尝试访问bigscreensize->get_model(),此方法在bigscreensize中不存在,但在作为bigscreensize父级的android中存在。继承在这里工作很好。请注意,您的修饰符不知道htc类是否存在,因此除非您为所有修饰符提供一个方法来访问/传递“model”变量。您将无法通过fir访问它st decorator.cost()之所以有效,是因为它存在于每个类中
在昨晚回答之前,我应该先阅读这个问题。对不起。当我第一次测试你的代码时,php告诉我,类LongLastingBattery
不存在,这是正确的-它不存在。我想你的意思是VideoCamera
;所以我回答中的主要功能将从以下内容开始:
$android2 = new HTC();
$android2 = new BigScreenSize($android2);
$android2 = new VideoCamera($android2);
您的问题是,您只是混淆了两个方法get_description()
和get_model()
:首先在摄像机实例上调用get_description()。这里有$this->android->get_model(),其中$this->android是BigScreenSize的实例。BigScreenSize类不会重写方法get_model().BigScreenSize扩展了FeaturesDecorator,它也不重写此方法,但扩展了Android,它有此方法并返回“未知模型”
为了克服这个问题,您可以在VideoCamera和BigScreenSize中将$this->android->get_model()
更改为$this->android->get_description()
,并将android和HTC中的get_model()方法重命名为get_description()。最后,您必须将FeaturesDecorator更改为:
abstract class FeaturesDecorator extends Android {}
然后你会得到这个:
<br/><br/>You have bought HTC plus a big size screen, plus a video camera, for $800
您花了800美元购买了HTC plus大屏幕和摄像机
你应该看看这篇博客文章。在这种方法中使用抽象类
会让PHP不支持多重继承(至少不是这样)。这段代码需要重构,并采取与抽象类
不同的方法。有什么区别。成本()方法是这样工作的,但是get_description,,,,doesnskiyd。,为什么?@DmitryMakovetskiyd我希望这次我能提供更多的帮助。是的,但是htc有一个Android抽象类,它有get_模型…可以被htc覆盖。@DmitryMakovetskiyd:是的,它可以被htc
覆盖,但是你的装饰程序没有扩展htc
——他们只扩展Android
。Android
和FeatureDecorator
都不了解HTC
。您可以做的一件事是将您的模型
成员变量存储在Android
中,而不是HTC
,这样也可以。
abstract class FeaturesDecorator extends Android {}
<br/><br/>You have bought HTC plus a big size screen, plus a video camera, for $800