就像谢尔盖说的那样,它不仅是关于构造函数。它可以节省您不得不一遍又一遍地初始化相同的字段。例如,
没有继承
class Cat
{
float height;
float weight;
float energy;
string breed;
int somethingSpecificToCat;
public Cat()
{
//your constructor. initialize all fields
}
public Eat()
{
energy++;
weight++;
}
public Attack()
{
energy--;
weight--;
}
}
class Dog
{
float height;
float weight;
float energy;
string breed;
int somethingSpecificToDog;
public Dog()
{
//your constructor. initialize all fields
}
public Eat()
{
energy++;
weight++;
}
public Attack()
{
energy--;
weight--;
}
}
具有继承
常见的动物一切都被搬到了基类。这样,当你想建立一个新的动物时,你不需要再把它全部输出。
abstract class Animal
{
float height;
float weight;
float energy;
string breed;
public Eat()
{
energy++;
weight++;
}
public Attack()
{
energy--;
weight--;
}
}
class Cat : Animal
{
int somethingSpecificToCat;
public Cat()
{
//your constructor. initialize all fields
}
}
class Dog : Animal
{
int somethingSpecificToDog;
public Dog()
{
//your constructor. initialize all fields
}
}
另一个好处是,如果你想标记一个唯一的ID每一个动物,你并不需要包括在每个构造,并保持使用的最后一个ID的全局变量。你可以很容易地在Animal构造函数中做到这一点,因为每当派生类被实例化时它都会被调用。
例
abstract class Animal
{
static int sID = 0;
float height;
float weight;
int id;
public Animal()
{
id = ++sID;
}
}
现在,当你这样做;
Dog lassie = new Dog(); //gets ID = 1
Cat garfield = new Cat(); // gets ID = 2
如果你想你的 '农场' 在所有动物的名单,
没有继承
List<Cat> cats = new List<Cat>(); //list of all cats
List<Dog> dogs = new List<Dog>(); //list of all dogs
...etc
具有继承
List<Animal> animals = new List<Animal>(); //maintain a single list with all animals
animals.Add(lassie as Animal);
animals.Add(garfield as Animal);
这样,如果你想要t Ø看到,如果你有一个名为Pluto
一种动物,你只需要遍历一个列表(动物),而不是多个列表(猫,狗,猪等)
编辑回应您的评论
你不需要实例化动物。你只需创建一个你想要的动物的对象。实际上,由于动物永远不会是通用动物,因此您可以创建Animal
作为抽象类。
abstract class Animal
{
float height;
float weight;
float energy;
string breed;
public Eat()
{
energy++;
weight++;
}
public Attack()
{
energy--;
weight--;
}
}
class Cat : Animal
{
int somethingSpecificToCat;
public Cat()
{
//your constructor. initialize all fields
}
}
class Dog : Animal
{
int somethingSpecificToDog;
public Dog()
{
//your constructor. initialize all fields
}
}
Cat garfield = new Cat();
garfield.height = 24.5;
garfield.weight = 999; //he's a fat cat
//as you can see, you just instantiate the object garfield
//and instantly have access to all members of Animal
Animal jerry = new Animal(); //throws error
//you cannot create an object of type Animal
//since Animal is an abstract class. In this example
//the right way would be to create a class Mouse deriving from animal and then doing
Mouse jerry = new Mouse();
编辑您的评论
如果您将它存放在动物名单,你仍然可以访问到所有领域。你只需要将其转换回原来的类型。
List<Animal> animals = new List<Animal>();
animals.Add(garfield as Animal);
animals.Add(lassie as Animal);
//if you do not cast, you cannot access fields that were specific to the derived class.
Console.WriteLine(animals[0].height); //this is valid. Prints Garfield's height
Console.WriteLine(animals[0].somethingSpecificToCat); //invalid since you haven't casted
Console.WriteLine((animals[0] as Cat).somethingSpecificToCat); //now it is valid
//if you want to do it in a loop
foreach(Animal animal in animals)
{
//GetType() returns the derived class that the particular animal was casted FROM earlier
if(animal is Cat)
{
//the animal is a cat
Cat garfield = animal as Cat;
garfield.height;
garfield.somethingSpecificToCat;
}
else if (animal is Dog)
{
//animal is a dog
Dog lassie = animal as Dog;
lassie.height;
lassie.somethingSpecificToDog;
}
}
你已经迷惑了你自己的例子。例如 - 只有猫有牙齿,还是做所有的动物?为了争论,让所有的动物都这样做(一个大多数正确的说法) - 那么牙齿不应该成为你的基类的一部分吗? –
那么这只是一个例子,我将会有多个范畴和物种,每一个物种都会有一个独特的领域,但是让我们改变这个思路:p。 – Gvs
@ user1083543:看起来这是某种家庭作业/课堂作业。出于这个原因,继承可能有很多优点,这个特定的任务不会导致你利用。但是分配的目的是让你熟悉继承,这样当你确实需要时,你可以使用它。 – xbonez