Lets take a look at a few examples, first the public class with private/protected members:
public class PublicClass
{
public void PublicMethod()
{
ProtectedMethod(); //Valid call
PrivateMethod(); //Also valid
}
protected void ProtectedMethod()
{
PublicMethod(); //Valid
PrivateMethod(); //Valid
}
private void PrivateMethod()
{
PublicMethod(); //Valid
PrivateMethod(); //Valid
}
}
public class SomeOtherClass
{
public void SomeMethod()
{
PublicClass c = new PublicClass();
c.PublicMethod(); //Valid
c.ProtectedMethod(); //Invalid, not accessible
c.PrivateMethod(); //Also invalid
}
}
Here, all these class calls are valid internally, but PrivateMethod
is not visible to anything outside the PublicClass
, including any class that derives from PublicClass
. ProtectedMethod
is also hidden outside of the class but is still accessible to classes that inherit PublicClass
, like this:
public class InheritedPublicClass : PublicClass
{
public void MyPublicMethod()
{
PublicMethod(); //Calls base class method
ProtectedMethod(); //Calls base class method
PrivateMethod(); //Invalid, not accessible
}
}
The call to PrivateMethod()
is a compile time error because it is not accessible to the InheritedPublicClass
.
Private allows you to create methods that are only visible to the immediate class, and nothing outside of it. Protected allows you to create methods that are visible internally, and visible to any class that derives from it.
Now lets look at a private class:
public class ParentClass
{
private class NestedClass
{
public void PublicMethod() { }
private void PrivateMethod() { }
}
private void SomeMethod()
{
//NestedClasscan only be created by methods of ParentClass
var nc = new NestedClass();
nc.PublicMethod(); //Internally visible
nc.PrivateMethod(); //Invalid, not accessible
}
}
Here NestedClass
is private because it is nested inside ParentClass
. It is not visible to anybody outside of NestedClass
including inheritors. If we made it protected, then inheritors would be able to see it.
Again, NestedClass.PrivateMethod()
is not visible outside of the implementation of the nested class.
This is useful for internal data structures that don't have any meaning outside of the class.