简体   繁体   English

具有unity和C#的类和接口

[英]Classes and interfaces with unity and C#

I need a bit help. 我需要一点帮助。 I have a class name "Employee", and I have inherited into two base classes out of it say "Manager" and "Clerk", Now I need another class that inherits both "Manager" and "Clerk", but that multiple inheritance is not possible in C# or Unity/C#. 我有一个类名“ Employee”,并且已经继承了两个基类,即“ Manager”和“ Clerk”,现在我需要另一个继承“ Manager”和“ Clerk”的类,但是多重继承是在C#或Unity / C#中不可能。 But someone advised me to use "interfaces". 但是有人建议我使用“接口”。 I am kinda new to "interfaces". 我对“接口”有点陌生。 So please can anybody help me out ? 所以有人可以帮我吗? Do send the the example code. 请发送示例代码。

Consider this : 考虑一下:

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

Here you try to inherit several base classes, the problem is that there is no way for the compiler to know which version of "Execute" the derivative inherits. 在这里,您尝试继承几个基类,问题是编译器无法知道派生继承的哪个版本的“ Execute”。 This is referred to as "The Diamond Of Death" 这被称为“死亡钻石”

What you could do instead is not provide implementations and mark the base classes as interfaces: 相反,您可以做的是不提供实现并将基类标记为接口:

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

Here the compiler will know what methods belong to what. 在这里,编译器将知道哪些方法属于什么方法。 You loose inherited implementations from the base class, but you gain multiple inheritance. 您从基类中释放了继承的实现,但是获得了多个继承。

You can use aggregation: 您可以使用聚合:

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

In Unity you can attach multiple components to a single game object which for most component types can be of a same type. 在Unity中,您可以将多个组件附加到一个游戏对象上,对于大多数组件类型而言,该对象可以是同一类型。 Which means you can attach two scripts to a single game object. 这意味着您可以将两个脚本附加到单个游戏对象。

This is quite different than inheritance but it is very helpful in many cases yet it might be a better idea to use interface. 这和继承有很大的不同,但是在很多情况下很有用,但是使用接口可能是一个更好的主意。

You have Employee class, and its derived classes Clerk and Manager as script components. 您拥有Employee类,及其派生类Clerk和Manager作为脚本组件。 Then you have ManagingClerk as another script: 然后,将ManagingClerk作为另一个脚本:

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

Now when you attach this script to a game object it automatically attach Manager and Clerk and you cannot remove either of them. 现在,当您将此脚本附加到游戏对象时,它将自动附加Manager和Clerk,并且您将无法删除它们。

You can have access to specific methods and members using GetComponent : 您可以使用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(); }

The down side of this approach is that you have three employees attached to a single gameobject where two of them are not real. 这种方法的缺点是,您将三个员工附加到一个游戏对象上,其中两个不是真实对象。 you need to be extra careful when changing manager and clerk not to mess up managingClerk. 在更换经理和文员时,您需要格外小心,不要弄乱managementClerk。

in order to initialize both clerk and manager components attached to managingClerk you need to implement a method (Init) in manager and clerk. 为了初始化附加到managementClerk的职员和经理组件,您需要在经理和职员中实现一个方法(Init)。

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

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