繁体   English   中英

具有unity和C#的类和接口

[英]Classes and interfaces with unity and C#

我需要一点帮助。 我有一个类名“ Employee”,并且已经继承了两个基类,即“ Manager”和“ Clerk”,现在我需要另一个继承“ Manager”和“ Clerk”的类,但是多重继承是在C#或Unity / C#中不可能。 但是有人建议我使用“接口”。 我对“接口”有点陌生。 所以有人可以帮我吗? 请发送示例代码。

考虑一下:

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

在这里,编译器将知道哪些方法属于什么方法。 您从基类中释放了继承的实现,但是获得了多个继承。

您可以使用聚合:

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

在Unity中,您可以将多个组件附加到一个游戏对象上,对于大多数组件类型而言,该对象可以是同一类型。 这意味着您可以将两个脚本附加到单个游戏对象。

这和继承有很大的不同,但是在很多情况下很有用,但是使用接口可能是一个更好的主意。

您拥有Employee类,及其派生类Clerk和Manager作为脚本组件。 然后,将ManagingClerk作为另一个脚本:

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

现在,当您将此脚本附加到游戏对象时,它将自动附加Manager和Clerk,并且您将无法删除它们。

您可以使用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(); }

这种方法的缺点是,您将三个员工附加到一个游戏对象上,其中两个不是真实对象。 在更换经理和文员时,您需要格外小心,不要弄乱managementClerk。

为了初始化附加到managementClerk的职员和经理组件,您需要在经理和职员中实现一个方法(Init)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM