2016-09-12 100 views
2

大家好我是用Unity3D編程的C#,當我寫代碼的時候,我偶然發現了一個小問題,我給你寫了一個例子,因爲我不知道解釋我。多態,調用父親的子方法

class Base 
{ 
    public string name; 
} 
class Derived : Base 
{ 
    public void Gun(); 
} 

class BasePlayer 
{ 
    public Base x; 
} 

class SoldierPlayer : BasePlayer 
{ 

} 

的情況是這樣的,我想要做這樣的事情

SoldierPlayer.x.Gun(); 

但我不知道該怎麼辦呢

的實際情況是這樣的

public class BasePlayerController : MonoBehaviour 
     { 

      public BasePlayerManager playerManager; 
... 
public class RobotPlayerController : BasePlayerController { 
... 
playerManager = gameObject.AddComponent<RobotPlayerManager>(); 

我會用新方法

UPDATE 1

我做了示例更好,我想在基本控制器manager.user.energy做,被視爲下一類型RobotManager.RobotUser.energy

BaseController 
BaseManager 
BaseUser 

class BaseController 
{ 
    BaseManager manager; 
    public virtual void Move(int x,int y)... 
} 

class BaseManager { 
    BaseUser user; 
    public virtual Pause(bool state); 
} 

class BaseUser { 
    int life 
} 

RobotController 
RobotManager 
RobotUser 

class RobotController : BaseController 
{ 
    // manager as RobotManager? 
    public void Ray(int x,int y); 
} 

class RobotManager : BaseManager 
{ 
    // user as RobotUser? 
} 

class RobotUser : BaseUser 
{ 
    int energy; 
} 

UPDATE 2 我試圖做到這一點

public Run() 
{ 
    RobotController rc = new RobotController(); 
    rc.manager.energy; 
} 
+0

爲什麼你不從'Base'的'SoldierPlayer'繼承?如果你想這樣做,在你的'BasePlayer'中它應該有一個像這樣的'public Derived x;'的字段。我強烈建議你,你看看[Polymorphismus](https://msdn.microsoft.com/de-de/library/ms173152.aspx)。 –

+0

您正在尋找*抽象類和方法*和*虛擬方法*。谷歌,首先。 –

+0

不應該簡單地把'x'變成'Derived'類型嗎? – Sinatr

回答

2

你不能叫SoldierPlayer.x.Gun();因爲SoldierPlayer.x有TY沒有方法Gun()的pe Base。 OOP世界和C#可以爲您提供許多解決方案,您的選擇取決於您的目標。

他們中的一些(通過最佳實踐順序):

1)重寫多態性。添加。 Gun()方法到基地類並在派生類中實現它。例如

class Base 
{ 
    public string name; 
    public void virtual Gun() 
    { 
     Trace.Log("I'm base class, i can't do anything"); 
    } 
} 
class Derived : Base 
{ 
    public override void Gun() 
    { 
     Consule.WriteLine("Hello i have gun"); 
    } 
} 

class Derived2 : Base 
{ 
    public override void Gun() 
    { 
     Consule.WriteLine("Hello i have 2 guns"); 
    } 
} 

2)重載多態性在許多源此方法中提到像某種多態性AD-HOC的

public void GunAction(Derived2 o) 
{ 
    o.Gun(); 
} 
public void GunAction(Derived1 o) 
{ 
    o.Gun(); 
} 
public void GunAction(Base o) 
{ 
    Trace.Log("I'm base class, i can't do anything"); 
} 

3)被鑄

public void GunAction(Base o) 
{ 
    if(o is Derived1) 
     o.Gun(); 
    if(o is Derived2) 
     o.Gun(); 
} 

更新1回答您的新要求s

class BaseController 
{ 
    public BaseManager manager; 
... 

class RobotController1 : BaseController 
{ 
    // manager as RobotManager? - no it is stil BaseManager 
    public void Ray(int x,int y); 
} 


class RobotController2 : BaseController 
{ 
    // manager as RobotManager? - yes. now it is RobotManager 
    public void Ray(int x,int y); 

    public RobotController2() 
    { 
     manager = new RobotManager(); 
    } 
} 

public void Run() 
{ 
    var controller = new RobotController2();// you have RobotManager 
    controller.manager = new BaseManager();// it is again BaseManager 
} 
+0

對於選項1,您應該在基礎中創建方法'virtual'並在派生類中覆蓋它。你需要解釋其他選項。 – juharr

+0

我無法訪問manager.user.energy – Jumper404

+0

我剛剛提供了一個實例。我向你展示如何解決經理人員的這種情況。你應該與用戶成員 – burzhuy