2016-11-17 3 views
-1

私は少し助けが必要です。 "Employee"というクラス名があり、そこから2つの基本クラスに継承しています。 "Manager"と "Clerk"と言うのですが、今度は "Manager"と "Clerk"の両方を継承する別のクラスが必要です。 C#やUnity/C#では不可能です。しかし、誰かが私に「インターフェース」の使用を勧めました。私はちょっと新しい "インターフェース"です。 だから誰でも私を助けてくれますか? サンプルコードを送信します。ユニティとC#のクラスとインターフェイス

+0

あなたはインターフェイスについて話していますか?あなたは実際に複数のインターフェースを実装することができますが、複数の基本クラスを継承することはできません。これらの2つの違いがあります。抽象基本クラスには実装があるため、複数の継承を使用することはできません。共通のメソッドで2つの基本クラスを継承すると、コンパイラが同じシグネチャで2つのメソッドを選択することは実際には困難です。しかし、インタフェースは実装を明示的に持たないことでこれを解決します。次に、1つの実装で複数のシグネチャを表すことができます。 – Espen

+0

まあ、私は "インターフェイス"に新しいと言ったが、私は複数の継承を実装する必要がありますので、アドバイス私はそれを実装するための手段は何ですか? –

+0

なぜ彼はdownvotedですか? –

答えて

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

このファサードの実装では、オブジェクトはスーパータイプとして継承できないことに注意してください。 – Espen

+0

あなたは正しいと思います。 'public class ManagerAndClerk: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"); 
    } 
} 

を、問題は、コンパイラがどのバージョンを知っているための方法がないということですデリバティブが "Execute"を継承します。これは、実装を提供し、インターフェイスとしての基本クラスをマークされていないあなたの代わりに何ができるか

「死のダイヤモンド」と呼ばれている:

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では、単一のゲームオブジェクトに複数のコンポーネントをアタッチすることができます。これは、ほとんどのコンポーネントタイプが同じタイプである可能性があります。つまり、1つのゲームオブジェクトに2つのスクリプトを付けることができます。

これは継承とはまったく異なりますが、多くの場合非常に役立ちますが、インターフェイスを使用する方が良い考えがあります。

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(); } 

このアプローチの下側には、あなたがそれらの二つは本物ではない、単一のゲームオブジェクトに添付3人の従業員を持っているということです。あなたはマネージャーを変更するときに特別な注意を払う必要があります。

managersClerkにアタッチされた店員とマネージャの両方のコンポーネントを初期化するには、マネージャと店員にメソッド(Init)を実装する必要があります。

関連する問題