2016-11-17 27 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)。