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
geschützten "vererbten member" A. foo()'
modifiers when overriding
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# nichtfriend
. 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.
Du musst angemeldet sein, um einen Kommentar abzugeben.
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:
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.D
designer. In derC#.NET
Sprache, es ist nicht möglich etwas schreiben, wie diecall_foo()
Methode. Es erhält eineerror CS0122: A.foo()' is inaccessible due to its protection level.
vielen Dank für die Antwort. 🙂A.foo()
direkt in deinem ursprünglichen Beispiel. Haben Sie einen Blick auf dieser, es scheint gut zu funktionieren.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.
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 alsprotected
oderpublic
, aber es kann nicht außer Kraft gesetzt werden, wieprivate
, und einpublic
Funktion kann nur überschrieben werden, wiepublic
.Ich habe keine Idee, warum C# beschränken würde
protected
so dass Sie konnte nicht überschreiben es mit einerpublic
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.