The public access modifier marks a type and a member of a type as accessible from external libraries. This means if you have a type in assembly A, and you add a reference to it from assembly B, it means you can access that type/member from types exposed in assembly B. There are other access modifiers (read up about them here).
Knowing how access modifiers change the behaviour of types is an important part of object orientated design.
virtual members allow a type to provide a default implementation of specific functionality. For example, if I had a type:
public class Logger {
protected virtual void Write(string message) {
Console.Write(message);
}
}
I could have a type:
public class DebugLogger : Logger {
}
That type will expose my default implementation of Write as the method Logger.Write. I could (optional) override this behaviour:
public class DebugLogger : Logger {
protected override void Write(string message) {
Debug.Print(message);
}
}
Using this use of virtual/override allows classes to optional customise their behaviour, and when Write is called with a reference simple to a Logger instance, the correct implementation will be called (so, the overriden method in the latter case).
private members are used to contain members that should not be exposed outside of the parent type. E.g. a backing field for a property will almost always be private.
The general rule I follow is:
public members expose specific functionality I want to be usable from external types/assemblies.
protected members expose specific functionality I want to be usable from inheriting types only.
private members hide functionality that I want to contain to just the parent type. E.g. I want a use a method which is specific to the type and has no benefi being exposed publicly. E.g. state mutation methods that I want to control from external access, etc.
Others:
internal allows me to mark members as accessible within only the assembly that contains them. This is useful when you need to expose things like builder methods, etc. which are specific to the containing assembly, that you don't want to mark as public but cannot be used as private members.
- I rarely use
protected internal.
Hope that helps!