在面向对象中,有两个很重要的东西,继承和包含。
更多的时候,我们不会去分析两种方式究竟哪种更好,能够达到自己想要的目的即可。但是存在即道理,还是要仔细分析一下。
继承:
Class Animal{};
Class Cat : public Animal{};
包含:
class Animal
{};
class Cat
{
private:
Animal *animal;
};
继承的弊端:
#include <iostream>
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 <iostream>
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 <iostream>
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 <iostream>
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.