宠物动物园 C++ / 继承 Class/Subclasses
Petting Zoo C++ / Inheritance Class/Subclasses
我得到了一个练习,它应该适用于不同的 classes 以及它们在不同 classes 之间的关系。
适用于不同 class 的函数应该定义为一个抽象的基础 class,然后用在对象上,class 是一个子class来自基本的。
在这个练习中,我应该展示分离接口和实现的优点。
我应该想象一个包含许多不同动物的动物园。这些动物应该分为哺乳动物、鸟类或鱼类。
- 游客应该可以喂一些动物(山羊、鹅、金鱼)
- 而其他的则无法喂食(熊、鲨鱼)
- 游客还应该可以抚摸一些动物,例如山羊,而其他动物,例如熊、鸟和鱼则不能抚摸
- 一些动物应该有特有的声音 - 鱼是沉默的
- 宠物也应该有一个昵称(每个人)
我应该实施 class/subclass 以便我能够使用
void feed ( Animal& Animal )
void pet ( mammal& mammal )
void noise ( mammal& mammal )
void noise ( bird& bird )
我应该有 10 种不同的动物 - 每种类型(哺乳动物、鸟类、鱼类)至少有 2 种,通过使用其中一种功能(无效饲料等)应该询问动物是否可以进行所需的操作,然后像这样回复答案:
"The goat billy can be fed"
"the bear bruno doesn't like to be pet"
"the goose herta quarks"
动物的特征适用于整个物种(哺乳动物、鸟类、鱼类只是特定的动物)
因此它们独立于实例(所有山羊都可以喂食——不仅仅是比利山羊)
关键字 "static" 可用于分配 class 变量
"static const bool feedable = ;"
然后变量不会再次应用于每个实例,而且它变得确定
该特征适用于该类型的所有动物。
使用抽象基础 class 并且仅使用虚拟方法。每个 animal/type 都应该使用其特定的变量和方法
它需要工作(不应该有 bool petable for fish)
最后还要画一个树状结构的继承图
抱歉,我的英语很糟糕,但我没有其他人可以问 - 所以我尽量解释清楚了
这是我目前得到的:
zoo.h
#include <iostream>
#include <cstring>
using namespace std;
// CAnimal abstract class
class CAnimal {
public:
CAnimal() { strcpy(m_name, ""); }
virtual ~CTier() { }
void setName(char *name) { strcpy(m_name, name); }
virtual void introduce() { cout << "Hello, my name is " <<m_name <<end1; }
virtual CAnimal* create(char *) = 0; // pure virtual method
private:
char m_name[50];
};
// CMammal
class CSMammal : public CAnimal {
public:
CMammal() { }
virtual ~CMammal() { }
virtual void introduce() {
CAnimal::introduce();
cout <<"I am a mammal"<<end1;
}
};
// CFish
class CFish : public CAnimal {
public:
CFish() { }
virtual ~CFish() { }
virtual void introduce() {
CTier::introduce();
cout << "I am a Fish" <<end1;
}
};
// CBird
class CBird : public CAnimal {
public:
CBird(){ }
virtual ~CBird() { }
virtual void introduce() {
CTier::introduce();
cout << "I am a Bird" <<end1;
}
};
// Tierart - legt eine Klasse an, welche von Vogel, Fisch oder Säugetier abgeleitet ist. Der Konstruktor legt die individuellen Namen fest.
#define ANIMALTYPE(cname,parentclass,whoami)
class name : public parentclass
{
public:
cname(char *name) { CTier::setName(name); }
/* Default-Konstruktor für Kreirrepresäntant */
cname() { }
void introduce() {
parentclass::introduce();
cout << "Ich bin " << whoami <<end1;
}
/* Kreirfunktion: Forward Ownership! */
CTier* create(char *name) { return new cname(name); }
};
这是我的 zoo.cpp
#include <stdlib.h>
#include <time.h>
#include "zoo.h"
// giving names
char *namen[] = { "Mehmet", "Aykut", "Dumbo", "Helga", "Henni",
"KQLY", "Pasha", "Huan", "Emilio", "Blume" };
const int namZahl = sizeof(namen) / sizeof(*namen);
// Tierarten (Klassen anlegen)
SPEZIES(CGoat, CMammal, "a Goat")
SPEZIES(CPenguin, CBird, "a Penguin")
SPEZIES(CGoldfish, CFish, "a Goldfish")
SPEZIES(CBaer, CMammal, "a Baer")
SPEZIES(CGoose, CBird, "a Goose")
SPEZIES(CShark, CFish, "a Shark")
SPEZIES(CBadge, CMammal, "a Badger")
SPEZIES(CSalmon, CFisch, "a Salmon")
SPEZIES(CBlackbird, CBird, "a Blackbird")
SPEZIES(CElefant, CMammal, "an Elefant")
// main methode
int main(void) {
所以现在我不知道如何实施其他 "voids" 如果我可以喂养动物 + 在练习的其余部分使用静态命令,它们会给我信息。
在这种情况下更好的设计是将所有常见行为移动到抽象的基础 class,然后让子classes 以自己的方式实现特定行为。例如:-
MakeNoise();
每个动物都支持 ,因此您可以轻松地将其作为纯虚函数包含在基础 class 中。但是,如果您考虑 feeding of animals 以与 MakeNoise
相同的方式包含在基础 class 中,那么您将不会获得直观的行为。例如:-
Feed(Item x);
鲨鱼不能喂食。你会如何在设计中翻译它。使该函数在 Shark 中抛出错误?
这意味着可以喂养鲨鱼,但尝试喂养它们是错误的。
因此,最好将其移出基础 class 并根据行为 classes 实施它。
class Feedable {};
class Feed1 : public Feedable {};
然后在 classes 中您想要此行为的地方实施这些。
我得到了一个练习,它应该适用于不同的 classes 以及它们在不同 classes 之间的关系。
适用于不同 class 的函数应该定义为一个抽象的基础 class,然后用在对象上,class 是一个子class来自基本的。
在这个练习中,我应该展示分离接口和实现的优点。
我应该想象一个包含许多不同动物的动物园。这些动物应该分为哺乳动物、鸟类或鱼类。
- 游客应该可以喂一些动物(山羊、鹅、金鱼)
- 而其他的则无法喂食(熊、鲨鱼)
- 游客还应该可以抚摸一些动物,例如山羊,而其他动物,例如熊、鸟和鱼则不能抚摸
- 一些动物应该有特有的声音 - 鱼是沉默的
- 宠物也应该有一个昵称(每个人)
我应该实施 class/subclass 以便我能够使用
void feed ( Animal& Animal )
void pet ( mammal& mammal )
void noise ( mammal& mammal )
void noise ( bird& bird )
我应该有 10 种不同的动物 - 每种类型(哺乳动物、鸟类、鱼类)至少有 2 种,通过使用其中一种功能(无效饲料等)应该询问动物是否可以进行所需的操作,然后像这样回复答案:
"The goat billy can be fed"
"the bear bruno doesn't like to be pet"
"the goose herta quarks"
动物的特征适用于整个物种(哺乳动物、鸟类、鱼类只是特定的动物) 因此它们独立于实例(所有山羊都可以喂食——不仅仅是比利山羊) 关键字 "static" 可用于分配 class 变量 "static const bool feedable = ;" 然后变量不会再次应用于每个实例,而且它变得确定 该特征适用于该类型的所有动物。
使用抽象基础 class 并且仅使用虚拟方法。每个 animal/type 都应该使用其特定的变量和方法 它需要工作(不应该有 bool petable for fish)
最后还要画一个树状结构的继承图
抱歉,我的英语很糟糕,但我没有其他人可以问 - 所以我尽量解释清楚了
这是我目前得到的:
zoo.h
#include <iostream>
#include <cstring>
using namespace std;
// CAnimal abstract class
class CAnimal {
public:
CAnimal() { strcpy(m_name, ""); }
virtual ~CTier() { }
void setName(char *name) { strcpy(m_name, name); }
virtual void introduce() { cout << "Hello, my name is " <<m_name <<end1; }
virtual CAnimal* create(char *) = 0; // pure virtual method
private:
char m_name[50];
};
// CMammal
class CSMammal : public CAnimal {
public:
CMammal() { }
virtual ~CMammal() { }
virtual void introduce() {
CAnimal::introduce();
cout <<"I am a mammal"<<end1;
}
};
// CFish
class CFish : public CAnimal {
public:
CFish() { }
virtual ~CFish() { }
virtual void introduce() {
CTier::introduce();
cout << "I am a Fish" <<end1;
}
};
// CBird
class CBird : public CAnimal {
public:
CBird(){ }
virtual ~CBird() { }
virtual void introduce() {
CTier::introduce();
cout << "I am a Bird" <<end1;
}
};
// Tierart - legt eine Klasse an, welche von Vogel, Fisch oder Säugetier abgeleitet ist. Der Konstruktor legt die individuellen Namen fest.
#define ANIMALTYPE(cname,parentclass,whoami)
class name : public parentclass
{
public:
cname(char *name) { CTier::setName(name); }
/* Default-Konstruktor für Kreirrepresäntant */
cname() { }
void introduce() {
parentclass::introduce();
cout << "Ich bin " << whoami <<end1;
}
/* Kreirfunktion: Forward Ownership! */
CTier* create(char *name) { return new cname(name); }
};
这是我的 zoo.cpp
#include <stdlib.h>
#include <time.h>
#include "zoo.h"
// giving names
char *namen[] = { "Mehmet", "Aykut", "Dumbo", "Helga", "Henni",
"KQLY", "Pasha", "Huan", "Emilio", "Blume" };
const int namZahl = sizeof(namen) / sizeof(*namen);
// Tierarten (Klassen anlegen)
SPEZIES(CGoat, CMammal, "a Goat")
SPEZIES(CPenguin, CBird, "a Penguin")
SPEZIES(CGoldfish, CFish, "a Goldfish")
SPEZIES(CBaer, CMammal, "a Baer")
SPEZIES(CGoose, CBird, "a Goose")
SPEZIES(CShark, CFish, "a Shark")
SPEZIES(CBadge, CMammal, "a Badger")
SPEZIES(CSalmon, CFisch, "a Salmon")
SPEZIES(CBlackbird, CBird, "a Blackbird")
SPEZIES(CElefant, CMammal, "an Elefant")
// main methode
int main(void) {
所以现在我不知道如何实施其他 "voids" 如果我可以喂养动物 + 在练习的其余部分使用静态命令,它们会给我信息。
在这种情况下更好的设计是将所有常见行为移动到抽象的基础 class,然后让子classes 以自己的方式实现特定行为。例如:-
MakeNoise();
每个动物都支持 ,因此您可以轻松地将其作为纯虚函数包含在基础 class 中。但是,如果您考虑 feeding of animals 以与 MakeNoise
相同的方式包含在基础 class 中,那么您将不会获得直观的行为。例如:-
Feed(Item x);
鲨鱼不能喂食。你会如何在设计中翻译它。使该函数在 Shark 中抛出错误?
这意味着可以喂养鲨鱼,但尝试喂养它们是错误的。
因此,最好将其移出基础 class 并根据行为 classes 实施它。
class Feedable {};
class Feed1 : public Feedable {};
然后在 classes 中您想要此行为的地方实施这些。