2016-11-17 74 views
-1

我需要一點幫助。 我有一個類名「Employee」,並且我已經繼承了兩個基類,它們分別是「Manager」和「Clerk」,現在我需要另一個繼承「Manager」和「Clerk」的類,但是這種多重繼承在C#或Unity/C#中是不可能的。但有人建議我使用「接口」。我對「接口」有點新鮮。 那麼請有人能幫助我嗎? 請發送示例代碼。類和接口與統一和C#

+0

你確定你在談論接口嗎?你可以實現多個接口,但是你不能繼承多個基類。這兩者之間有區別。抽象基類可能有實現,因此不能使用多繼承,因爲如果你用一個共同的方法繼承兩個基類,編譯器真的很難選擇兩個具有相同簽名的方法。然而,接口通過明確地沒有任何實現來解決這個問題,只是簽名。然後,您可以通過一個實現代表多個簽名。 – Espen

+0

那麼正如我所說我是新的「接口」,但我需要實現多重繼承,所以你可以建議我任何意思來實現它? –

+0

他爲什麼低調? –

回答

1

可以使用聚合:

public interface IEmployee 
{ 
} 

public interface IClerk : IEmployee 
{ 
    void DoClerkThing(); 
} 

public interface IManager : IEmployee 
{ 
    void DoManagerThing(); 
} 

public class Clerk : IClerk 
{ 
    public void DoClerkThing() 
    { 
    } 
} 

public class Manager : IManager 
{ 
    public void DoManagerThing() 
    { 
    } 
} 

public class ManagerAndClerk : IManager, IClerk 
{ 
    private readonly Manager manager; 
    private readonly Clerk clerk; 

    public ManagerAndClerk(Manager manager, Clerk clerk) 
    { 
    this.manager = manager; 
    this.clerk = clerk; 
    } 

    public void DoClerkThing() 
    { 
    this.clerk.DoClerkThing(); 
    } 

    public void DoManagerThing() 
    { 
    this.manager.DoManagerThing(); 
    } 
} 
+0

請注意,在此Facade實現中,該對象因爲超類型而不可通過。 – Espen

+0

你是對的,應該是:'公共班級經理和幹部:IClerk,IManager' –

2

考慮一下:

public abstract class ManagerBase 
{ 
    public void Execute() 
    { 
     Manage(); 
    } 

    public virtual void Manage() {} 
} 

public abstract class ClerkBase 
{ 
    public virtual void Expedite(){} 

    public void Execute() 
    { 
     Expedite(); 
    } 
} 

public class ManagingClerk : ClerkBase, ManagerBase 
{ 
    public override void Expedite() 
    { 
     Console.WriteLine("Expedited"); 
    } 

    public override Manage() 
    { 
     Console.WriteLine("Managed"); 
    } 
} 

在這裏,您嘗試繼承幾個基類,問題是,有沒有辦法讓編譯器知道哪個版本「執行」衍生物繼承。這被稱爲「鑽石之死」

你可以做的反而是沒有提供實現和基類標記爲接口:

public interface IManager 
{ 
    void Execute(); 

    void Manage(); 
} 

public interface IClerk 
{ 
    void Expedite(); 

    void Execute(); 
} 

public class ManagingClerk : IClerk, IManager 
{ 
    public void Expedite() 
    { 
     Console.WriteLine("Expedited"); 
    } 

    void IClerk.Execute() 
    { 
     Expedite(); 
    } 

    public void Manage() 
    { 
     Console.WriteLine("Managed"); 
    } 
    void IManager.Execute() 
    { 
     Manage(); 
    } 
} 

這裏編譯器會知道什麼方法屬於什麼。你從基類中放棄了繼承的實現,但你獲得了多重繼承。

1

在Unity中,您可以將多個組件附加到單個遊戲對象,對於大多數組件類型可以是同一類型。這意味着您可以將兩個腳本附加到單個遊戲對象。

這與繼承有很大不同,但在很多情況下它是非常有用的,但使用接口可能更好。

您有Employee類和它的派生類Clerk和Manager作爲腳本組件。然後,你必須ManagingClerk作爲另一個腳本:

[RequireComponent(typeof(Manager), typeof(Clerk))] 
public class ManagingClerk : Employee { 
} 

現在,當您將這個腳本的遊戲對象,它會自動連接管理器和職員,你無法刪除它們的任何。

可以使用GetComponent可以訪問特定的方法和成員:

Manager manager; 
Clerk clerk; 
void Awake(){ 
    //find components 
    manager = GetComponent<Manager>(); 
    clerk = GetComponent<Clerk>(); 
    //initialize both 
    manager.Init(this); 
    clerk.Init(this); 
} 
public void DoManagerStuff() { manager.DoStuff(); } 
public void DoClerkStuff() { clerk.DoStuff(); } 

這種方法的缺點是,你必須連接到一個單一的遊戲物體,其中兩個是不是真正的三名員工。在更換經理和職員不要搞亂管理人員時,你需要格外小心。

爲了初始化與manageClerk相關的職員和管理員組件,您需要在管理員和職員中實施一個方法(Init)。