Montag, Mai 25, 2020

Warum eine Funktion mit geschützten modifier außer Kraft gesetzt werden können und zugänglich sind alle wo?

Ich bin C# – Programmierer, der neu D Sprache. Ich bin ein bisschen verwirrt mit OOP in D programming language.

Davon aus, dass ich die folgende Klasse:

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

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

Den protected Modifikator bedeutet, dass ich Zugriff auf die .foo() Methode nur auf vererbte Klasse,warum also dieser D Programm kompiliert normalerweise?

Hier ist das äquivalent zu 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();
   }
};

Es nicht kompiliert werden, und die folgende Fehlermeldung(wie von mir erwartet):

test.cs(10,30): Fehler CS0507: B.foo()': cannot change access
modifiers when overriding
geschützten „vererbten member“ A. foo()‘

Kann sich das jemand erklären D Verhalten? Vielen Dank im Voraus.

  • Warum sind Sie verwirrt? C# und D sind nur verschiedene Sprachen, so dass Sie die Dinge anders. Auf den ersten Blick, beide Ansätze machen einige Sinn für mich, so ist es die Sprache, die Designer, um zu entscheiden, welchen Weg zu gehen.
  • Humm,denn ich hatte im Hinterkopf, dass die Zugriffs-Modifizierer einer Objekt-orientierten Programmiersprache betrieben in der gleichen Weise.
  • downvotes – können erklären, bitte?
  • Und Sie tun das Gegenteil in C# finden Sie unter msdn.microsoft.com/en-us/library/aa288461%28v=vs.71%29.aspx ; also public/protected auf private. interface I { void foo(); } class A { virtual public void foo() {} } class B : A, I { void I. foo() {} }
  • Sie sind sicherlich nicht arbeiten auf die gleiche Weise. Zum Beispiel, C++ nicht haben internal und C# nicht friend. Oder Python, die haben nicht zugriffsmodifizierer an alle. Es gibt keinen standard, was zugriffsmodifizierer sollte eine Objekt-orientierte Sprache haben. Jede Sprache ist einfach anders.
  • C# hat eine Menge von Einschränkungen, die dazu bestimmt sind, um Fehler zu reduzieren. „denn ich hatte im Hinterkopf, dass die Zugriffs-Modifizierer einer Objekt-orientierten Programmiersprache wird in der gleichen Art und Weise“ — Das macht die Frage nicht beantworten. Warum haben Sie das im Hinterkopf? Es gibt keine rationale Grundlage für einen solchen glauben.

InformationsquelleAutor Jack | 2012-05-05

3 Kommentare

  1. 18

    Gibt es keinen Zweck hat zu verhindern das überschreiben. Die abgeleitete Klasse implementieren können ein bagatell-forwarding-Funktion, die den Zugriff ermöglicht. Bedenken Sie:

    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!
       }
    };

    So, auch wenn ich nicht neu definieren, die Zugriff foo ich noch erlaubt den öffentlichen Zugang zu es und es gibt nichts, was Sie dagegen tun können. Erlaubt die Neudefinition ist nur einfacher.

    • Humm,dann ist Es D designer. In der C#.NET Sprache, es ist nicht möglich etwas schreiben, wie die call_foo() Methode. Es erhält eine error CS0122: A.foo()' is inaccessible due to its protection level. vielen Dank für die Antwort. 🙂
    • Was, in C# kann man nicht schreiben, eine öffentliche Methode, die fordert, eine protected-Methode?
    • Nein. Nicht für mich funktioniert,habe ich getestet, auf C#-Mono-und-es angesichts der oben genannten Fehlermeldung.
    • Das ist, weil Sie genannt A.foo() direkt in deinem ursprünglichen Beispiel. Haben Sie einen Blick auf dieser, es scheint gut zu funktionieren.
  2. 8

    Da gibt es einige tolle Antworten auf die Frage „warum ist das möglich?“ Ich denke, dass C# verdient eine Erklärung, warum es NICHT möglich ist: Es geht um die „Philosophie“ einer Sprache, die von design, und kann verkuerzt werden, um „ist-ein“ vs. „hat-ein“ Kampf der Ideen.

    C++ ist „hat-ein“ denken, einige der ihm übergeben wurde, zu D und Java. B hat Methode foo – und dies ist besonders wichtig, für die sowohl der compiler und Programmierer – nicht das, was B ist. In C++ ist es sogar möglich, deklarieren Sie eine Methode als private (oder Erben von der Klasse als private), was bedeutet, dass ein Mitglied einer NICHT ausgesetzt durch B.

    C# ist hardcore über „is-a“ – Konzept. Deshalb, weil hier B tatsächlich ist Ein, alles, was in B sein muss, gerade wie in A. Weder der compiler noch der Programmierer Gedanken über änderungen, da keine änderungen möglich sind. B ist immer eine perfekte drop-in-Ersatz für A.

    Den „ist-ein“ – Philosophie verbietet C# – Programm aus der Veröffentlichung zuvor geschützte member, obwohl es trivial, um es über eine öffentliche wrapper. Es macht wenig Sinn und ist nur eine kleine Unannehmlichkeit hier – aber es ist eine große Sache dabei, die Sprache der Philosophie im Einklang.

  3. 6

    D ‚ s Verhalten in diesem Spiele Java Verhalten. Eine abgeleitete Klasse kann seine Funktion, ein access-level, die weniger restriktiv sind als die, die auf die Funktion in der Basisklasse, aber nicht eines, das mehr restriktiv. So, ein protected Funktion kann überschrieben werden, entweder als protected oder public, aber es kann nicht außer Kraft gesetzt werden, wie private, und ein public Funktion kann nur überschrieben werden, wie public.

    Ich habe keine Idee, warum C# beschränken würde protected so dass Sie konnte nicht überschreiben es mit einer public Funktion. Als jemand, der ‚ s programmiert sehr viel in C++, D, Java aber nur sehr wenig in C#, C#’s Wahl hier macht sehr wenig Sinn für mich. C++, D, Java und alle es zulassen.

Kostenlose Online-Tests