2017-02-20 85 views
0

這應該是一個非常直接的問題。我只要求一個簡單容易理解答案。不,我不想要教科書定義或鏈接到文檔,請儘可能簡單地回答。在c中創建一個繼承類的對象#

考慮以下幾點:

class Monster 
{ 
    public int Hp { get; protected set; } 
    public string Name { get; protected set; } 

    public virtual void Attack() 
    { 
     Console.WriteLine("Monster attacking!"); 
    } 
} 

class Skeleton : Monster 
{ 
    public Skeleton() 
    { 
     Hp = 20; 
     Name = "Skeleton"; 
    } 
    public override void Attack() 
    { 
     Console.WriteLine("Skeleton attacking!"); 
    } 
} 

現在想象一下,我創建類型怪物作爲這樣一個新的骨架對象。

Monster skeleton = new Skeleton(); 

我想知道創建與怪物類型一個骷髏對象VS創建與骨架型骷髏對象之間的區別。

Skeleton skeleton = new Skeleton(); 

我不明白這兩者之間是否存在差異,或者真的如何工作。任何和所有幫助表示讚賞!謝謝!

+1

骨架*是一個*怪物,但怪物*並不需要*骨架,考慮一個案例,當你有一羣擁有**多種類型的怪物時,他們所有的攻擊都是相同的時間** –

+0

(Phun打算)希望你不要想着c#/ oop作爲怪物(oop = monster,c#= skeleton):D –

回答

3

當您想要在單個集合中保存多個怪物時,使用Monster類型創建Skeleton對象的好處變得更加明顯。

List<Monster> EncounterMonsters = new List<Monster>(); 

聲明你Skeleton對象Monster允許你將它添加到這個列表,與您共創任何其他Monster類一起:

例如,可以按照以下方式定義一個列表。

所以,你可能有另一個怪物等級:

class Ogre : Monster 
{ 
    public Ogre() 
    { 
     Hp = 50; 
     Name = "Ogre"; 
    } 

    public override void Attack() 
    { 
     Console.WriteLine("Ogre attacking!"); 
    } 
} 

然後,您可以執行以下操作:

Monster skeleton = new Skeleton(); 
Monster ogre = new Ogre(); 

EncounterMonsters.Add(skeleton); 
EncounterMonsters.Add(ogre); 

這則允許你遍歷EncounterMonsters收集和攻擊每個使用爲每個方法重寫了Attack方法。

+0

絕對完美的答案,非常感謝。 – Tony

+0

當然,這很簡單,根據您的應用程序,您可能需要在受到攻擊時分別跟蹤每個怪物的HP,但它說明了這一點。 – Steve

+0

我假設最佳做法是創建一個骨架對象的類型骨架,除非我有一個理由不糾正? – Tony

1

擴大上公認的答案,不同的是,如果你使用的基類Monster實例化對象,只有屬性和由Monster類公開的方法可用。

考慮一下:

public class Monster 
{ 
    public Monster(int hp, string name) 
    { 
     Hp = hp; 
     Name = name; 
    } 
    public int Hp { get; protected set; } 
    public string Name { get; protected set; } 
} 

public class Skeleton : Monster 
{ 
    public string Loot { get; set; } // <- Note added property. 
    public Skeleton(int hp, string name) : base(hp, name) 
    { 
     Loot = "Sword"; 
    } 
} 

public class Vampire : Monster 
{ 
    //- some vampire specific properties 

    public Vampire(int hp, string name) : base(hp, name) 
    { 
     // ... 
    } 
} 

現在,如果你實例化骨架作爲一個怪物。

Monster skeleton = new Skeleton(100, "skully"); 
skeleton.Loot(); //- Will throw a compile time error. 

如果你將它實例化爲一個骨架;

Skeleton skeleton = new Skeleton(100, "skully"); 
skeleton.Loot(); // Will return "Sword"; 

這是有用的,當你,例如,有一種方法或服務,將你的怪物的公共屬性行事,說你有記錄了一個怪物的統計方法。

public string LogMonsterStats(Monster monster) 
{ 
    return $"{monster.Name} has {monster.Hp} health points"; 
} 

///.... 

Skeleton skeleton = new Skeleton(100, "Bob"); 
LogMonsterStats(skeleton); // returns "Bob has 100 health points" 

請注意,我們正在將一個Skeleton實例傳遞給一個期望Monster實例的方法。所以在方法範圍內Bob被視爲怪物,而不是骨架。