2016-02-25 176 views
0

對於繼承還是比較新的,所以我需要一些幫助。目前,我有一項任務是創建一個使用3種武器繼承的基本遊戲。我的基類:實例化一個繼承對象

public class Weapons : MonoBehaviour 
{ 
    public int rateOfFire; 
    public string myName; 

    public Weapons(string Name) 
    { 
     myName = Name; 
    } 
} 

而子類中的一種:

public class Rifle : Weapons 
{ 
    public Rifle(string Name) 
     : base(Name) 
    { 
     myName = Name; 
     rateOfFire = 5; 
    } 
} 

我的第一個問題來了這樣一個事實,如果我連這樣做對嗎?

我的第二個問題是如何將這些實例化到我的Unity場景中? 我已經寫了一個方法來切換武器,這是我的播放器腳本上的數組,所以我會在這裏插入一個實例化線或創建另一個方法?缺少一些線條,但這裏是它的只是:

public GameObject[] weapons; 
public int currentweapon = 0; 
private int invweap; 
void Start() 
{ 
    //Managing weapons 
    invweap = weapons.Length; 
    SwitchWeapon(currentweapon); 
} 
void SwitchWeapon(int index) 
{ 
    for (int i = 0; i<invweap;i++) 
    { 
     if (i == index) 
     { 
      weapons[i].gameObject.SetActive(true); 
     } 
     else 
     { 
      weapons[i].gameObject.SetActive(false); 
     } 
    } 
} 
+0

在繼承的類中調用'myName = Name;'是沒有必要的,因爲您調用基類並且基類已經這樣做了。 – Icemanind

+0

爲什麼你需要在這裏繼承?你不使用任何繼承的優勢。 Unity3d中的每個對象都是從MonoBehaviour繼承而來的。 – Valentin

+1

@Valentin因爲這就是任務所要求的,正如他所說的。 – Asik

回答

7

我的第一個問題來了這樣一個事實,如果我連這樣做對嗎?

非常接近。我們看看吧。

public class Weapons : MonoBehaviour 
{ 

我認爲這是來自給定基類型的這種類型的Unity限制。通常,人們永遠不會說武器是一種「monobehaviour」,無論如何。

有沒有武器不是更具體的武器?不,所以這應該是一個抽象類。

類應該命名爲單數,除非類本身代表一組事物。這應該是「武器」,而不是「武器」。

abstract class Weapon: MonoBehaviour 
{ 

繼續前進。

public int rateOfFire; 

我們已經陷入困境。公共字段在C#中是不好的代碼味道。如果你想有一個公共屬性,則使其成爲一個屬性:

​​3210

更多的鼻子上,但:射速僅適用於遠程武器。你在基類中有這個,暗示它適用於所有武器。你不會開刀。

public string myName; 

再次,公共領域,不好。使它成爲一個財產。不要稱之爲myName。叫它它是什麼:Name

public string Name { get; set; } 

繼續前進。

public Weapons(string Name) 
{ 
    myName = Name; 
} 

使用駝峯的參數,PascalCase的性質:

public Weapon(string name) 
{ 
    Name = name; 
} 

將其命名爲過改變嗎?如果沒有,請將其設置爲只讀屬性。

public string Name { get; } 

(取決於你使用的是什麼版本的C#這可能不合法。嘗試{ get; private set; }如果不工作)。

那名可以在構造函數中設置意味着每實例的武器有一個名字。是對的嗎?這看起來不正確。有沒有名爲鮑勃劍的劍,還有名爲「Stormbringer」的劍和什麼?我原以爲這個名字會與這個類型相關聯,而不是與一個給定的實例相關聯。我期望這個名字是一個抽象的屬性,被派生類型覆蓋。

public abstract string Name { get; } 

移動到派生類型:

public Rifle(string Name) 
    : base(Name) 
{ 
    myName = Name; 
    rateOfFire = 5; 
} 

這被弄亂了。您已經在基類構造函數中設置了名稱;不要再設置它!爲什麼是由基地設定的名稱,而是由派生的電力公司設定的火災率?要麼火速應該是派生類型的屬性,要麼應該與名稱一起傳入。

讓我們擺脫它們,只是在派生類中重寫fire抽象屬性的名稱和速率。並且讓我們改進類型層次結構,以便武器基類不包含僅適用於遠程武器的東西。

所以,把它放在一起:

public abstract class Weapon : MonoBehaviour 
{ 
    public abstract string Name { get; } 
} 

public abstract class RangedWeapon : Weapon 
{ 
    public abstract int RateOfFire { get; } 
} 

public class Rifle : RangedWeapon 
{ 
    public override string Name { get { return "rifle"; } } 
    public override int RateOfFire { get { return 5; } } 
} 

public class Sword : Weapon 
{ 
    public override string Name { get { return "sword"; } } 
} 

有意義嗎?

我的第二個問題是如何將這些實例化到我的Unity場景中?

這是更好地讓每StackOverflow上的問題一個問題,因爲通常會發生什麼是第二個問題沒有得到回答。就像我沒有在這裏回答它。

+0

爲什麼在基類中有一個抽象屬性而不是在構造函數中設置的具體屬性更好?我這樣問,是因爲當我擁有對於對象必不可少的不變屬性時,我總是在這兩種解決方案之間猶豫不決,比如'Name'或'Id'。最近我開始使用混凝土材料,以保證其不變性。 –

+0

@LucaCremonesi:如果這個屬性真的是不變的,那麼我認爲這是更好的解決方案。在OP所在的「遊戲」領域,可能會有一些遊戲規則,比如說,根據上下文來改變火焰的速度,就好像你在夜間在潮溼的屋頂上一樣。在這種情況下,人們可能會爭辯說,財產首先不是正確的,而虛擬方法會更好。或者說房地產應該是「未修改的火災率」,然後這是對更復雜政策的不變的投入。我的觀點是:這取決於情況。 –