Herencia
## Objetivos de Aprendizaje
- Comprender la herencia
- Dominar el polimorfismo
- Trabajar con clases abstractas
- Implementar interfaces
## ¿Qué es la Herencia?
### Relación "Es-un"
```csharp
// Clase base
class Animal
{
public string Name { get; set; }
public void Eat()
{
Console.WriteLine("Comiendo");
}
}
// Clase derivada
class Dog : Animal
{
public void Bark()
{
Console.WriteLine("¡Guau!");
}
}
// Uso
Dog dog = new Dog();
dog.Name = "Buddy";
dog.Eat(); // De clase base
dog.Bark(); // De clase Dog
```
## Acceso protected
### Accesible en Clases Derivadas
```csharp
class Animal
{
protected string _name; // Accesible a clases derivadas
private int _age; // No accesible fuera de la clase
}
class Dog : Animal
{
public void Introduce()
{
_name = "Buddy"; // OK - _name es protected
// _age = 5; // Error - _age es private
}
}
```
## Referencia a Clase Base
### Polimorfismo
```csharp
class Animal
{
public string Name { get; set; }
public virtual void MakeSound()
{
Console.WriteLine("Algún sonido");
}
}
class Dog : Animal
{
public override void MakeSound()
{
Console.WriteLine("¡Guau!");
}
}
class Cat : Animal
{
public override void MakeSound()
{
Console.WriteLine("¡Miau!");
}
}
// Uso
Animal[] animals = { new Dog(), new Cat(), new Animal() };
foreach (Animal animal in animals)
{
animal.MakeSound(); // Llama el override apropiado
}
// Salida: ¡Guau! ¡Miau! Algún sonido
```
## virtual y override
### Métodos Virtuales
```csharp
class Animal
{
public virtual void MakeSound()
{
Console.WriteLine("...");
}
}
```
### Métodos Override
```csharp
class Dog : Animal
{
public override void MakeSound()
{
Console.WriteLine("¡Guau!");
}
}
```
### sealed (Prevenir Override)
```csharp
class Dog : Animal
{
public sealed override void MakeSound()
{
Console.WriteLine("¡Guau!");
}
}
class Husky : Dog
{
// No puede hacer override de MakeSound - está sealed
}
```
## Clases Abstractas
### No Pueden Instanciarse
```csharp
abstract class Shape
{
public abstract double Area(); // Debe implementarse
public abstract double Perimeter();
public void Print()
{
Console.WriteLine($"Área: {Area()}");
}
}
class Rectangle : Shape
{
public double Width { get; set; }
public double Height { get; set; }
public override double Area() => Width * Height;
public override double Perimeter() => 2 * (Width + Height);
}
// Shape s = new Shape(); // Error - no puede instanciarse
Shape r = new Rectangle { Width = 5, Height = 3 };
```
### abstract vs virtual
| abstract | virtual |
|----------|---------|
| Debe hacer override | Puede hacer override opcionalmente |
| Sin cuerpo | Tiene cuerpo |
| No puede instanciarse | Puede instanciarse |
## Interfaces
### Definición de Contrato
```csharp
interface IShape
{
double Area();
double Perimeter();
}
interface IPrintable
{
void Print();
}
class Rectangle : IShape, IPrintable
{
public double Width { get; set; }
public double Height { get; set; }
public double Area() => Width * Height;
public double Perimeter() => 2 * (Width + Height);
public void Print()
{
Console.WriteLine($"Rectángulo: {Width} x {Height}");
}
}
```
### Convención de Nomenclatura de Interfaces
- Comenzar con "I" (ej., IDisposable, IEnumerable)
- Describir capacidad (IComparable, ICloneable)
### Interface vs Clase Abstracta
| Interface | Clase Abstracta |
|-----------|----------------|
| Sin implementación | Puede tener implementación |
| Múltiples permitidas | Solo una |
| Sin estado | Puede tener estado |
| Público por defecto | Puede tener modificadores de acceso |
## Implementación de Interface por Defecto (C# 8+)
```csharp
interface IAnimal
{
void Speak();
public void PrintSpecies()
{
Console.WriteLine("Animal genérico");
}
}
class Dog : IAnimal
{
public void Speak()
{
Console.WriteLine("¡Guau!");
}
}
Dog dog = new Dog();
dog.Speak();
((IAnimal)dog).PrintSpecies(); // Debe hacer cast
```
## Ejemplo de Polimorfismo
### Jerarquía de Formas
```csharp
interface IShape
{
double Area();
}
class Circle : IShape
{
public double Radius { get; set; }
public double Area() => Math.PI * Radius * Radius;
}
class Rectangle : IShape
{
public double Width { get; set; }
public double Height { get; set; }
public double Area() => Width * Height;
}
// Calcular área total
IShape[] shapes = { new Circle(5), new Rectangle(4, 6) };
double totalArea = 0;
foreach (IShape shape in shapes)
{
totalArea += shape.Area();
}
```
## Palabra Clave base
### Acceder Miembros de Clase Base
```csharp
class Animal
{
public string Name { get; set; }
public virtual void Speak()
{
Console.WriteLine("...");
}
}
class Dog : Animal
{
public override void Speak()
{
Console.WriteLine("¡Guau!");
}
public void SpeakWithName()
{
base.Speak(); // Llama Animal.Speak()
Console.WriteLine($"Mi nombre es {Name}");
}
}
```
### base en Constructores
```csharp
class Animal
{
public string Name { get; set; }
public Animal(string name)
{
Name = name;
}
}
class Dog : Animal
{
public string Breed { get; set; }
public Dog(string name, string breed) : base(name)
{
Breed = breed;
}
}
```
## Casting y typeof
### Casting Exícito
```csharp
Animal animal = new Dog();
Dog dog = (Dog)animal; // Cast explícito
// Cast seguro con 'as'
Dog? dog2 = animal as Dog;
if (dog2 != null)
{
dog2.Bark();
}
```
### Operador is con Pattern
```csharp
Animal animal = new Dog();
if (animal is Dog dog) // Pattern matching
{
dog.Bark(); // dog está en alcance
}
// O
if (animal is Dog)
{
Dog dog = (Dog)animal;
dog.Bark();
}
```
## Clase Object
### Todas las Clases Derivan de object
```csharp
class Person
{
public string Name { get; set; }
}
// Estos son equivalentes:
Person p = new Person();
object o = new Person();
```
### Métodos de object
```csharp
object o = new Person { Name = "Alice" };
o.ToString(); // "Person" o sobreescrito
o.GetHashCode();
o.Equals(other);
o.GetType();
```
## Resumen
- Herencia: clase deriva de otra clase
- protected: accesible en clases derivadas
- virtual/override: para polimorfismo
- abstract: debe hacer override, no puede instanciarse
- interface: contrato, múltiples permitidas
- base: acceder miembros de clase base
- is/as: verificación y conversión de tipos
- Todos los tipos derivan de object
Comments
Comments powered by Giscus
To enable comments, add your Giscus embed code here.
Learn more about Giscus →