Can Virtual/Override be used with a 3 piece inheritance?
The image should say it all. Im wanting to have a separate inheritance class (Equipment) just to make organisation easier. Will the Virtual/Override methods still work as pictured?
Yes, you can do that. Every method that you don’t override just passes down to the next level without modification.
Regarding your bonus question, declaring a virtual method in Equipment is no different from declaring one in Item, and uses exactly the same syntax. If you don’t specify a base class that you’re inheriting from, that just means that you automatically inherit from a special type called “object”. (There’s effectively a fourth box on the left side of your diagram that flows into Item.) Thus, Item is a “middle” class in your inheritance hierarchy, just like Equipment is. The same rules apply to both.
Also note that you can declare a virtual method in Item, override it in Equipment, and then override it again in Sword if you want.
I do have another question.
As you mentioned, Equipment can have either a Virtual or Override method.
What would happen with the below? What difference would it make between the two methods?
If a base class has a function, and a subclass redefines the same function without saying “override”, then you are hiding the original method instead of overriding it. You probably don’t ever want to do this on purpose; it’s mostly for cases where the base class and the subclass were made by different people and they coincidentally happened to use the same name to mean fundamentally different things. The compiler will give you a warning (you can make the warning go away if you add the word “new” to the subclass method declaration, which basically tells the compiler “yes, I did that on purpose”).
The main difference between hiding and overriding is that if you override, then which version gets called depends on the type of the object instance, but if you hide, then which version gets called depends on the type of the variable.
BaseClass a = new SubClass();
a.SomeFunction();
If SubClass has an override for SomeFunction, then this will call the SubClass’s implementation of SomeFunction. But if the SubClass hides SomeFunction by reusing the same method signature but without the “override” keyword, then that code will call BaseClass’s implementation of SomeFunction, because the variable “a” is of type BaseClass (even though it’s referring to an object of type SubClass).
The classic case where hiding is good is if you invent some function Foo() on the subclass, but then someone edits the base class and creates a new function called Foo() that does something different from what the subclass does. You don’t want to break all the code that is already calling Foo() on the subclass, but you also don’t want to call the subclass’s version of Foo() when someone is trying to use the base class’s version, because they don’t mean the same thing.
If you know in advance that you’re going to need both functions, you should just give them different names.
Right, from what im getting, this would also apply to Virtual >> Virtual >> Override. The MiddleClass would simply ignore the BaseClass (BaseClass is not executed at all) and the SubClass (Override) would of course ignore the MiddleClass (Unless I use base.MiddleClass();) only executing its own method alone.
Am I correct here?
I read this bit at least 3 times now and im getting confused…not following you.
Could you provide a visual or a coded example please? Id really appreciate it!
public class BaseClass {
public virtual void Foo() {
Debug.Log("base foo");
}
public virtual void Bar() {
Debug.Log("base bar");
}
}
public class SubClass : BaseClass {
public override void Foo() {
Debug.Log("sub foo");
}
public new void Bar() {
Debug.Log("sub bar");
}
}
BaseClass a = new BaseClass(); // BaseClass variable referencing a BaseClass instance
BaseClass b = new SubClass(); // BaseClass variable referencing a SubClass instance
SubClass c = new SubClass(); // SubClass variable referencing a SubClass instance
a.Foo(); // prints "base foo"
b.Foo(); // prints "sub foo", because Foo() is overridden
c.Foo(); // prints "sub foo"
a.Bar(); // prints "base bar"
b.Bar(); // prints "base bar", because Bar() was NOT overridden
c.Bar(); // prints "sub bar", because SubClass has its own Bar() function