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#. 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.
-
Are you sure you are talking about interfaces? You can infact implement more than one interface, you cannot however inherit more than one base class. There is a difference between these two. Abstract base classes may have implementations, therefore multiple inheritance cannot be used, since it is really hard for the compiler to select two methods with the same signature if you inherit two base classes with a method in common. However, interfaces solves this by explicitly not have any implementations, just signatures. Then you can represent multiple signatures through one implementation.Espen– Espen2016-11-17 06:29:54 +00:00Commented Nov 17, 2016 at 6:29
-
Well as I said I am new to "interfaces", but I need to implement multiple inheritance, so can you advice me any mean to implement it ??TanvirDuggal– TanvirDuggal2016-11-17 06:33:52 +00:00Commented Nov 17, 2016 at 6:33
-
Why is he downvoted?hyankov– hyankov2016-11-17 08:47:57 +00:00Commented Nov 17, 2016 at 8:47
3 Answers
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. 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.
Comments
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. 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. Then you have ManagingClerk as another script:
[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.
You can have access to specific methods and members using 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.
in order to initialize both clerk and manager components attached to managingClerk you need to implement a method (Init) in manager and clerk.