2016-07-13 40 views
2

好吧,不好意思,我知道你們會告訴我我需要搜索和搜索,但是我已經確定我是正確的,並且認爲這樣會按照我想要的方式工作,但是我想我會在這裏問一下,並嘗試在我的學習經驗上得到一些專業幫助,因爲統一答案並不是那麼好。內部類Constructer ...做這個工作嗎?

反正我想開始構建另一個MMORPG,我也在同一時間學習c sharp。我有一個課程,我想在創建玩家類的同時創建一個Vocation類(玩家的職業,像法師,騎士等),所以我需要用一個ID來決定哪個職業和什麼職業它們繼承的屬性值。

這就是我的,這項工作,我正在努力?還是我在做可怕的錯事...?

編輯

using UnityEngine; 
using System.Collections; 

//DONE: abstract: a personage can't be "Vocation", but Mage, Warrior, Archer... 
public abstract class Vocation 
{ 
    //DONE: just a readonly property 
    public int Vid {get; } 
    //DONE: just a readonly property 
    public string Name { get { return _Name; } } 
    protected string _Name = "None"; 

    //DONE: let's ensure the property to be overriden 
    public abstract HitPointsPerLevel { get; } 
    public abstract ManaPointsPerLevel { get; } 

    //DONE: you don't want this constructor to be public, but protected only 
    //DONE: Assign all the data in one place 
    protected Vocation(int vid) 
    { 
     Vid = vid; 
    } 
} 

//DONE: do not declare derived class as inner one 
internal class Mage : Vocation 
{ 
    sealed public override float HitPointsPerLevel { get { return 12f; } } 
    sealed public override string _Name = "Mage"; 

    //DONE: typo constructor should have been "Mage" 
    public Mage() : base(1) 
    { 
    } 
} 

如何做IT現在看GUYS?

+1

您沒有使用法師類。 – user3185569

+0

'internal'表示一個類只能從相同的程序集(exe,dll)中訪問。沒有進一步的背景,我會說你現在不需要打擾。 「法師」也是一個內部階級,但我沒有看到它應該是的原因。我認爲'戰士'是一個複製粘貼的錯誤,你的意思是'法師'?最後,你爲什麼傳入'vid'並將其分配給只讀屬性?這是行不通的。 –

+1

如果你嘗試過,你會看到'base.Vid = 1;'產生一個編譯器錯誤,因爲'Vid'沒有setter。即使'Vid = vid;'失敗,也不會做任何事情,因爲'Vid'總是返回'0'。其次,'base.Name =「法師」;'也不會出於同樣的原因。你能*做的是在'Vocation'中有一個'protected string _Name ='None「',然後將Name屬性變成'public string Name {get {return _Name}}',並在'Mage'中設置字段被稱爲「戰士」的構造函數?認真地說,讓IDE(Visual Studio)以這樣的錯誤幫助你... – Corak

回答

3

我建議重新設計實施

using UnityEngine; 
using System.Collections; 

//DONE: abstract: a personage can't be "Vocation", but Mage, Warrior, Archer... 
public abstract class Vocation 
{ 
    //DONE: just a readonly property 
    public int Vid {get; } 
    //DONE: just a readonly property 
    public string Name {get; } 

    //DONE: let's ensure the property to be overriden 
    public abstract HitPointsPerLevel { get; } 

    //DONE: you don't want this constructor to be public, but protected only 
    //DONE: Assign all the data in one place 
    protected Vocation(int vid, string name) 
    { 
     if (string.IsNullOrEmpty(name)) 
      throw new ArgumentNullException("name"); 

     Vid = vid; 
     Name = name; 
    } 
} 

//DONE: do not declare derived class as inner one 
internal class Mage : Vocation 
{ 
    sealed public override float HitPointsPerLevel { get { return 12f; } } 

    //DONE: typo constructor should have been "Mage" 
    public Mage() : base(1, "Mage") 
    { 
    } 
} 
+0

爲什麼不把'HitPointsPerLevel'放入構造函數呢? –

+0

不要緊,如果你使一個抽象類的構造函數公開或保護...... –

+0

@HitPointsPerLevel:'HitPointsPerLevel'很可能*複雜*(取決於*法力*的情況下'法師',*敏捷* ,*武器類型*如果是「勇士」等) –

0

該代碼將工作,除了構造函數名稱(Warrior而不是Mage)。

我在想,爲什麼Mage必須是內部嵌套類Vocation。那有什麼用?

我可以理解你爲什麼要做它internal:你不想讓外部程序集創建一個實例,你可以通過工廠來實現。但是,沒有理由讓類嵌套。基類可以獨立運作。只要將嵌套類拉出來,就可以在基類上使用protected成員來在基類​​和派生類之間進行通信。

一個小側面說明:您可以在這裏使用this代替base

public Mage(int vid) : base(vid) 
{ 
    this.Vid = 1; 
    this.Name = "Mage"; 
} 
+0

我想我可以使用這個,而不是基地,這是一個意外,使它內部和嵌套。 – Codinablack

0

很少有東西,除了其他的答案來發表評論,但他們都在代碼審查中。也許這在codereview.stackexchange.com更好。

首先(這歸結於風格) - 我儘量避免使用像Vid這樣的變量 - vocationId沒有什麼問題 - 描述性更好。

第二,更相關的問題,我不知道你Mage /人,語義上講,一種職業 - 所以它不應該繼承它。也許這是一個有職業的人,但它本身不是一種職業 - 它可能不會延伸職業功能。這是繼承的唯一意圖。

您是否試圖在實踐中繼承傳統概念中的鞋號角?

而且,順便說一句,在C#6你有表達濃郁的性能,讓您可以將您的代碼一點:

public string Name => "None"; 

雖然這些看起來像常量給我。這基本上需要重新設計,從OOP封裝的基本原理開始,並保持簡單。

+0

Unity不支持C#4,5甚至6 – Programmer

+1

我想他還是很好的知道他。 –

+0

是的,很高興知道! – Codinablack