Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
abstract Modifikátor označuje, že změněná věc má chybějící nebo neúplnou implementaci. Abstraktní modifikátor lze použít s třídami, metodami, vlastnostmi, indexery a událostmi.
abstract Modifikátor v deklaraci třídy slouží k označení, že třída je určena pouze jako základní třída jiných tříd, nikoli vytvoření instance sama. Členy označené jako abstraktní musí být implementovány ne abstraktní třídy, které jsou odvozeny z abstraktní třídy.
Abstraktní třídy mohou obsahovat abstraktní členy (které nemají žádnou implementaci a musí být přepsány v odvozených třídách) a plně implementované členy (například běžné metody, vlastnosti a konstruktory). To umožňuje abstraktní třídy poskytovat společné funkce, zatímco stále vyžadují odvozené třídy k implementaci konkrétních abstraktních členů.
Příklad 1 – abstraktní třída se smíšenými členy
Následující příklad ukazuje abstraktní třídu, která obsahuje implementované metody i abstraktní členy:
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
*/
V tomto příkladu Vehicle poskytuje abstraktní třída:
-
Implementované členy:
GetInfo()metoda,StartEngine()metoda a konstruktor – poskytují společné funkce pro všechna vozidla. -
Abstraktní členy:
Move()metoda aMaxSpeedvlastnost – musí být implementovány jednotlivými konkrétními typy vozidel.
Tento návrh umožňuje abstraktní třídě poskytovat sdílené funkce a zároveň zajistit, aby odvozené třídy implementovaly chování specifické pro vozidla.
Příklad 2
V tomto příkladu musí třída Square poskytnout implementaci GetArea , protože je odvozena z 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
Abstraktní třídy mají následující funkce:
Abstraktní třídu nelze vytvořit instanci.
Abstraktní třída může obsahovat abstraktní metody a přístupové objekty.
Abstraktní třída může také obsahovat implementované metody, vlastnosti, pole a další členy, které poskytují funkce odvozeným třídám.
Abstraktní třídu s zapečetěným modifikátorem není možné upravit, protože tyto dva modifikátory mají opačný význam.
sealedModifikátor zabraňuje dědění třídy aabstractmodifikátor vyžaduje, aby byla zděděna třída.Abstraktní třída odvozená z abstraktní třídy musí obsahovat skutečné implementace všech zděděných abstraktních metod a přístupových objektů.
abstract Použijte modifikátor v metodě nebo deklaraci vlastnosti k označení, že metoda nebo vlastnost neobsahuje implementaci.
Abstraktní metody mají následující funkce:
Abstraktní metoda je implicitně virtuální metoda.
Deklarace abstraktní metody jsou povoleny pouze v abstraktních třídách.
Vzhledem k tomu, že deklarace abstraktní metody neposkytuje žádnou skutečnou implementaci, neexistuje žádný tělo metody; deklarace metody jednoduše končí středníkem a za podpisem nejsou žádné složené závorky ({ }). Příklad:
public abstract void MyMethod();Implementace je poskytována přepsáním metody, která je členem ne abstraktní třídy.
Jedná se o chybu použití statických nebo virtuálních modifikátorů v abstraktní deklaraci metody.
Abstraktní vlastnosti se chovají jako abstraktní metody, s výjimkou rozdílů v deklaraci a syntaxi vyvolání.
Jedná se o chybu použití modifikátoru
abstractu statické vlastnosti.Abstraktní zděděná vlastnost lze přepsat v odvozené třídě zahrnutím deklarace vlastnosti, která používá modifikátor přepsání .
Další informace o abstraktních třídách naleznete v tématu Abstraktní a zapečetěné třídy a členy třídy.
Abstraktní třída musí poskytovat implementaci pro všechny členy rozhraní.
Abstraktní třída, která implementuje rozhraní, může mapovat metody rozhraní na abstraktní metody. Příklad:
interface I
{
void M();
}
abstract class C : I
{
public abstract void M();
}
Příklad 3
V tomto příkladu je třída DerivedClass odvozena z abstraktní třídy BaseClass. Abstraktní třída obsahuje abstraktní metodu , AbstractMethoda dvě abstraktní vlastnosti, X a 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
Pokud se v předchozím příkladu pokusíte vytvořit instanci abstraktní třídy pomocí příkazu, který je podobný tomuto:
BaseClass bc = new BaseClass(); // Error
Zobrazí se chyba s informací, že kompilátor nemůže vytvořit instanci abstraktní třídy BaseClass.
Nicméně je možné použít abstraktní konstruktor třídy, jak je uvedeno v následujícím příkladu.
Příklad 4
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()}");
}
}
Třída Shape je deklarována abstract, což znamená, že nelze instancovat přímo. Místo toho slouží jako podrobný plán pro jiné třídy.
- I když nemůžete vytvářet objekty abstraktní třídy, může mít stále konstruktor. Tento konstruktor je obvykle
protected, což znamená, že k němu lze přistupovat pouze z odvozených tříd. V tomto případě konstruktorShapepřebírácolorparametr a inicializujeColorvlastnost. Vytiskne také zprávu do konzoly. Částpublic Square(string color, double side) : base(color)volá konstruktor základní třídy (Shape) a předává mu argumentcolor. - Ve třídě Shape definovaný konstruktor přebírá barvu jako parametr
protected Shape(string color). To znamená, že už neexistuje výchozí konstruktor bez parametrů automaticky poskytovaný jazykem C#, takže odvozené třídy musí k vyvolání základního konstruktoru použít výraz: base(color). Nastavení výchozí hodnoty na barvuprotected Shape(string color="green")umožní vynechat výraz: base(color)v odvozených třídách, stále takový konstruktorprotected Shape(string color="green")bude vyvolán a nastaví barvu na zelenou.
Specifikace jazyka C#
Další informace najdete v tématu Specifikace jazyka C#. Specifikace jazyka je úplným a rozhodujícím zdrojem pro syntaxi a použití jazyka C#.