Why can a function with a protected modifier be overridden and available everywhere?

I am a C # programmer, new to D. I got a little confused with OOP in D.

Assuming 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 only access the .foo() method from the inherited class, so why does this D program usually compile?

Here is the C # .NET equivalent:

 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 does not compile and does not receive the following error message (as I expected):

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

Can someone explain this behavior of D? Thanks in advance.

+6
source share
3 answers

There is no purpose in preventing overriding. The resulting class can 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, although I did not redefine the foo access level, I still allowed public access to it, and you can do nothing about it. Overrides are easier to resolve.

+17
source

Because there are some excellent answers to the question "why is this possible?". I think C # deserves an explanation of why this is NOT possible: it is about the โ€œphilosophyโ€ of language design and can be reduced to โ€œis-aโ€ versus โ€œhasโ€ a clash of ideas.

C ++ is all about thinking "has-a", some of which were passed to D and Java. B has a foo method, and this is most important for both the compiler and the programmer, not B. In C ++, you can even override a method as private (or inherit a class as private), which means that member A will NOT be displayed B.

C # - hardcore about the is-a concept. Therefore, since B really is A here, everything in B should be exactly the same as in A. Neither the compiler nor the programmer should worry about the changes, because no changes are possible. B is always the perfect replacement for A.

The is-a philosophy forbids the C # program to publish a previously protected member, although it is trivial to do this through a public shell. It makes little sense, and here it is just a slight inconvenience, but it is very important to adhere to the philosophy of language.

+7
source
Behavior

D in this corresponds to Java behavior. A derived class can give its function an access level that is less restrictive than that used for the base class function, but no more restrictive. Thus, the protected function can be redefined as protected or public , but it cannot be redefined as private , and the public function can only be redefined as public .

I have no idea why C # would restrict protected such that you could not override it with the public function. As someone who has programmed a lot in C ++, D and Java, but very little in C #, choosing C # here makes very little sense to me. C ++, D and Java all allow this.

+5
source

Source: https://habr.com/ru/post/914942/


All Articles