Calendar

<<  août 2008  >>
lumamejevesadi
28293031123
45678910
111214151617
181920222324
25262728293031
1234567

View posts in large calendar
Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2008

(janvier 30, 2008 09:09)

By chance, I have discovered something new related to the protected keyword yesterday. I was very surprised because I had never seen such a behavior in C++ or Java. But maybe I had never tested it in the past ? Anyway, I think it's important enough to share it with you.

Private keyword

Just for reminding, a private member will be visible only in the container object (class or structure). However, you can write something like :

public class ClassWithPrivate
{
   private int privateMember;
 
   public void DoSomething(ClassWithPrivate c)
   {
      /* The private members are also accessible on 
       * another instance, as long as you work with it
       * inside of the class */
      c.privateMember = 12;
   }
}

Protected keyword

With the previous example shown, we can expect a similar behavior with the protected keyword as it is an "extended private". Indeed a protected member will be visible in the container object and also in all the derived class of this object. However, there is a limitation when working with other instances as shown below:

public class BaseClass
{
   protected void DoSomething() { }
}
 
public class DerivedClass : BaseClass
{
   public void OtherMethod()
   {
      //The protected method of the base class is accessible on "this"
      this.DoSomething();
 
      //The protected method is accessible via another instance
      DerivedClass derived = new DerivedClass();
      derived.DoSomething();
 
      /* Compilation Error:
       * Cannot access protected member 'BaseClass.DoSomething()' 
       * via a qualifier of type * 'BaseClass'; the qualifier 
       * must be of type 'DerivedClass' (or derived from it)
       */
      BaseClass baseClass = new DerivedClass();
      baseClass.DoSomething();
   }
}

Experts of all language, can you tell me if you have this limitation also in your language ?

Extra question : I don't really see why we have this compilation error. Why this limitation exist ? DO you have any idea or clue ?

Billets liés

Commentaires

janvier 30. 2008 12:43

I've the same limitation in C++. For .net, it's written in the ECMA-334 but they aren't explicit about the reason ... (and I don't know why :/)

Thierry Thoua

janvier 30. 2008 18:19

I'm waiting for our C++ master that may light our darkness on. Didier are you there ? ;-)

For info, where have you seen that in the ECMA ? related to the protected keyword ? I'll have a look to it.

pe.dautreppe

janvier 30. 2008 22:29

http://en.csharp-online.net/ECMA-334:_10.5.3_Protected_access_for_instance_members

Thierry Thoua

février 5. 2008 14:57

The C++ behavior is similar to the C# one. To the contrary, Java is more permissive and allows the access.

I believe that there is no "technical reason" for this "limitation" (since it is always possible to render visible any field by making it public), but a language choice.

In C++, a derived object may access the protected members of its base class only through a derived object. The derived class has no special access to the protected members of base type objects [Lippman, 15.2.2].

I guess that the C# rule is similar (*). The second sentence makes the intent of the rule crystal-clear: if a BaseClass is used as a class of its own, its privacy has to be enforced against other classes, including from classes that are derived from it. The privacy must only be dropped-off for the BaseClass part of DerivedClass instances.

To the contrary, Java is more relax and allows DerivedClass instances to access protected members of any BaseClass instances. This means that Java weakens the encapsulation principle, which is bad from a pure OO point of view. But on the other side, it makes the access rule a bit simpler to understand, which is good too and is compatible with the principle of least astonishment Wink

Hope this help...
DP

(*) I can't access the link given by Thierry from here, so I can't check the C# rule.

Didier Pieroux

février 5. 2008 21:16

Just to put my salt :
object, ie System.Object, defines at least one protected method :
object MemberwiseClone(), which by default makes a shallow copy of the current instance.

If protected methods where accessible for all derived classes, anybody (as anybody inherits object) could call .MemberwiseClone().

Btw, did you know that System.Object wasn't the really base class ?
At least, if I believe the Reflector (Lutz Roeder's must-have), object overrides a Finalize() method.
So "someone" should declare a virtual or abstract Finalize() method, no ?
I really need to configure this symbol server I've so heard about :
http://tinyurl.com/yqsokg

Damien Pinauldt

février 11. 2008 00:31

If the compiler allowed this:

BaseClass baseClass = new DerivedClass();
baseClass.DoSomething();

then, since it has no way to distinguish the two, it would also have to allow the following:

BaseClass baseClass = new OtherDerivedClass();
baseClass.DoSomething();

where OtherDerivedClass is a different class derived from BaseClass (but not from DerivedClass).

However, to do so would violate the semantics of "protected", which dictates that visibility is restricted to derived classes of the method's owner.

DerivedClass is *not* derived from OtherDerivedClass, so it has no business invoking a protected method on an instance of that class. Therefore the compiler cannot allow the first formulation.

Laurent Bossavit

Ajouter un commentaire


 

  Country flag





Live preview

août 28. 2008 17:22

Powered by BlogEngine.NET 1.2.0.0 | Theme by Pierre-Emmanuel Dautreppe