Overuse of virtual methods?

Recently, I was tasked with when I had to implement something similar to the following:

There are some animals with certain attributes, for example:

Dog1: name: tery, color: white, fav drink: grape juice
Dog2: name: chiva, color: black, fav drink: lemonade
Bird1: name: tweety, canfly: yes, cansing: no
Bird2: name: parry, canfly: no, cansing: yes

How could you do this in C ++ effectively taking advantage of OOP?

I did something like this:

class Animal {  
    Animal(...);  
    ...  
    public String getName() const;  
    public void setName(string s);  
    ...  
    private:  
    String name;  
}  

class Bird : public Animal {  
    Bird(...);  

    public bool canFly() const;  
    public void setCanFly(bool b);  
    ...

    private:  
    bool canFly;  
    bool canSing;  
}  

class Dog : public Animal {  
    ...  
}  

The problem with this implementation is that I cannot use polymorphism:

Animal* p = new Anima(...);  
...  
p->canFly();  

and I have to use casting:

((Bird*)p)->canFly();  

In the end, I was criticized for not using virtual functions in the base class and using throws instead of OOP.

, , , getName() , . canFly , .

, () , , :

bool Dog::canFly () const {
return false;
}

, ?

+5
9

, canFly , false.

canFly , , . , , c- , , canFly, .

canFly , bool canFly() const {return false; } .

, " ", , , , .

+7

, . :

Animal
  |
  |--Flying Animal
  |        |---Bird
  |
  |--Non Flying Animal
           |---Dog

:

class Animal
{
public:
  virtual bool CanFly () = 0;
  String Name ();
};

class Flying : public Animal
{
public:
  virtual bool CanFly () { return true; }
};

class NonFlying : public Animal
{
public:
  virtual bool CanFly () { return false; }
};

class Bird : public Flying
{
};

class Dog : public NonFlying
{
};

, , .

EDIT: . , ( , ), , . , .

, ( ) :

class Animal
{
public:
   String Name ();
   List <Characteristic> Characteristics ();
};

class Characteristic
{
public:
   String Name ();
};

class CanFly : public Characteristic
{
public:
  bool CanFly ();
};

class Legs : public Characteristic
{
public:
  int NumberOfLegs ();
};

, :

Animal *CreateDog ()
{
  Animal *dog = new Animal;
  dog->Characteristics ()->Add (new CanFly (false));
  dog->Characteristics ()->Add (new NumberOfLegs (4));
  return dog;
}

:

Animal *CreateBird ()
{
  Animal *bird = new Animal;
  bird->Characteristics ()->Add (new CanFly (true));
  bird->Characteristics ()->Add (new NumberOfLegs (2));
  return bird;
}

:

  • , , .
  • , .

, . - , .

+7

, :

((Bird*)p)->canFly(); 

C- static_cast; p Dog, , . .

, , dynamic_cast:

if (Bird* bp = dynamic_cast<Bird*>(p)) {
    // p points to a Bird
}
else {
    // p points to something else
}

dynamic_cast , , .


, . , . . dynamic_cast , , .

, , , , , , Animal , - .

+5

, , ( ).

canFly canSing, , get/set virtual .

virtual fly sing, , true, .

+3
struct Animal {
  std::string name;
  std::string favoriteDrink;
  bool canFly;
  bool canSing;
};

get/seters , .

, , , . , , -.

, .

, . , , - " ", " ", " " (, , " ?" )

, , . , . , .

: , , , . . , , , Animal.

- Fly(), . , ( . , , "fly" , bool -, , , , ).

, . .

, , , ( "" " , ", " ".

, -, , .

.

+3

, ( - ), , .

GameObject, , update() draw() - . , . PlayerObject, EnemyObject, PowerUpObject ..

- :

GameObject *p = firstObject;
while(p)
{
    p->update();
    p = p->nextObject;
}

update() (, , - ), - , . , - .

+1

, . , Animal, .

, , .. canFly , , .

0

.

, . .

false canFly() ? , , .

0

In my humble opinion, the setter methods , and indicate a bad object-oriented design. And this problem space is not particularly conducive to demonstrating what a good object-oriented design is, too.

0
source

All Articles