Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why a function with protected modifier can be overridden and accessible every where?

I'm C# programmer new to D language. I'm a bit to confused with OOP in D programming language.

Assuming that I have the following class:

public class A {
   protected void foo() {
      writefln("A.foo() called.");
   }
};

public class B : A {
   public override void foo() {
      writefln("B.foo() called.");
   }
};

The protected modifier means that I can access the .foo() method just on inherited class,so why this D program compiles normally?

Here is the equivalent to C#.NET:

using System;

public class A {
   protected virtual void foo() {
      Console.WriteLine("a.foo() called.");
   }
};

public class B : A {
   public override void foo() {
      Console.WriteLine("b.foo() called.");
   }
};

public class MainClass  {
   public static void Main(string[] args) {
      A a = new A();
      B b = new B();    
      a.foo();
      b.foo();
   }
};

It don't compiles and given the following error message(as I expected):

test.cs(10,30): error CS0507: B.foo()': cannot change access modifiers when overridingprotected' inherited member `A.foo()'

Can someone explain this D behavior? Thanks in advance.

like image 946
Jack Avatar asked May 05 '12 01:05

Jack


2 Answers

There's no purpose in preventing the override. The derived class could implement a trivial forwarding function that allows access. Consider:

public class A {
    protected void foo() {
        writefln("A.foo() called.");
    }
};

public class B : A {
   protected override void foo() { // OK
       writefln("B.foo() called.");
   }
   public void call_foo() {
       foo(); // But I allowed public access anyway!
   }
};

Thus, even though I didn't redefine the access level of foo, I still allowed public access to it and there's nothing you can do about it. Allowing the redefinition is just simpler.

like image 168
Puppy Avatar answered Sep 27 '22 17:09

Puppy


Because there are some great answers to the the question "why it's possible?" I think C# deserves explanation why it's NOT possible: It's about the "philosophy" of a language design, and can be boiled down to "is-a" vs "has-a" clash of ideas.

C++ is all about "has-a" thinking, some of it was passed to D and Java. B has method foo and this is most important for both the compiler and the programmer - not what B is. In C++ it's even possible to redeclare a method as private (or inherit class as private) which means that a member of A will NOT be exposed by B.

C# is hardcore about "is-a" concept. Therefore because here B actually is A, everything in B must be just like in A. Neither compiler nor the programmer have to worry about changes, because no changes are possible. B always is a perfect drop-in replacement for A.

The "is-a" philosophy forbids C# program from publicising previously protected member, even though it's trivial to do it via a public wrapper. It makes little sense and is just a small inconvenience here - but it's a big deal in keeping the language philosophy consistent.

like image 28
Agent_L Avatar answered Sep 27 '22 16:09

Agent_L