正如 Sergey 所说,这不仅仅是关于构造函数。它使您不必一遍又一遍地初始化相同的字段。例如,
没有继承
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);
这样,如果您想查看是否有一个名为 Pluto 的动物,您只需要遍历单个列表(动物)而不是多个列表(猫、狗、猪等)
编辑以回应您的评论
您不需要实例化 Animal。您只需创建您想要的任何 Animal 的对象。事实上,由于 Animal 永远不会是泛型 Animal,您可以将 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;
}
}