Nur die 5 Minuten Überblick wäre schön ....Bitte erläutern Sie die Nützlichkeit von abstrakten Methoden in C#
Antwort
public abstract class Request
{
// each request has its own approval algorithm. Each has to implement this method
public abstract void Approve();
// refuse algorithm is common for all requests
public void Refuse() { }
// static helper
public static void CheckDelete(string status) { }
// common property. Used as a comment for any operation against a request
public string Description { get; set; }
// hard-coded dictionary of css classes for server-side markup decoration
public static IDictionary<string, string> CssStatusDictionary
}
public class RequestIn : Request
{
public override void Approve() { }
}
public class RequestOut : Request
{
public override void Approve() { }
}
Warum machst du das als abstrakte Methode und nicht als Schnittstelle? Ist es nur leichter, wenn Sie nur ein paar Dinge implementieren Request implementieren? –
Wie ist das ein reales Beispiel? – Oded
Eine abstrakte Klasse kann Methoden implementieren, so dass Sie dort möglicherweise ein Standardverhalten haben, nach dem ein Nachkomme anruft ... Sie können dies nicht mit einer Schnittstelle tun. –
für eine hausgemachte Version von Tetris Verwendet es, wo jeder Typ Tetraminos eine Klasse Kind war von die Tetramino-Klasse.
Sie könnten eine abstrakte Methode verwenden (anstelle einer Schnittstelle) jedes Mal, wenn Sie eine Basisklasse haben, die tatsächlich einige Implementierungscode enthält, aber es gibt keine vernünftige Default-Implementierung für eine oder mehrere seiner Methoden:
public class ConnectionFactoryBase {
// This is an actual implementation that's shared by subclasses,
// which is why we don't want an interface
public string ConnectionString { get; set; }
// Subclasses will provide database-specific implementations,
// but there's nothing the base class can provide
public abstract IDbConnection GetConnection() {}
}
public class SqlConnectionFactory {
public override IDbConnection GetConnection() {
return new SqlConnection(this.ConnectionString);
}
}
Schauen Sie sich einfach die Template Method Pattern an.
Angenommen, Sie haben einige Klassen, die den Zeilen in Ihrer Datenbank entsprechen. Vielleicht möchten Sie, dass diese Klassen als gleich gelten, wenn ihre ID gleich ist, denn so funktioniert die Datenbank. Sie könnten also die ID abstrahieren, weil Sie damit Code schreiben könnten, der die ID verwendet, aber nicht implementieren, bevor Sie die ID in den konkreten Klassen kennen. Auf diese Weise vermeiden Sie die Implementierung der gleichen equals -Methode in allen Entitätsklassen.
public abstract class AbstractEntity<TId>
{
public abstract TId Id { get; }
public override void Equals(object other)
{
if (ReferenceEquals(other,null))
return false;
if (other.GetType() != GetType())
return false;
var otherEntity = (AbstractEntity<TId>)other;
return Id.Equals(otherEntity.Id);
}
}
Ich bin kein C# Typ. Darf ich Java benutzen? Das Prinzip ist das gleiche. Ich habe dieses Konzept in einem Spiel verwendet. Ich berechne den Rüstungswert verschiedener Monster sehr unterschiedlich. Ich nehme an, ich könnte sie verschiedene Konstanten verfolgen lassen, aber das ist konzeptionell viel einfacher.
abstract class Monster {
int armorValue();
}
public class Goblin extends Monster {
int armorValue() {
return this.level*10;
}
}
public class Golem extends Monster {
int armorValue() {
return this.level*this.level*20 + enraged ? 100 : 50;
}
}
Wie beschrieben, bietet Ihr Beispiel eine Begründung für die Verwendung einer Schnittstelle, aber keine Rechtfertigung für die Verwendung einer abstrakten Klasse. – Brian
Ich denke, ich hätte 20 weitere Zeilen Code einfügen können, um es ausführlicher zu machen. Ich sehe auch, wie ich ein Interface wie Attackable hätte verwenden können, das (unter anderem) armorValue() als Mitglied hätte. Ich denke aber immer noch, dass dies den Punkt recht gut illustriert: Sowohl Goblins als auch Golems haben einen Rüstungswert, aber sie müssen anders berechnet werden. – corsiKa
Verwendung der abstrakten Methode ist sehr üblich, wenn Sie die Template Method Pattern verwenden. Sie können damit das Skelett eines Algorithmus definieren und Unterklassen bestimmte Schritte des Algorithmus modifizieren oder verfeinern, ohne seine Struktur zu ändern.
Werfen Sie einen Blick auf ein "real-world" Beispiel von doFactory's Template Method Pattern page.
public abstract class MyBaseController {
public void Authenticate() { var r = GetRepository(); }
public abstract void GetRepository();
}
public class ApplicationSpecificController {
public override void GetRepository() { /*get the specific repo here*/ }
}
Dies ist nur einige Dummy-Code, der einige realen Welt Code repräsentiert ich haben (der Kürze halber dies nur Beispielcode ist)
Ich habe 2 ASP MVC-Anwendungen, die ziemlich ähnliche Dinge zu tun. Sicherheit/Sitzung Logik (zusammen mit anderen Dingen) passiert das gleiche in beiden. Ich habe die Basisfunktionalität von beiden in eine neue Bibliothek abstrahiert, die beide erben. Wenn die Basisklasse Dinge benötigt, die nur aus der eigentlichen Implementierung erhalten werden können, implementiere ich diese als abstrakte Methoden. In meinem obigen Beispiel muss ich Benutzerinformationen aus einer Datenbank abrufen, um die Authentifizierung in der Basisbibliothek durchzuführen. Um die richtige DB für die Anwendung zu erhalten, habe ich eine abstrakte GetRepository
Methode, die das Repository für die Anwendung zurückgibt. Von hier aus kann die Basis eine Methode auf dem Repo aufrufen, um Benutzerinformationen zu erhalten und mit der Validierung fortzufahren, oder was auch immer.
Wenn eine Änderung an der Authentifizierung vorgenommen werden muss, muss ich jetzt nur eine Lib aktualisieren, anstatt doppelte Anstrengungen in beiden zu machen. Kurz gesagt, wenn Sie einige Funktionen implementieren möchten, aber nicht alle, dann funktioniert eine abstrakte Klasse großartig. Wenn Sie keine Funktionalität implementieren möchten, verwenden Sie eine Schnittstelle.
Die letzten zwei Sätze sind Gold. :) – GalacticCowboy
Das war ein großartiges Beispiel – Vamsi
Die .NET-Klassen Stream sind ein gutes Beispiel. Die Stream-Klasse enthält grundlegende Funktionen, die von allen Streams implementiert werden, und dann stellen bestimmte Streams spezifische Implementierungen für die tatsächliche Interaktion mit I/O bereit.
Die Grundidee, ist, die abstrakte Klasse zu haben, um das Skelett und die grundlegende Funktionalität zu liefern und lassen Sie einfach die konkrete Implementierung, um die genauen Details zur Verfügung zu stellen.
Angenommen, Sie haben eine Schnittstelle mit ... +20 Methoden, zum Beispiel eine List-Schnittstelle.
Wenn jemand eine Implementierung für diese Liste bereitstellen muss, muss er jedes Mal die Methode +20 implementieren.
Eine Alternative wäre, eine abstrakte Klasse zu haben, die die meisten Methoden bereits implementiert und den Entwickler nur einige davon implementieren lassen würde.
Zum Beispiel
eine unveränderbare Liste zu implementieren, muss der Programmierer nur diese Klasse zu erweitern und bieten Implementierungen für die get (int index) und Größe() -Methoden
AbstractList: List
+ get(index: Int) : Object { abstract }
+ size() : Int { abstract }
... rest of the methods already implemented by abstract list
In dieser Situation: get
und size
sind abstrakte Methoden der Entwickler muss implementieren. Der Rest der Funktionalität ist möglicherweise bereits implementiert.
EmptyList: AbstractList
{
public overrride Object Get(int index)
{
return this;
}
public override int Size()
{
return 0;
}
}
Während diese Implementierung absurd aussehen, wäre es sinnvoll sein, eine Variable zu initialisieren:
List list = new EmptyList();
foreach(Object o: in list) {
}
Null-Zeiger zu vermeiden.
Ein Beispiel
namespace My.Web.UI
{
public abstract class CustomControl : CompositeControl
{
// ...
public abstract void Initialize();
protected override void CreateChildControls()
{
base.CreateChildControls();
// Anything custom
this.Initialize();
}
}
}
- 1. Bitte erläutern Sie diese Objective-C-Code
- 2. Bitte erläutern Sie den folgenden C-Code?
- 3. Bitte erläutern Sie Vims Konfigurationsverzeichnishierarchie
- 4. Bitte erläutern Sie diese Syntax
- 5. System.Runtime.Remoting.Channels.CoreChannel.GetMachineIP() von .NET Reflector - bitte erläutern
- 6. Bitte erläutern Sie diese SerializationException zu mir
- 7. Bitte erläutern Sie mir folgende Clojure Code
- 8. Bitte erläutern Sie die @Produces Annotation in CDI
- 9. C Programmierung Anfänger - Bitte erläutern Sie diesen Fehler
- 10. Bitte erläutern Sie die Abfrage-Plan SQL Server wählt
- 11. Leere Endlosschleife und GC (JVM). Bitte erläutern Sie die Wirkung
- 12. Erläutern Sie bitte die Verwendung der Option orNull
- 13. Bitte erläutern Sie die Syntaxregeln und den Geltungsbereich für "typedef"
- 14. Bitte erläutern Sie diese frühe Beendigung der multiprocess.Process-Unterklasse?
- 15. Bitte erläutern Sie diese mongodb Abfrage und das Ergebnis
- 16. Android Fatal Ausnahme Threads Hierarchie (bitte erläutern)
- 17. Was macht diese SQL-Abfrage? Bitte erläutern Sie
- 18. Was sind "Reduktionssemantik"? Bitte erläutern Sie die Verwendung von PLT Redex in Laien-Begriff
- 19. Erstellen Sie eine Oberklasse mit abstrakten Variablen und nicht abstrakten Methoden in C#
- 20. Delphi> Bitte erläutern Sie: Art ... Prozedur des Objekts
- 21. Bitte erläutern Sie, warum ich die "Application" -Schnittstelle in Excel instanziieren kann. VSTO
- 22. Vererbung von abstrakten Methoden mit Paketzugriffs
- 23. Generika Rückgabetypen von abstrakten/virtuellen Methoden
- 24. Hervorrufen von privaten Methoden einer abstrakten Klasse
- 25. Swift - Mischen von abstrakten und konkreten Methoden
- 26. Bitte erläutern (Form_ [stdout, stderr] Flip hPutStrLn.) :: String -> IO()
- 27. Bitte erläutern diesen Simulator Turing-Maschine in Prolog geschrieben
- 28. Eine Schnittstelle mit abstrakten Methoden
- 29. Vorteile von abstrakten Methoden gegenüber Methodenüberschreibung
- 30. Nützlichkeit von JNI
Dies scheint nicht die Anforderungen zu erfüllen ‚eine wirkliche Frage nicht.‘ –
Es gibt keinen Grund, diese Frage zu schließen. Die Frage ist zwar nicht wortwörtlich, aber genau und nicht zweideutig. –
Umm schloss das war ein bisschen hart. –