2012-07-16 85 views
0
不工作

我有这样的结构:继承在PHP

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(); 

我得到

你买未知的品牌加上一个长只要$ 650

还是那句话:

我不知道为什么我得到Unknown brand而不是HTCget_model()通过get_description()叫,$650被正确计算。

+1

LongLastingBattery类? – LanguagesNamedAfterCofee 2012-07-16 19:53:53

+2

您应该查看[this](http://blog.ircmaxell.com/2012/07/oop-vs-procedural-code.html)博客文章。在这种方法中使用'abstract class'使得它在PHP中不支持多重继承(至少不是这种方式)。这段代码需要重构,并采取与“抽象类”不同的方法。 – Whisperity 2012-07-16 20:11:50

+0

hmmm ..感谢文章 – 2012-07-17 05:03:22

回答

-1

您的FeatureDecorator继承自Android,而不是从HTC继承。因此,第一次添加装饰时,$android2将是Android而不是以前的HTC类型。

也许你的意思如下:

abstract class FeaturesDecorator extends HTC { 
    // ... 
} 

这应该给你的例子正确的输出。


编辑则可以将model成员变量移动到Android类;应该工作以及:

abstract class Android { 
    protected $model = "unknown model"; 

    public function get_model() { 
    return $this->model; 
    } 
} 

这样model直接存储内Android,可以从所有的子类进行设置,可以从持有到Android对象的引用任何其他类进行检索。

+0

是的,但HTC获得了Android抽象类,其中有get_model ...可以被htc重写.. – 2012-07-17 04:59:09

+0

@DmitryMakovetskiyd:是的,它可以被'HTC'重写,但是你的装饰者不会扩展'HTC' - 他们只扩展'Android'。 “Android”和“FeatureDecorator”都不知道“HTC”。你可以做的一件事是将'model'成员变量存储在'Android'而不是'HTC'中,这也可以起作用。 – knittl 2012-07-17 08:30:44

-1
$android1=new HTC(); 
$android2=new BigScreenSize($android1); 
$android3=new VideoCamera($android2); 

上做$ android2和3会给你他们持有的对象的var_dump(不得不改变,以摄影机为电池类中不存在您提供的代码)和android3持有bigscreensize对象不是HTC ,因此是'未知'。如果你想获得你的结果(以下简称“HTC”),你必须(让$ Android的市民,不要私第一)和

echo $android3->android->get_description(); 

或根据你的榜样(仍然在你的班级做$安卓公众)

echo $android2->android->get_description(); 

应用这些变化给我:

你买HTC加上大尺寸屏幕,为$ 800

最后我仍然认为你应该修补你所采取的方法。也许添加一个方法,它可以从它的父级获得$模型,并在构造函数中使用它。这样您可以跟踪模型并使用本地属性。(在我上面的例子中,videocamera尝试在执行get_description()时访问bigscreensize-> get_model(),这个方法在bigscreensize中不存在,但是在android中是bigscreensize的父类的父类。装饰器不知道htc类的存在,所以除非你提供了一个方法让所有的装饰器访问/传递'model'变量,你将无法访问它传递的第一个装饰器。在

每节课我应该读的问题之前,我昨晚回答对不起

+0

最新的区别。 cost()方法是这样工作的,但是get_description ,,, does not..why? – 2012-07-17 04:58:11

+0

@DmitryMakovetskiyd我希望这次能有更多的帮助。 – StrayObject 2012-07-17 09:21:49

0

当我第一次测试你的代码,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,它具有此方法并返回"unknown model"

为了克服这个问题,你可以在这两个摄影机和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