그런데 실제로 상속을 사용하다 보면 오히려 더 어려운 코드가 만들어지는 경우가 있습니다.
만약 동물의 왕국을 상속을 통해 만든다면...
public class Animal
{
public virtual void Bite()
{
// do Nothing
}
public virtual void Swim()
{
// do Nothing
}
public virtual void Run()
{
// do Nothing
}
public virtual void Fly()
{
// do Nothing
}
}
public class Avian : Animal
{
public override void Fly()
{
// do Fly
}
}
public class Mammal : Animal
{
}
public class Seagal : Avian
{
}
public class Penguin : Avian
{
public override void Swim()
{
// do Swim
}
public override void Fly()
{
// do Nothing - Avian은 날 수 있는데 Penguin은 날지 못하므로
}
}
public class Ostrich : Avian
{
public override void Run()
{
// do Run
}
public override void Fly()
{
// do Nothing - Avian은 날 수 있는데 Ostrich는 날지 못하므로
}
}
public class Bat : Mammal
{
public override void Fly()
{
// do Fly
}
}
public class Whale : Mammal
{
public override void Swim()
{
// do Swim
}
}
public class Dog : Mammal
{
public override void Bite()
{
// Do bite
}
public override void Run()
{
// do Run
}
}
.....
List<Animal> Zootopia = new List<Animal>();
Zootopia.Add(new Penguin());
Zootopia.Add(new Seagal());
Zootopia.Add(new Ostrich());
Zootopia.Add(new Bat());
Zootopia.Add(new Dog());
Zootopia.Add(new Whale());
이정도가 될 수 있겠죠. 전체적으로 정돈되지 않고, 중복되는 코드(While.Swim(), Penguin.Swim()), 복잡한 가상함수관계(Animal.Fly(), Avian.Fly(), Ostrich.Fly(), Bat.Fly()), 그리고 덩치가 큰 base 클래스(class Animal) 등에 의해 알아보기 힘든 코드가 됩니다.
이런 단점을 보완하기 위해서 컴포넌트(Component)를 사용할 수 있습니다. 상속관계를 본체(Animal)가 아니라 컴포넌트에 적용하는 것입니다.
// Components
public class Component
{
public virtual void Do
{
// do Nothing
}
}
public class Bite : Component
{
public override void Do
{
// do Bite
}
}
public class Swim : Component
{
public override void Do
{
// do Swim
}
}
public class Run : Component
{
public override void Do
{
// do Run
}
}
public class Fly : Component
{
public override void Do
{
// do Fly
}
}
public class Animal : List<Component>
{
}
public class Avian : Animal
{
Add(new Fly()); // 조류의 경우는 기본적으로 날아다님
}
public class Mammal : Animal
{
}
public class Seagal : Avian
{
public Seagal()
{
}
}
public class Penguin : Avian
{
public Penguin()
{
Add(new Swin());
RemoveFly(); // 리스트에서 Fly 제거
}
}
public class Ostrich : Avian
{
public Ostrich()
{
Add(new Run());
RemoveFly(); // 리스트에서 Fly 제거
}
}
public class Bat : Mammal
{
public Bat()
{
Add(new Fly());
}
}
public class Whale : Mammal
{
public Whale()
{
Add(new Swim());
}
}
public class Dog : Mammal
{
public Dog()
{
Add(new Bite());
Add(new Run());
}
}
.....
List<Animal> Zootopia = new List<Animal>();
Zootopia.Add(new Penguin());
Zootopia.Add(new Seagal());
Zootopia.Add(new Ostrich());
Zootopia.Add(new Bat());
Zootopia.Add(new Dog());
Zootopia.Add(new Whale());
이렇게 각자가 가진 속성만 정의하면 되므로 가독성이 높아질 수 있습니다.