为什么装饰器模式实现需要具有核心类的通用抽象超类?

用户名

我正在尝试使用中的装饰器设计模式c++但是,如果没有抽象超类(内核和装饰类都从中继承),我将无法实现它。

我不明白为什么需要抽象超类。

我的工作装饰器示例:

#include <string>
#include <iostream>
using namespace std;

// abstract superclass
class Pizza
{
  public:
    virtual string GetDescription() = 0;
    virtual int GetCost() = 0;
};

// base class that can be extended
class Margharita: public Pizza 
{ 
   private:
    string description;
    int cost;
   public:
     Margharita(string t, int c){description = t; cost = c;} 
     string GetDescription(){return(description);}
     int GetCost(){return(cost);}
}; 

// decorator class that extends base class
class ExtraCheese: public Pizza
{
   private:
    Pizza* pizza;

   public:
    // constructor
    ExtraCheese(Pizza* p) {pizza = p;}

    string GetDescription() { return (pizza->GetDescription() + ", Extra Cheese"); } 
    int GetCost() {  return(pizza->GetCost() + 20); } 
};

int main()
{
  // create decorated object
  Pizza* pizza = new ExtraCheese(new Margharita("Margharita", 100));
  cout <<  pizza->GetDescription() << '\n';
  cout << pizza->GetCost() << '\n';
}

给出输出:Margharita, Extra Cheese 120

如果删除抽象超类,装饰将停止工作:

#include <string>
#include <iostream>
using namespace std;

// base class that can be extended
class Pizza
{
  private:
   string description;
   int cost;
  public:
    Pizza(){description = "Pizza"; cost = 100;};
    string GetDescription(){return(description);}
    int GetCost(){return(cost);}
}; 

// decorator class that extends base class
class ExtraCheese: public Pizza
{
   private:
    Pizza* pizza;

   public:
    // constructor
    ExtraCheese(Pizza* p) {pizza = p;}

    string GetDescription() { return (pizza->GetDescription() + ", Extra Cheese"); } 
    int GetCost() {  return(pizza->GetCost() + 20); } 
};

int main()
{
  // create decorated object
  Pizza* pizza = new ExtraCheese(new Pizza());
  cout <<  pizza->GetDescription() << '\n';
  cout << pizza->GetCost() << '\n';
}

在这种情况下,输出仅显示核心对象(Pizza 100的属性

为什么会这样呢?

讲故事的人-Unslander Monica

当您删除抽象基类时,就创建了函数GetDescriptionGetCost不是虚函数因此,它们不会动态分配。这就是为什么pizza->GetDescription()叫做Pizza成员函数,它是一个电话解决的基础上,静态类型pizza唯一。

您不需要抽象的基础就可以再次工作,只需动态分配即可,因此只需添加虚拟说明符

class Pizza
{
  private:
   string description;
   int cost;
  public:
    Pizza(){description = "Pizza"; cost = 100;};
    virtual string GetDescription(){return(description);}
    virtual  int GetCost(){return(cost);}
}; 

这将允许ExtraCheese通过动态调度获取中的覆盖您还可以通过使用说明override来帮助编译器捕获此类错误您是否已定义ExtraCheese如下:

class ExtraCheese: public Pizza
{
   private:
    Pizza* pizza;

   public:
    // constructor
    ExtraCheese(Pizza* p) {pizza = p;}

    string GetDescription() override { return (pizza->GetDescription() + ", Extra Cheese"); } 
    int GetCost() override {  return(pizza->GetCost() + 20); } 
};

现代编译器会抱怨您试图覆盖未声明为虚函数的功能。该错误将是显而易见的。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

装饰器模式:为什么需要抽象装饰器?

装饰器模式:为什么我们需要抽象装饰器?

Typescript中抽象通用Container类的子代的装饰器

具有通用参数的Java抽象类,实现了自己的通用参数

在Typescript中,为什么我的通用抽象类在尝试实现它时没有找到类型参数?

将实例变量移动到装饰器模式中的抽象类的原因是什么?

为什么抽象类不能具有Sealed方法

Java:装饰器模式 - 对主要抽象类的引用

Matlab:当实现在超类中声明为抽象的方法时,为什么必须公开访问?

具有通用类的Monolog实现

Swift-具有通用超类约束的扩展中的协议默认实现

当通过将所有方法抽象为抽象类而可以实现与Interface相同的功能时,为什么需要Interface?

类中所有方法的抽象方法装饰器

为什么装饰器设计模式在示例中总是显示为类和子类?

客户类的装饰器模式

为什么实现具有类型约束的泛型接口的泛型类需要重复这些约束?

为什么超类通用类型不被擦除/铸造

在Kotlin中创建具有通用Type的抽象类

JsonFormat用于具有通用参数的抽象类

使用两个不同的装饰器实现装饰所有类方法的元类

Android:扩展应用程序类。为什么我们需要实现单例模式?

如何在Angular 8的抽象类和抽象类的实现中使用@Component装饰器?

抽象装饰器类(而不是装饰器)内部的功能

为什么我需要在实现接口的类中实现接口的所有方法?

为什么Typescript允许实现抽象类?

为什么在装饰器设计模式中需要装饰器?

使用类作为装饰器时,为什么 args 中没有“self”?

当采用具有“ Self”类型的属性的协议时,为什么类需要为“ final”类?

Java:为什么需要包装器类?