When I interview someone, I start the question phase with simple object-oriented questions to get a feel for the person. Am I interviewing someone who writes rote procedural code or do I have someone in front of me who thinks in terms of objects and relationships. Even more intriguing, am I talking to a functional wunderkind who will enlighten me in my own journey through code? I start off with the simplest of questions: what’s the difference between a class and an object? Of course, the topics usually end up deep into their own experience as I use technical questions for the response factor more than right or wrong answers. I’m more interested in the fact that someone is thoughtful, into programming, and able to learn rather than whether they memorized a textbook or interview prep site.
A person came to me today to ask me a question they had recently in an interview for a C# position: are private members inherited? The answer given was no, and the interviewee was promptly informed that answer was incorrect.
On one level, it would appear that classes don’t inherit private members. Public and protected members are accessible by the subclass, but those pesky privates seemingly can’t be accessed. Of course, they’re there, otherwise calls to the exposed methods would not work. Then, there’s always reflection to access them. But I’m not really concerned about reflection or lower-level activities such as memory access; I’m more interested in the higher level concept of inheritance. Is the private member passed on to the subclass?
The problem with the private member isn’t actually one of inheritance, it’s one of accessibility. Being a private member means it’s only accessible within its defining type. To discover if the private members are inherited, we can set up a simple test: define the subclass within its parent.
public class Person
{
private string message;
public override string ToString()
{
return message;
}
public static Person CreateEmployee()
{
return new Employee();
}
class Employee : Person
{
public Employee()
{
this.message = "I inherit private members!";
}
}
}
Run this within a Console application, and it will print the message on the screen: “I inherit private members!”
class Program
{
static void Main()
{
Console.WriteLine(Person.CreateEmployee());
}
}
Proof positive that private members are actually inherited. Remember, modifiers such as public, protected, private, and internal are all accessibility modifiers. These modifiers affect encapsulation rather than inheritance.
A class takes everything from its parent class; its instantiation will have every member. In most situations, those marked private are hidden from from the subclass. Using reflection follows this same behavior: with the example above, message will not be returned through type.GetMembers(BindingFlags.NonPublic|BindingFlags.Instance) despite the fact that it has been exposed.
I do, however, feel that the concept of encapsulation and inheritance coexist and are intertwined. Certainly, at a physical level, the instance of the object has the same memory, and therefore can access the functionality that has been hidden from it through the interface its parent has given it. But conceptually, one does not look at a class and consider members that have been hidden from view as being part of it. Instead, we think of a class as inheriting an interface and behavior, not the entire template. I may inherit my parents’ features, but their secrets are theirs to keep.
I did demonstrate a way to break the way many think about inheritance in C#. Some languages don’t allow access beyond the public interface even to their subclasses. In those languages, inheritance doesn’t break encapsulation, and I believe the case is stronger that encapsulation makes our conceptual view more valid. Don’t get me wrong though, the accessibility modifiers in C# are very useful, and I wouldn’t trade them for a more “pure” language.
If I were the one asking the interview question, I would not be interested if the candidate got the question right with a simple yes or no answer. I would ask why in either case. Most people probably would respond that “objects can’t access private members of the parent class,” despite the fact that I’ve proven it can be done. Does that make the person a bad developer? No, because that is true in nearly all situations, and it describes, without being too technical, encapsulation. That would be a good time for me to follow up with encapsulation. What if instead the person knew how to access the parent’s private members through inheritance, then proceeded to provide more information about encapsulation and inheritance? Well, kudos, maybe you read my blog? In all seriousness though, if someone came back to me with that information I would be impressed simply because they care enough about their craft to learn it, just as I am impressed when someone cares enough to discuss these topics at conferences because they are truly interested in learning.