Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
De abstract wijzigingsfunctie geeft aan dat het doel een ontbrekende of onvolledige implementatie heeft. Gebruik de abstracte wijziging met klassen, methoden, eigenschappen, indexeerfuncties en gebeurtenissen. Gebruik de abstract wijzigingsfunctie in een klassedeclaratie om aan te geven dat een klasse alleen bedoeld is als basisklasse van andere klassen, niet zelfstandig geïnstantieerd. Niet-abstracte klassen die zijn afgeleid van de abstracte klasse moeten leden implementeren die zijn gemarkeerd als abstract.
De C#-taalreferentiedocumenten beschrijven de meest recent uitgebrachte versie van de C#-taal. Het bevat ook de eerste documentatie voor functies in openbare previews voor de aanstaande taalrelease.
De documentatie identificeert alle functies die voor het eerst zijn geïntroduceerd in de laatste drie versies van de taal of in de huidige openbare previews.
Aanbeveling
Raadpleeg het artikel over de versiegeschiedenis van de C#-taal om te achterhalen wanneer een functie voor het eerst is geïntroduceerd in C#.
Abstracte klassen kunnen zowel abstracte leden bevatten (die geen implementatie hebben en moeten worden overschreven in afgeleide klassen) als volledig geïmplementeerde leden (zoals reguliere methoden, eigenschappen en constructors). Met deze functie kunnen abstracte klassen algemene functionaliteit bieden terwijl er nog steeds afgeleide klassen nodig zijn om specifieke abstracte leden te implementeren.
Opmerking
Interfaceleden zijn abstract standaard.
Abstracte klasse met gemengde leden
In het volgende voorbeeld ziet u een abstracte klasse die zowel geïmplementeerde methoden als abstracte leden bevat:
namespace LanguageKeywords;
public abstract class Vehicle
{
protected string _brand;
// Constructor - implemented method in abstract class
public Vehicle(string brand) => _brand = brand;
// Implemented method - provides functionality that all vehicles share
public string GetInfo() => $"This is a {_brand} vehicle.";
// Another implemented method
public virtual void StartEngine() => Console.WriteLine($"{_brand} engine is starting...");
// Abstract method - must be implemented by derived classes
public abstract void Move();
// Abstract property - must be implemented by derived classes
public abstract int MaxSpeed { get; }
}
public class Car : Vehicle
{
public Car(string brand) : base(brand) { }
// Implementation of abstract method
public override void Move() => Console.WriteLine($"{_brand} car is driving on the road.");
// Implementation of abstract property
public override int MaxSpeed => 200;
}
public class Boat : Vehicle
{
public Boat(string brand) : base(brand) { }
// Implementation of abstract method
public override void Move() => Console.WriteLine($"{_brand} boat is sailing on the water.");
// Implementation of abstract property
public override int MaxSpeed => 50;
}
public class AbstractExample
{
public static void Examples()
{
// Cannot instantiate abstract class: Vehicle v = new Vehicle("Generic"); // Error!
Car car = new Car("Toyota");
Boat boat = new Boat("Yamaha");
// Using implemented methods from abstract class
Console.WriteLine(car.GetInfo());
car.StartEngine();
// Using abstract methods implemented in derived class
car.Move();
Console.WriteLine($"Max speed: {car.MaxSpeed} km/h");
Console.WriteLine();
Console.WriteLine(boat.GetInfo());
boat.StartEngine();
boat.Move();
Console.WriteLine($"Max speed: {boat.MaxSpeed} km/h");
}
}
class Program
{
static void Main()
{
AbstractExample.Examples();
}
}
/* Output:
This is a Toyota vehicle.
Toyota engine is starting...
Toyota car is driving on the road.
Max speed: 200 km/h
This is a Yamaha vehicle.
Yamaha engine is starting...
Yamaha boat is sailing on the water.
Max speed: 50 km/h
*/
In dit voorbeeld biedt de Vehicle abstracte klasse het volgende:
-
Geïmplementeerde leden:
GetInfo()methode,StartEngine()methode en constructor: deze leden bieden algemene functionaliteit voor alle voertuigen. -
Abstracte leden:
Move()methode enMaxSpeedeigenschap - deze leden moeten worden geïmplementeerd door elk specifiek voertuigtype.
Met dit ontwerp kan de abstracte klasse gedeelde functionaliteit bieden en ervoor zorgen dat afgeleide klassen voertuigspecifiek gedrag implementeren.
Concrete klasse afgeleid van een abstracte klasse
In dit voorbeeld moet de klasse Square een implementatie GetArea opgeven, omdat deze is afgeleid van Shape:
abstract class Shape
{
public abstract int GetArea();
}
class Square : Shape
{
private int _side;
public Square(int n) => _side = n;
// GetArea method is required to avoid a compile-time error.
public override int GetArea() => _side * _side;
static void Main()
{
var sq = new Square(12);
Console.WriteLine($"Area of the square = {sq.GetArea()}");
}
}
// Output: Area of the square = 144
Abstracte klassen hebben de volgende functies:
- U kunt geen exemplaar van een abstracte klasse maken.
- Een abstracte klasse kan abstracte methoden en accessors bevatten.
- Een abstracte klasse kan ook geïmplementeerde methoden, eigenschappen, velden en andere leden bevatten die functionaliteit bieden voor afgeleide klassen.
- U kunt de
sealedmodifier niet gebruiken voor een abstracte klasse, omdat de twee modifiers tegengestelde betekenissen hebben. Desealedwijzigingsfunctie voorkomt dat een klasse wordt overgenomen en deabstractwijzigingsfunctie vereist dat een klasse wordt overgenomen. - Een niet-abstracte klasse die is afgeleid van een abstracte klasse moet werkelijke implementaties van alle overgenomen abstracte methoden en accessors bevatten.
Gebruik de abstract wijzigingsfunctie in een methode- of eigenschapsdeclaratie om aan te geven dat de methode of eigenschap geen implementatie bevat.
Abstracte methoden hebben de volgende functies:
Een abstracte methode is impliciet een virtuele methode.
Abstracte methodedeclaraties zijn alleen toegestaan in abstracte klassen.
Omdat een abstracte methodedeclaratie geen werkelijke implementatie biedt, is er geen hoofdtekst van de methode. De methodedeclaratie eindigt gewoon met een puntkomma. Voorbeeld:
public abstract void MyMethod();De implementatie wordt geleverd door een methode
override, die lid is van een niet-abstracte klasse.Het is een fout bij het gebruik van de
staticofvirtualmodifiers in een abstracte methodedeclaratie in eenclasstype. U kunt declarerenstatic abstractenstatic virtualmethoden in interfaces.Abstracte eigenschappen gedragen zich als abstracte methoden, met uitzondering van de verschillen in declaratie- en aanroepsyntaxis.
Het is een fout bij het gebruik van de
abstractwijzigingsfunctie voor een statische eigenschap in eenclasstype. U kunt declaraties ofstatic virtualeigenschappen declarerenstatic abstractin interfacedeclaraties.Een abstracte overgenomen eigenschap kan worden overschreven in een afgeleide klasse door een eigenschapsdeclaratie op te nemen die gebruikmaakt van de
overridewijzigingsfunctie.
Zie Abstracte en Verzegelde klassen en Klasseleden voor meer informatie over abstracte klassen.
Een abstracte klasse moet implementatie bieden voor alle interfaceleden. Een abstracte klasse die een interface implementeert, kan de interfacemethoden toewijzen aan abstracte methoden. Voorbeeld:
interface I
{
void M();
}
abstract class C : I
{
public abstract void M();
}
In het volgende voorbeeld is de klasse DerivedClass afgeleid van een abstracte klasse BaseClass. De abstracte klasse bevat een abstracte methode, AbstractMethoden twee abstracte eigenschappen, X en Y.
// Abstract class
abstract class BaseClass
{
protected int _x = 100;
protected int _y = 150;
// Abstract method
public abstract void AbstractMethod();
// Abstract properties
public abstract int X { get; }
public abstract int Y { get; }
}
class DerivedClass : BaseClass
{
public override void AbstractMethod()
{
_x++;
_y++;
}
public override int X // overriding property
{
get
{
return _x + 10;
}
}
public override int Y // overriding property
{
get
{
return _y + 10;
}
}
static void Main()
{
var o = new DerivedClass();
o.AbstractMethod();
Console.WriteLine($"x = {o.X}, y = {o.Y}");
}
}
// Output: x = 111, y = 161
Als u in het voorgaande voorbeeld probeert een instantie van de abstracte klasse te maken met behulp van een instructie als volgt:
BaseClass bc = new BaseClass(); // Error
Er wordt een foutbericht weergegeven dat de compiler geen exemplaar van de abstracte klasse BaseClass kan maken. U kunt echter een abstracte klasseconstructor gebruiken, zoals wordt weergegeven in het volgende voorbeeld.
public abstract class Shape
{
public string Color { get; set; }
// Constructor of the abstract class
protected Shape(string color)
{
Color = color;
Console.WriteLine($"Created a shape with color {color}.");
}
// Abstract method that must be implemented by derived classes
public abstract double CalculateArea();
}
public class Square : Shape
{
public double Side { get; set; }
// Constructor of the derived class calling the base class constructor
public Square(string color, double side) : base(color)
{
Side = side;
}
public override double CalculateArea()
{
return Side * Side;
}
}
public class Program
{
public static void Main(string[] args)
{
Square square = new Square("red", 5);
Console.WriteLine($"Area of the square: {square.CalculateArea()}");
}
}
De Shape klasse wordt gedeclareerd abstract, wat betekent dat u deze niet rechtstreeks kunt instantiëren. In plaats daarvan fungeert het als blauwdruk voor andere klassen.
- Hoewel u geen objecten van een abstracte klasse kunt maken, kan deze nog steeds een constructor hebben. Deze constructor is doorgaans
protected, wat betekent dat alleen afgeleide klassen er toegang toe hebben. In dit geval neemt deShapeconstructor eencolorparameter en initialiseert de eigenschapColor. Er wordt ook een bericht naar de console afgedrukt. Hetpublic Square(string color, double side) : base(color)onderdeel roept de constructor van de basisklasse (Shape) aan en geeft het argumentcolordoor. - In de
Shapeklasse heeft de gedefinieerde constructor een kleur als parameterprotected Shape(string color). Dit betekent dat C# geen standaard parameterloze constructor meer automatisch biedt. Afgeleide klassen moeten de: base(color)expressie gebruiken om de basisconstructor aan te roepen. Als u de standaardwaarde instelt op kleurprotected Shape(string color="green"), kunt u de: base(color)expressie weglaten in afgeleide klassen. De constructorprotected Shape(string color="green")stelt de kleur in op groen.
C#-taalspecificatie
Zie de C#-taalspecificatie voor meer informatie. De taalspecificatie is de definitieve bron voor de C#-syntaxis en het gebruik.