Um zu verdeutlichen, was ich frage ist
public class A{
private/*or public*/ B b;
}
gegen
public class A{
private/*or public*/ class B{
....
}
}
Ich kann mir auf jeden Fall einige Gründe vorstellen, um den einen oder anderen zu verwenden, aber was ich wirklich sehen möchte, sind überzeugende Beispiele, die zeigen, dass die Vor- und Nachteile nicht nur akademisch sind.
object-oriented-design
class-design
EpsilonVector
quelle
quelle
Antworten:
Sie werden normalerweise verwendet, wenn eine Klasse ein internes Implementierungsdetail einer anderen Klasse ist und nicht Teil ihrer externen Schnittstelle. Ich habe sie meistens als reine Datenklassen angesehen, die die internen Datenstrukturen in Sprachen, die keine separate Syntax für Strukturen im C-Stil haben, sauberer machen. Sie sind manchmal auch nützlich für stark angepasste, von einer Methode abgeleitete Objekte wie Ereignishandler oder Arbeitsthreads.
quelle
Angenommen, Sie erstellen einen Baum, eine Liste, ein Diagramm usw. Warum sollten Sie die internen Details eines Knotens oder einer Zelle der Außenwelt aussetzen?
Wenn Sie ein Diagramm oder eine Liste verwenden, sollten Sie sich nur auf die Benutzeroberfläche und nicht auf die Implementierung verlassen, da Sie sie möglicherweise eines Tages in der Zukunft ändern möchten (z. B. von einer Array-basierten auf eine Pointer-basierte Implementierung) und auf die Clients, die Ihre verwenden Die Datenstruktur ( jeder von ihnen ) müsste ihren Code ändern, um ihn an die neue Implementierung anzupassen.
Wenn Sie stattdessen die Implementierung eines Knotens oder einer Zelle in eine private innere Klasse einkapseln, können Sie die Implementierung jederzeit ändern, ohne dass die Clients gezwungen sind, ihren Code entsprechend anzupassen, solange die Schnittstelle Ihrer Datenstruktur erhalten bleibt unberührt.
Das Ausblenden der Details der Implementierung Ihrer Datenstruktur führt auch zu Sicherheitsvorteilen, da Sie, wenn Sie Ihre Klasse verteilen möchten, nur die Schnittstellendatei zusammen mit der kompilierten Implementierungsdatei zur Verfügung stellen und niemand weiß, ob Sie tatsächlich Arrays oder Zeiger verwenden für Ihre Implementierung, um Ihre Anwendung vor einer Ausbeutung oder zumindest vor Wissen zu schützen, da es unmöglich ist, Ihren Code zu missbrauchen oder zu überprüfen. Bitte unterschätzen Sie neben praktischen Aspekten nicht, dass es sich in solchen Fällen um eine äußerst elegante Lösung handelt.
quelle
Meiner Meinung nach ist es ein fairer Cop, intern definierte Klassen für Klassen zu verwenden, die kurz in einer Klasse verwendet werden, um eine bestimmte Aufgabe zu ermöglichen.
Wenn Sie beispielsweise eine Datenliste binden müssen, die aus zwei unabhängigen Klassen besteht:
Wenn Ihre interne Klasse von einer anderen Klasse verwendet wird, sollten Sie sie separat platzieren. Wenn Ihre interne Klasse eine Logik enthält, sollten Sie sie separat platzieren.
Grundsätzlich finde ich sie großartig, um Lücken in Ihren Datenobjekten zu schließen, aber sie sind schwierig zu pflegen, wenn sie tatsächlich Logik enthalten müssen, da Sie wissen müssen, wo Sie danach suchen müssen, wenn Sie sie ändern müssen.
quelle
tuple.ItemX
macht das den Code unübersichtlich.Innere Klassen in einer bestimmten Sprache (z. B. Java) sind an ein Objekt ihrer übergeordneten Klasse gebunden und können ihre Mitglieder verwenden, ohne sie zu qualifizieren. Wenn verfügbar, ist es klarer als eine Neuimplementierung mit anderen Sprachfunktionen.
Geschachtelte Klassen in einer anderen Sprache (z. B. C ++) haben keine solche Bindung. Sie verwenden einfach die von der Klasse bereitgestellte Bereichs- und Zugriffskontrolle.
quelle
Ich vermeide innere Klassen in Java, da das Austauschen im laufenden Betrieb nicht funktioniert, wenn innere Klassen vorhanden sind. Ich hasse das, weil ich es wirklich hasse, den Code für solche Überlegungen zu kompromittieren, aber diese Tomcat-Neustarts summieren sich.
quelle
Eine der Anwendungen für die private statische innere Klasse ist das Memo-Muster. Sie ordnen alle Daten, die gespeichert werden müssen, einer privaten Klasse zu und geben sie von einer Funktion als Objekt zurück. Niemand außerhalb kann es (ohne Reflektion, Deserialisierung, Speicherinspektion ...) untersuchen / modifizieren, aber er kann es Ihrer Klasse zurückgeben und es kann seinen Zustand wiederherstellen.
quelle
Ein Grund für die Verwendung einer privaten inneren Klasse könnte sein, dass für eine von Ihnen verwendete API die Vererbung einer bestimmten Klasse erforderlich ist, Sie jedoch das Wissen dieser Klasse nicht an Benutzer Ihrer äußeren Klasse exportieren möchten. Beispielsweise:
In diesem Fall erfordert do_my_async_op, dass ein Objekt vom Typ Rückruf an dieses Objekt übergeben wird. Dieser Rückruf hat eine Signatur einer öffentlichen Memberfunktion, die von der API verwendet wird.
Wenn do_op () von der äußeren Klasse aufgerufen wird, verwendet es eine Instanz der privaten inneren Klasse, die von der erforderlichen Rückrufklasse erbt, anstatt eines Zeigers auf sich selbst. Die äußere Klasse hat einen Verweis auf die äußere Klasse, um den Rückruf einfach in die private Memberfunktion do_callback der äußeren Klasse umzuleiten.
Dies hat den Vorteil, dass Sie sicher sind, dass niemand die öffentliche "fire ()" - Memberfunktion aufrufen kann.
quelle
Laut Jon Skeet in C # in Depth war die Verwendung einer verschachtelten Klasse die einzige Möglichkeit, einen vollständig faulen thread-sicheren Singleton (siehe Fünfte Version) (bis .NET 4) zu implementieren .
quelle
Private und innere Klassen werden verwendet, um den Kapselungsgrad zu erhöhen und Implementierungsdetails zu verbergen.
In C ++ kann das gleiche Konzept zusätzlich zu einer privaten Klasse erreicht werden, indem der anonyme Namespace einer Klasse cpp implementiert wird. Dies dient zum Verbergen / Privatisieren eines Implementierungsdetails.
Es ist die gleiche Idee wie eine innere oder private Klasse, jedoch auf einer noch größeren Ebene der Kapselung, da es außerhalb der Kompilierungseinheit der Datei vollständig unsichtbar ist. Nichts davon erscheint in der Header-Datei oder ist in der Deklaration der Klasse äußerlich sichtbar.
quelle