0

私はこの構造を持っています:

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

私は得る

Unkown ブランドと長持ちするバッテリーを $650 で購入しました

また:

from が呼び出されたのではUnknown brandなく、正しく計算されている、なぜ取得するのだろうか。HTCget_model()get_description()$650

4

3 に答える 3

0

あなたのコードを最初にテストしたとき、php はクラスLongLastingBatteryが存在しないと言いましたが、これは正しいです。私はあなたが意味したと思いますVideoCamera; だから私の答えのあなたの主な機能はこれで始まります:

$android2 = new HTC();
$android2 = new BigScreenSize($android2);
$android2 = new VideoCamera($android2);

あなたの問題は、2 つのメソッドget_description()とを単に混同していることですget_model(): 最初に VideoCamera インスタンスで get_description() を呼び出します。$this->android->get_model() があり、$this->android は BigScreenSize のインスタンスです。クラス BigScreenSize はメソッド get_model() をオーバーライドしません。BigScreenSize は、このメソッドをオーバーライドしない FeaturesDecorator を拡張しますが、このメソッドを持ち、 を返す Android を拡張します"unknown model"

この問題を解決するには、VideoCamera と BigScreenSize の両方で変更$this->android->get_model()し、Android と HTC の両方で get_model() メソッドの名前を get_description() に変更します。$this->android->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
于 2013-01-24T14:42:22.497 に答える
-1

FeatureDecoratorからAndroidではなく、から継承しHTCます。したがって、最初に装飾を追加するときは、以前のタイプの ではなく の$android2タイプになります。AndroidHTC

多分あなたは次のことを意味しました:

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

これにより、例の正しい出力が得られるはずです。


編集modelすると、メンバー変数をAndroidクラスに移動できます。同様に動作するはずです:

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

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

その方法modelは に直接格納されAndroid、すべての子クラスから設定でき、 Androidオブジェクトへの参照を保持する他のクラスから取得できます。

于 2012-07-16T20:00:03.620 に答える
-1
$android1=new HTC();
$android2=new BigScreenSize($android1);
$android3=new VideoCamera($android2);

$android2 と 3 で var_dump を実行すると、それらが保持するオブジェクトが得られ (指定したコードにバッテリー クラスが存在しないため、ビデオカメラに変更する必要がありました)、android3 は htc ではなく bigscreensize オブジェクトを保持するため、「不明」です。結果 (「HTC」) を取得したい場合は、(最初に $android を非公開ではなく公開にする) 必要があります。

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

またはあなたの例に従って(まだあなたのクラスで $android を公開しています)

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

これらの変更を適用すると、次のようになります。

HTC と大画面スクリーンを $800 で購入しました

結局、私はあなたがとったアプローチをいじくり回すべきだという私の最初の考えをまだ保持しています. おそらく、その親から $model を取得し、コンストラクターで使用するメソッドを追加します。このようにして、モデルを追跡し、ローカル プロパティを使用できます。(上記の私の例では、get_description() を実行するときに videocamera が bigscreensize->get_model() にアクセスしようとします。このメソッドは bigscreensize には存在しませんが、bigscreensize の親の親である android には存在します。継承はここでうまく機能します。デコレータは htc クラスの存在を認識していないため、すべてのデコレータが「モデル」変数にアクセス/渡すためのメソッドを提供しない限り、最初のデコレータに渡されたものにはアクセスできません。cost() は存在するため機能しますすべてのクラスで。

昨夜答える前に質問を読むべきでした。ごめん。

于 2012-07-16T23:22:32.087 に答える