The best way to learn is to keep things simple and practice (program) a lot.
Regarding virtual/new/override, there are three main cases:
virtual + override
Use virtual in the base class and override in the derived class as in
class BaseClass
{
public void virtual Test(){...}
}
class DerivedClass: BaseClass
{
public void override Test(){...}
}
abstract + override
This is a variant of the previous case where the base member does not define a body
abstract class BaseClass
{
public void abstract Test(){...}
}
class DerivedClass: BaseClass
{
public void override Test(){...}
}
No modifier
This is useful when you don't plan on overriding a method
class BaseClass
{
public void Test(){...}
}
class DerivedClass: BaseClass
{
public void OtherMethod(){...}
}
In the this case, there would be a warning if "OtherMethod" was named "Test". Indeed, it would clash with the base method. You can get rid of the warning by adding a "new" modifier as in
abstract class BaseClass
{
public void Test(){...}
}
class DerivedClass: BaseClass
{
public new void Test(){...}
}
However, I would recommend avoiding the "new" modifier if possible since it is somewhat confusing.