当前位置: 首页 > 知识库问答 >
问题:

如何处理一个子类有一个方法,而另一个子类没有它?

公冶俊达
2023-03-14

我有一个关于接口的问题,比如:

class IAnimal
{ ...
Public:
    virtual void makeSound() = 0;
};

class Cat : public IAnimal
{  ...
    void makeSound() { std::cout << "purr" << std::endl; }
};
class Dog : public IAnimal
{  ...
    void makeSound() { std::cout << "bark" << std::endl; }
};
class AnimalFactory
{
    std::shared_ptr<IAnimal> createAnimal(animalType type)
    {  
        std::shared_ptr<IAnimal> animal;
        switch(type)
        { case animal_type::cat: animal = std::shared_ptr<Cat>(); break; 
          case animal_type::dog: animal = std::shared_ptr<Dog>(); break; 
        … }
        return animal;
    }
};

class App
{ ...
    std::shared_ptr<IAnimal> _animal;
    AnimalFactory::animal_type type;
    void haveCat()
    { ...
        type = AnimalFactory::animal_type::cat;
        _animal = AnimalFactory.createAnimal(type);
        _animal->makeSound();
        ...
    } 
};

现在,我需要这只猫去抓一只老鼠void catchMouse(){std::cout

void haveCat()
{ ...
  type = AnimalFactory::animal_type::cat;
  _animal = AnimalFactory.createAnimal(type);
  _animal->makeSound();
  // catchMouse();
  ...
}

有几种可能的解决方案,但看起来都不好。

>

  • 在IAnim中添加一个方法,然后使用AnimalFactory创建猫后,我可以从IAnimal调用catchMouse()方法。但是catchMouse并不适用于所有动物,狗不catchMouse。将方法添加到IEM会污染界面,嗅到代码。
  • 在Cat中添加一个公共方法catchMouse(),并将_animal强制转换为haveCat()方法中的Cat。

    {
    _cat = std::dynamic_pointer_cast<Cat>(AnimalFactory.createAnimal(type));
    _cat->makeSound();
    _cat->catchMouse();
    }
    

    但有一个html" target="_blank">动态演员阵容,不好,对吧?

    让Cat实现IAnimal接口和另一个关于鼠标的接口,但AnimalFactory只返回std::shared\u ptr,我们不能在IAnimal中调用catchMouse。

    我想说的是,在一个子类中有一个公共方法,但如果我们使用factory,另一个子类没有,如何设计它。请不要回复,让狗抓兔子,然后在IAnimal中添加catch()方法,这样,猫可以抓老鼠,狗可以抓兔子。

    这个问题的好解决方案是什么?谢谢

  • 共有2个答案

    汤枫
    2023-03-14

    我想,处理这个问题的方法是解决方案2的变体:使用特殊的方法catch创建一个特定的接口ICatcher,并执行如下操作:

    AnimalFactory::animal_type type = AnimalFactory::animal_type::cat;
    std::shared_ptr<IAnimal> animal = myAnimalFactory.createAnimal(type);
    (dynamic_cast<ICatcher*>(animal.get()))->catch();
    

    但在这里,您应该确保dynamic\u cast会成功,或者提供额外的检查。

    也许,您还会对超级接口IUnknown及其QueryInterface方法如何在COM中解决此问题感兴趣。可以为该体系结构实现本地版本。

    洪昱
    2023-03-14

    我认为你不能从shared\u ptr演到Cat,对吗?因此,在不了解您的代码库的情况下,我编写了一个小型测试程序,

    #include <memory>
    #include <string>
    #include <iostream>
    
    class IAnimal
    { 
    public:
       virtual void makeSound(){}
    };
    
    class Cat : public IAnimal
    {  
    public:
        virtual void makeSound() { std::cout << "purr" << std::endl; }
        void catchMice(void){
            std::cout<<"mouse catched\n";
        }
    };
    class Dog : public IAnimal
    {  
        virtual void makeSound() { std::cout << "bark" << std::endl; }
    };
    
    int main(int argc,char** argv){
        Cat* c = new Cat;
        std::shared_ptr<IAnimal> s(c);
        //you've basically got something of this sort don't you?
        s->makeSound();
        (static_cast<Cat*>(s.get()))->catchMice();
        return 0;
    }
    

    那应该是你想要的。我认为您可能希望将makeSound(void)作为一个虚拟函数

     类似资料:
    • 如何从另一个类中处理?下面列出了我的代码。 处置类别: <代码>主窗口。main\u f.dispose()不起作用,因为它不是变量。你能帮助我吗?

    • 我的Java包中有四个类。只有一个类具有方法。 当我运行方法时,我如何运行这四个类中的所有方法? 以下是我的课程: 第一类。JAVA 第二类。爪哇 第三类。JAVA 样品。JAVA

    • 如有任何帮助,我们将不胜感激。

    • 我有抽象类动物,然后我有像狗和猫这样的类,并且扩展了类动物。 我想确保父类动物的所有子类都有一个静态方法:getProperties。即使其他人无权访问我的代码,也可以实现一个新的动物子类。 我希望它是静态的,因为Dog类的所有Animals都具有完全相同的属性(或者您不需要Dog来了解Dog的一般外观),因此它是在classtype上调用的方法,而不是类实例。 这可能吗?

    • 问题内容: 假设我有一个西服套装和四个西服套装子类别:Heart,Spade,Diamond和Club。 我有一个方法,该方法接收西装作为参数,这是一个类对象,而不是实例。更准确地说,它可能仅接收以下四个值之一:Heart,Spade,Diamond,Club。我该如何做出保证这种事情的断言?就像是: 我正在使用Python 3。 问题答案: 您可以使用像这样。

    • 问题内容: 在Bruce Eckel的“ Thinking In Java,第四版”的第428页(有关类型信息的章节)中,具有以下示例: 也许我有点累,但是我看不到add()方法中对add()的调用是如何工作的。我一直认为它应该有一个引用,或者是一个静态方法(并且我在ArrayList或List中找不到静态add())。我想念什么? 我只是为自己测试,发现这可行: 问题答案: Java为这样的方法