When defining what data and methods belong to a class, you also get to set accessibility levels so that some things are available for general use while other members are more restricted. Why not just make everything available? Then you don’t have to worry about it, right? Learning proper access control will help you write code that’s actually easier to understand and easier to use. This episode will explain why.
The access levels discussed that apply to both C++ and C# are:
public – Makes members available to any code in the application.
protected – Makes members available only to classes that derive from your class.
private – Allows only the class itself to have access.
And the access levels that apply only to C# are:
internal – Makes members available only to code within the same assembly.
protected internal – Makes members available only to code within the same assembly or to any derived class either in the same assembly or not.
If you want a starter class that you can use to create all of your classes, just go to takeupcode.com/offers where you’ll find links to all our special offers.
Listen to the full episode or read the full transcript below.
Picture yourself in a small clothing store that has an area in front to display merchandise. You’re looking around when you see a door with a sign that says “Private: Employees Only.”
That sign is there to let you know what parts of the store you should not visit. Employees of the store are allowed to enter but the general public really has no business in that part of the store.
Imagine if this concept didn’t exist and you’re browsing the store when you see an interesting shirt with no price tag. You take the shirt to the counter only to find out that it’s not for sale because it needs some modification first. This isn’t the best shopping experience and it gets worse. You take the shirt back and can’t remember exactly where you found it so you put it down on another table. Later when the owner of the store arrives, he can’t find the shirt he was working on the day before.
Keeping things private not only helps the consumer, it also helps the employees. And the same concept applies to object-oriented programming.
When you create a class, you’ll need to specify which methods are public. You can also make data members public but I don’t recommend that.
Instead of making a data member public, keep it private instead and create methods that get and set the data value. These methods are called getters and setters. If you only want consumers to be able to read the data, then either don’t create a setter or keep the setter private.
If you don’t specify anything for public or private, then by default C++ and C# classes start out as private. If everything’s private, then your class won’t be much use to anybody. In C++, this default level is really the only difference between classes and structs. Classes start out private until you specify otherwise and structs start out as public until you specify otherwise. There’re some other differences between languages that I’ll explain in just a moment.
When I say that you’re creating a class, I’m not talking about creating instances of your class in code. I’m talking about creating a new source file and header file, if applicable, and writing the definition of the new class. You’ll need to give the class a name, declare methods and data members, and figure out which methods should be public. Creating a class means that you’re writing the definition and code that make up the class.
You can do some interesting things with accessibility levels. For example, if you make all your class constructors private, then no other code will be able to create instances of your class. What good is that you might wonder? Well, you could then create a public method that other code can call and this method will have access to the constructors because it’s a member of the class. But isn’t that what constructors do? Constructors allow other code to create instances of your class directly. But with this technique, you can control the creation of your class however you want. This is an example of a software pattern called a Singleton. Patterns will also need future episodes.
There’s one more detail to this technique. If other code can’t create instances, then how will the other code be able to call a method? It seems like a chicken and egg problem. What we need to solve this is the ability to call class methods even without having an instance of the class. You can do this with static methods which we’ll talk about in another episode. Just know for now that by making a public static method, then consumers will be able to call the method without creating an instance of the class. Then because the public static method is part of the class, it has access to the private methods including the private constructors and can create a new instance to return to the calling code. And once the other code has an instance, it can then call other public methods.
Public and private are fairly easy to understand. Public makes class members visible and available outside of the class and private keeps members hidden and only available to code that belongs to the class methods.
Most programming languages will also have another accessibility level called protected. This is like private except that protected members are available for use in derived classes. We’ll discuss derived classes and inheritance in the next episode. I actually thought about introducing inheritance first before talking about accessibility but there’s public vs. private inheritance to consider. Plus, I think learning about accessibility levels first is the right way anyway because you need to know this in order to write even a basic class. Any other code trying to use your class won’t be able to tell the difference between protected and private. They both declare members to be off limits to outside code.
C++ has a useful ability to declare other classes and methods to be friends. When you’re writing your class, you may find that you want some members to be off limits for other code except very special methods or classes. Protected won’t always help because for one, protected only works with other classes that derive from your class. So a normal method is completely out of luck. Protected just won’t help with another method. And maybe you don’t want another special class to have to inherit from your class in order to gain access. Instead of relying on protected access level, you can declare the other class or method to be a friend of your class. This grants that other class or method full access to your class.
Just like in real life, you can’t declare that you’re friends with somebody who doesn’t know you. In programming terms, you can’t just declare friendship from the receiving end of that friendship. This means that if a class has private methods or private data that you want to access from another method, you can’t just declare from that other method that it’s a friend and expect to be given access. You can only declare the other method to be a friend from within the class that’s granting friendship.
C# not only has some extra accessibility levels that need explaining but it’s also a bit more complicated. Unlike C++ where you put labels in your class for public, protected, or private that then apply to everything from that point until either the end of the class or until a new label is found, in C# you label everything directly. Need a class method? If you don’t specify otherwise, it’ll be private. and you also need to give the class itself an accessibility level otherwise the class itself will be given the level of internal. This applies to class definitions that are not nested inside other class definitions. For nested classes, the default level is private just like any other default class member.
So what does internal mean? We’ll need another episode to fully understand this. But for now, just know that everything you write in C# eventually becomes part of an assembly. Assemblies form the pieces of your application that you distribute to your customers. Anything that has an accessibility level of internal is available to any code within the same assembly. It doesn’t matter if the other class is a derived type or not.
And C# has one more level that’s a combination of protected and internal and is called protected internal. I think the language designers missed a good opportunity to coin a new term printernal. This combination makes class members available to anything within the same assembly or to any derived classes which can be outside the assembly. There’s no combination that will restrict access only to derived classes within the same assembly.
There’re other details that you’ll surely come across while programming. This episode would just be too tedious if I tried explaining all of them. There’s lots of good information available online that you can find just by searching for C++ access levels or C# access levels.
If you want a starter class that you can use to create all of your classes, just go to takeupcode.com/offers where you’ll find links to all our special offers. There’s currently a starter class for C++ and I’ll create one for C# soon. This link is also in the show notes page for this episode. All you have to do is copy and paste the starter class into your own project and modify it to suite your needs. You’ll see exactly how I use public and private in the class to control access. And there’s quite a few other features included too.