Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why have class-level access modifiers instead of object-level?

While using C#, I recently realised that I can call a Foo object's private functions from Foo's static functions, and even from other Foo objects. After everything I have learned about access modifiers, this sounds very strange to me.

As far as I know, you make a function private when it does something that's part of some kind of internal process. Only the object itself knows when to use those functions, because other objects shouldn't/can't control the object's flow. Is there any reason why other objects of the same class should be excepted from this pretty straightforward rule?

As per request, an example:

public class AClass {
    private void doSomething() { /* Do something here */ }
    public void aFunction() {
        AClass f = new AClass();
        f.doSomething(); // I would have expected this line to cause an access error.
    }
}
like image 280
Lee White Avatar asked May 03 '13 08:05

Lee White


People also ask

What are class access modifiers?

Access modifiers (or access specifiers) are keywords in object-oriented languages that set the accessibility of classes, methods, and other members. Access modifiers are a specific part of programming language syntax used to facilitate the encapsulation of components.

Can object of a class access private members?

This is perfectly legal. Objects of the same type have access to one another's private members. This is because access restrictions apply at the class or type level (all instances of a class) rather than at the object level (this particular instance of a class).

Which of the below access specifiers can be used to access classes only inside the package?

The private modifier specifies that the member can only be accessed in its own class. The protected modifier specifies that the member can only be accessed within its own package (as with package-private) and, in addition, by a subclass of its class in another package.

Which access modifier makes variables and methods visible only in the class where they are declared?

Private: The private access modifier is specified using the keyword private. The methods or data members declared as private are accessible only within the class in which they are declared.


4 Answers

The private modifier enforces Encapsulation principle.

The idea is that 'outer world' should not make changes to AClass internal processes because AClass implementation may change over time (and you would have to change the whole outer world to fix the differences in implementation - which is nearly to impossible).

When instance of AClass accesses internals of other AClass instance - you can be sure that both instances always know the details of implementation of AClass. If the logic of internal to AClass processes is changed - all you have to do is change the code of AClass.

In some other languages, however, private works on instance level, but this is not true in C#.

like image 154
Artemix Avatar answered Sep 28 '22 05:09

Artemix


When you make a member private, it's private to other classes not the class itself.

It can be useful for instance if you have an Equals method which needs access to another instance's private members:

public class AClass
{
    private int privateMemberA;

    // This version of Equals has been simplified
    // for the purpose of exemplifying my point, it shouldn't be copied as is
    public override bool Equals(object obj)
    {
        var otherInstance = obj as AClass;
        if (otherInstance == null)
        {
            return null;
        }

        return otherInstance.privateMemberA == this.privateMemberA;
    }
}
like image 29
Sam Bauwens Avatar answered Sep 28 '22 05:09

Sam Bauwens


Private members are only accessibly from all other members within the scope of that class. It does not matter if this is done by multiple instances or one instance.

You are trying to restict members to be only called from this., so they are not allowed to be called from the outside world (seen from the point of view of the instance), but they are allowed to be called once you have entered the scope of your instance. This is simply not possible in C#.

Would be a nice feature though... :)

like image 36
Martin Mulder Avatar answered Sep 28 '22 05:09

Martin Mulder


The private (C# Reference) topic says:

The private keyword is a member access modifier. Private access is the least permissive access level. Private members are accessible only within the body of the class or the struct in which they are declared (...)

Even more:

Nested types in the same body can also access those private members.

So the following code will work perfectly.

class Foo
{
    private void PrivateMethod()
    {
    }
    class FooBaby
    {
        public static void MethodB()
        {
            Foo foo = new Foo();
            foo.PrivateMethod();
        }
    }
}

Concerning the question "why" classes have access modifiers and not the objects, it's one of the ways through which information is hidden in OOP (read more about Encapsulation (object-oriented programming).

I also recommend you to go through the chapters:

  • 10.5 Member access
  • 17.2.3 Access modifiers

of the Standard ECMA-334 C# Language Specification.

like image 31
Alex Filipovici Avatar answered Sep 28 '22 04:09

Alex Filipovici