I understand that a private protection level is meant to stop any child accessing private parent variables.
But isn't there a way to do it with accessors and mutators(get and set)? I have to have some kind of way to change a private string because that is the homework.
I have a public abstract pet class with a private string for a name. I want to create a dog and use that string name. I can't figure it out though. Since it is homework, I understand I cannot be given code or anything, but could someone point out the method to do this so I can google it? All my searches just imply that it is impossible.
Here's my code if it will help.
edit I can't just make it protected.
public abstract class Pet
{
private string name;
private string species;
public abstract void speak();
public abstract void play();
public abstract void info();
}
Part of the child dog class...
class Dog : Pet
{
public Dog(string xname, string xspecies)
{
this.name = xname; // this is where I'm having trouble.
}
Let's make sure that you have a clear and accurate understanding; many beginners are taught subtle falsehoods.
That's a correct summary of the intention of the feature. Basically you are saying that access control modifiers are for controlling access, which should not be a surprise.
However there are two subtleties that I want to point out here.
The first is that access modifiers control access to the names of things, not to the things. When you have a member named
foo, the namefoomay only be used to refer to that member from within the accessibility domain of that member. The "accessibility domain" is a region of program text; the accessibility domain of a private member is the text of the type which declares the member.If you have come up with some other way to refer to a member, that mechanism is not controlled by the accessibility modifier. The only thing an accessibility modifier controls is where the name may be used in the text of the program.
Make sure that is clear in your head.
Second, you note that a
privatemember is not accessible to a "child", by which I assume you mean a derived class. There is a situation in which a derived class can access private member by name. Given what I've said so far, you should be able to deduce what it is. Give it some thought and then read on.I said that a private member is accessible by name only inside the text of the declaring type, so if a private member is accessible by name by a derived class, the derived class must be inside the text of the declaring type:
This is legal because
xis used by name inside its accessibility domain.So, how do you do your homework problem? There are only two ways:
(1) Put
Doginside ofPet; anyDogthen has access to all the private members ofPet. This is a "for advanced players only" feature of C# and almost certainly not what your instructor is looking for. But it is a really powerful technique and I use it frequently, so keep it in mind for your later career; in particular, when you learn about the "factory pattern" you can pull out of your back pocket the knowledge that putting the derived classes inside the base class is a good trick for making the factory pattern work well.(2) Make some accessor mechanism for the private member, and make that accessor mechanism's name protected, internal, or public.
Typically you'd use a property. You make an property with a read-only accessor in C# like this:
Or, in more modern versions of C# you can use this short form:
And now code outside of
Basecannot usexby name, because that is outside of the accessibility domain ofBase.x. ButXhas an unrestricted accessibility domain, so it can be used anywhere you like.That's a read-only accessor. To make a write accessor you add a setter:
Notice that setters have a magic
valuename that is the value that is to be assigned to the property.There are other ways to make accessors but this is by far the most common.
While we are looking at your code, a couple other things:
(1)
Public methods should be
PascalCasedLikeThis, notlowercase, in C#. It's just an arbitrary convention that makes it easier to read your code.(2)
Why is
infovoid returning? Surely it should be returning some info.(3)
Is your intention to further subclass
Dog? Probably not, because it is notabstract. Consider marking classes not intended to be subclassed assealed, so that you do not have to worry about designing the class for safe inheritance.