在面向對象中,有兩個很重要的東西,繼承和包含。
更多的時候,我們不會去分析兩種方式究竟哪種更好,能夠達到自己想要的目的即可。但是存在即道理,還是要仔細分析一下。
繼承:
Class Animal{};
Class Cat : public Animal{};
包含:
class Animal
{};
class Cat
{
private:
Animal *animal;
};
繼承的弊端:
#include
using namespace std;
class Animal
{
public:
int makeSound() {
cout << "Animal is making sound" << endl;
return 1;
}
private:
int ntimes;
};
class Cat : public Animal
{};
int main()
{
Cat *cat = new Cat();
cat->makeSound();
return 0;
}
//輸出:
//Animal is making sound
此時此刻,如果我們想改變makesound函數:
Sound *makeSound(int n) {
cout << "Animal is making sound" << endl;
return new Sound;
}
因此,我們的代碼也要進行改變:
#include
using namespace std;
class Sound{};
class Animal
{
public:
Sound *makeSound() {
cout << "Animal is making sound" << endl;
return new Sound;
}
};
class Cat : public Animal
{};
int main()
{
Cat *cat = new Cat();
cat->makeSound();
return 0;
}
如果使用包含呢:
#include
using namespace std;
class Animal
{
public:
int makeSound() {
cout << "Animal is making sound" << endl;
return 1;
}
};
class Cat
{
private:
Animal *animal;
public:
int makeSound() {
return animal->makeSound();
}
};
int main()
{
Cat *cat = new Cat();
cat->makeSound(3);
return 0;
}
同樣是對makeSound進行修改:
#include
using namespace std;
class Sound{};
class Animal
{
public:
Sound* makeSound() {
cout << "Animal is making sound" << endl;
return new Sound();
}
};
class Cat
{
private:
Animal *animal;
public:
Sound* makeSound() {
return animal->makeSound();
}
};
int main()
{
Cat *cat = new Cat();
cat->makeSound();
return 0;
}
This example shows that the ripple effect caused by changing a back-end class stops (or at least can stop) at the front-end class. Although Animal’s makeSound() method had to be updated to accommodate the change to Animal, our main()required no changes.
Object composition helps us keep each class encapsulated and focused on one task. Our classes and class hierarchies will remain small and will be less likely to grow and become unmanageable.
However, a design based on object composition will have more objects (if fewer classes), and the system’s behavior will depend on their (remote) interrelationships instead of being defined in one class.
Favor object composition over class inheritance.