Nota
O acceso a esta páxina require autorización. Pode tentar iniciar sesión ou modificar os directorios.
O acceso a esta páxina require autorización. Pode tentar modificar os directorios.
El modificador abstract indica que lo que se modifica carece de implementación o tiene una implementación incompleta. El modificador abstract puede usarse con clases, métodos, propiedades, indexadores y eventos. Use el modificador abstract en una declaración de clase para indicar que una clase está diseñada como clase base de otras clases, no para crear instancias por sí misma. Los miembros marcados como abstractos deben implementarse con clases no abstractas derivadas de la clase abstracta.
Las clases abstractas pueden contener miembros abstractos (que no tienen ninguna implementación y deben invalidarse en clases derivadas) y miembros totalmente implementados (como métodos normales, propiedades y constructores). Esto permite que las clases abstractas proporcionen funcionalidad común, a la vez que requieren clases derivadas para implementar miembros abstractos específicos.
Ejemplo 1: clase abstracta con miembros mixtos
En el ejemplo siguiente se muestra una clase abstracta que contiene los métodos implementados y los miembros abstractos:
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
*/
En este ejemplo, la Vehicle clase abstracta proporciona:
-
Miembros implementados:
GetInfo()método,StartEngine()método y constructor: proporcionan funcionalidad común para todos los vehículos. -
Miembros abstractos:
Move()método yMaxSpeedpropiedad: cada tipo de vehículo específico debe implementarlos.
Este diseño permite que la clase abstracta proporcione funcionalidad compartida al tiempo que garantiza que las clases derivadas implementen un comportamiento específico del vehículo.
Ejemplo 2
En este ejemplo, la clase Square debe proporcionar una implementación de GetArea porque se deriva de 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
Las clases abstractas tienen las siguientes características:
No se pueden crear instancias de una clase abstracta.
Una clase abstracta puede contener descriptores de acceso y métodos abstractos.
Una clase abstracta también puede contener métodos, propiedades, campos y otros miembros implementados que proporcionan funcionalidad a las clases derivadas.
No es posible modificar una clase abstracta con el modificador sealed porque los dos modificadores tienen significados opuestos. El modificador
sealedimpide que una clase se herede y el modificadorabstractrequiere que una clase se herede.Una clase no abstracta que derive de una clase abstracta debe incluir implementaciones reales de todos los descriptores de acceso y métodos abstractos heredados.
Use el modificador abstract en una declaración de método o de propiedad para indicar que el método o la propiedad no contienen implementación.
Los métodos abstractos tienen las siguientes características:
Un método abstracto es, implícitamente, un método virtual.
Solo se permiten declaraciones de métodos abstractos en clases abstractas.
Dado que una declaración de método abstracto no proporciona una implementación real, no hay ningún cuerpo de método; la declaración de método finaliza simplemente con un punto y coma y no hay llaves ({ }) después de la firma. Por ejemplo:
public abstract void MyMethod();La implementación la proporciona un método, override, que es miembro de una clase no abstracta.
Es un error usar los modificadores static o virtual en una declaración de método abstracto.
Las propiedades abstractas se comportan como métodos abstractos, salvo por las diferencias en la sintaxis de declaración e invocación.
Es un error usar el modificador
abstracten una propiedad estática.Una propiedad abstracta heredada se puede invalidar en una clase derivada incluyendo una declaración de propiedad que use el modificador override.
Para obtener más información sobre las clases abstractas, vea Clases y miembros de clase abstractos y sellados (Guía de programación de C#).
Una clase abstracta debe proporcionar implementación para todos los miembros de interfaz.
Una clase abstracta que implemente una interfaz podría asignar los métodos de interfaz a métodos abstractos. Por ejemplo:
interface I
{
void M();
}
abstract class C : I
{
public abstract void M();
}
Ejemplo 3
En este ejemplo, la clase DerivedClass se deriva de una clase abstracta BaseClass. La clase abstracta contiene un método abstracto, AbstractMethod, y dos propiedades abstractas, X y 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
En el ejemplo anterior, si intenta crear una instancia de la clase abstracta mediante una instrucción como esta:
BaseClass bc = new BaseClass(); // Error
Se mostrará un mensaje de error en el que se indica que el compilador no puede crear una instancia de la clase abstracta "BaseClass".
Sin embargo, es posible usar un constructor de clase abstracta, como en el ejemplo siguiente.
Ejemplo 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()}");
}
}
La clase Shape se declara abstract, lo cual significa que no se puede instanciar directamente. En su lugar, sirve como plano técnico para otras clases.
- Aunque no se pueden crear objetos de una clase abstracta, todavía puede tener un constructor. Este constructor suele ser
protected, lo que significa que solo se puede tener acceso a él desde clases derivadas. En este caso, el constructorShapetoma un parámetrocolore inicializa la propiedadColor. También imprime un mensaje en la consola. La partepublic Square(string color, double side) : base(color)llama al constructor de la clase base (Shape) y pasa el argumentocolora él. - En la clase Shape, el constructor definido toma un color como parámetro
protected Shape(string color). Esto significa que ya no hay un constructor sin parámetros predeterminado proporcionado automáticamente por las clases derivadas de C#, por lo que las clases derivadas deben usar la expresión: base(color)para invocar el constructor base. Establecer el valor predeterminado en colorprotected Shape(string color="green")permitirá omitir la expresión de: base(color)en las clases derivadas, aún este constructorprotected Shape(string color="green")se invocará, estableciendo el color en verde.
Especificación del lenguaje C#
Para obtener más información, consulte la Especificación del lenguaje C#. La especificación del lenguaje es la fuente definitiva de la sintaxis y el uso de C#.