你可能不想要一个层次结构,就像在你交付的低类中没有声明的方法Bird
那样产生Bat
。这样你就失去了统一层次结构的意义。Animal
fly()
你可以这样做:
class Animal {
virtual bool canFly() { return false; }
virtual void fly() {throw Exception( "Sorry babe, I don't fly"); }
}
并覆盖fly
和。Bird
Bat
这将导致您为fly()
您可能不想要的狗、猫实现方法。所以也许你可以创建一个新的类Flyer
来声明这个方法:
class Flyer : public Animal {
virtual void fly() = 0;
}
class Bat : public Flyer {}
class Bird : public Flyer {}
这将与更详细的生物学分类不一致,例如Reptile
,Mammal
。
另一个技巧可能是提出方法 likemove()
和 dog 会实现它 asrun()
和 bird as fly()
,都具有统一的接口。
另一件事是,我认为问狗是否会飞是一个有效的问题,所以我认为 Dog.canFly()
应该在你的代码中实现类似的方法,作为动物的一部分。
考虑到所有这些,我会这样做:
// Your base animal
class Animal {
virtual bool canFly() {return false;}
};
// Any animal that could fly, just abstract class
class Flyer {
virtual void fly() = 0;
}
// Ants, flies etc.; real biological hierarchy
class Insect : public Animal {}
class Mammals : public Animals {}
class Birds : public Animals {}
// And now flying bird :
class Bird : public Birds, public Flyer {
virtual bool canFly() {return true; }
virtual void fly() {...}
}
// And flying insect
class Fly : public Insect, public Flyer {
virtual bool canFly() {return true; }
virtual void fly() {...}
}
然后您就可以这样做(基于此答案,恐怕您必须为此使用指针):
if( Collection[i]->canFly()){
Flyer *thisBird = static_cast<Flyer*>(Collection[i]);
}
您也可以从虚拟继承派生Flyer
并Animal
使用虚拟继承,但这被称为“可怕的钻石”,它不被认为是好的做法,但值得一读。
正如Ricibob在评论中指出的那样,Flyer
应该指定canFly()
,这将在简单的示例中:
class Flyer {
public:
virtual bool canFly() const {return true;}
virtual void fly() {cout << "Flying" << endl; }
};
Bird b;
cout << "Can fly: " << b.canFly() << endl;
// Error 1 error C2385: ambiguous access of 'canFly'
但是,如果您从课程的一部分中Flyer
交付Animal
并且:Bird
Birds
Flyer
class Animal {
public:
virtual bool canFly() const {return false;}
};
class Flyer : virtual Animal {
public:
virtual bool canFly() const {return true;}
virtual void fly() {cout << "Flying" << endl; }
};
class Bird : virtual public Birds, virtual public Flyer {
};
// Warning 1 warning C4250: 'Bird' : inherits 'Flyer::Flyer::canFly' via dominance
现在canFly()
返回1
,但代码对我来说似乎是错误的。
此时......您可以canFly()
为每个子类(或大型组)手动指定,或者Birds
从Flyers
(例如对于 不正确Chicken
)交付,或者交付新的子类:
class FlyingBrids : public Birds, public Flyer /* Flyer not delivered from Animal */ {
virtual bool canFly() const {return true;}
};
请注意,这Flyer
仍然很重要,因为Fly
从Insect
.