Overloading is providing multiple methods with the same name and different signatures:
void Foo() {...}
void Foo(int i) {...}
Overriding is used in inheritance to change the implementation per subclass:
class SomeBase {
public virtual void Foo() {}
}
class SomeOther : SomeBase {
public override void Foo() {
// different implementation, possibly calling base.Foo();
}
}
With the above, even if I do:
SomeBase obj = new SomeOther();
obj.Foo();
it will call the SomeOther.Foo
implementation. The method called depends on the instance type, not the variable.
Method hiding is the opposite; it replaces the method signature, but only applies if you call the method from the derived type:
class SomeBase {
public void Foo() {}
}
class SomeOther : SomeBase {
public new void Foo() {
// different implementation, possibly calling base.Foo();
}
}
Now:
SomeOther obj = new SomeOther();
SomeBase baseObj = obj;
obj.Foo(); // calls SomeOther.Foo
baseObj.Foo(); // calls SomeBase.Foo
i.e. the method calls depends on the variable, not the instance.