就像謝爾蓋說的那樣,它不僅是關於構造函數。它可以節省您不得不一遍又一遍地初始化相同的字段。例如,
沒有繼承
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