---
title: 🧬 Herdanza, super e clases abstractas
description: "A **herdanza** permite crear unha clase a partir doutra. Usamos `extends`: a clase orixinal é a **superclase** e a nova é a **subclase**. Un profesor **é unha** persoa. Pode herdar datos e métodos de `Persoa` e engadir outros propios. ##…"
url: "https://www.drodicio.com/docs/dart/obxectos-dart/herdanza/"
updated: "2026-09-27"
category: Tema 2. Orientación a obxectos en Dart
---

# 🧬 Herdanza, super e clases abstractas

A **herdanza** permite crear unha clase a partir doutra. Usamos `extends`: a clase orixinal é a **superclase** e a nova é a **subclase**.

Un profesor **é unha** persoa. Pode herdar datos e métodos de `Persoa` e engadir outros propios.

## 🧬 `extends` e a chamada ao construtor con `super`

```dart
class Persoa {
  final String nome;
  Persoa(this.nome);

  void saudar() {
    print('Ola, son $nome.');
  }
}

class Profesor extends Persoa {
  // A superclase necesita un nome: pasámosllo con super(nome).
  Profesor(String nome) : super(nome);

  void explicar() {
    print('$nome explica Dart.'); // nome é un atributo herdado
  }
}

void main() {
  var profesor = Profesor('Diego Rodicio');
  profesor.saudar(); // Método herdado
  profesor.explicar(); // Método propio
}
```

Os construtores **non se herdan**. Se non escribimos unha chamada ao da superclase, Dart intenta chamar a `super()` sen argumentos. Se ese construtor necesita datos, debemos pasalos.

## ✂️ A forma curta: parámetros `super`

Podemos evitar repetir un parámetro que só se pasa á superclase. Por exemplo, `Profesor(String nome) : super(nome);` pode escribirse `Profesor(super.nome);`.

Tamén funciona cos parámetros nomeados:

```dart
class Persoa {
  final String nome;
  Persoa({required this.nome});
}

class Profesor extends Persoa {
  // Recibe nome e pásallo ao construtor de Persoa.
  Profesor({required super.nome});
}

void main() {
  var profesor = Profesor(nome: 'Diego Rodicio');
  print(profesor.nome);
}
```

> 📱 Esta é a idea que hai detrás de `super.key` en Flutter: recibir un parámetro e pasalo ao construtor da superclase. O significado de `key` verémolo en Flutter.

## 🔁 Sobrescribir un método e usar `super.metodo()`

**Sobrescribir** é dar a nosa propia versión dun método herdado. Engadimos `@override` para indicar a intención; o analizador avísanos se non existe un membro que sobrescribir.

Se queremos conservar o comportamento anterior e engadir algo, podemos chamar a `super.metodo()`. Non é obrigatorio en todos os métodos: depende do que queiramos facer e do contrato da superclase.

## 🧪 Exemplo completo: ampliar un saúdo

> 🔗 [Ver o código en DartPad — https://dartpad.dev/?id=ece7d59f9e194522395fca282ea9e74a](https://dartpad.dev/?id=ece7d59f9e194522395fca282ea9e74a)

[https://dartpad.dev/embed-inline.html?id=ece7d59f9e194522395fca282ea9e74a](https://dartpad.dev/embed-inline.html?id=ece7d59f9e194522395fca282ea9e74a)

En Flutter tamén sobrescribiremos métodos e atoparemos chamadas como `super.initState()` e `super.dispose()`. Alí veremos cando se executan e a orde que debemos respectar.

## 🧩 Clases e métodos abstractos

Unha clase `abstract` serve de base e non se pode instanciar directamente. Pode deixar métodos sen corpo para que os completen as subclases concretas.

```dart
abstract class PersoaCentro {
  // Método abstracto: remata en ; porque aínda non ten implementación.
  void presentarse();
}

class Profesor extends PersoaCentro {
  @override
  void presentarse() {
    print('Son Diego Rodicio, profesor no IES San Mamede.');
  }
}

void main() {
  PersoaCentro persoa = Profesor();
  persoa.presentarse();
  // PersoaCentro(); // ❌ Non podemos instanciar a clase abstracta
}
```

Unha clase abstracta tamén pode ter atributos, construtores e métodos xa implementados. Verémolo no exemplo final.

## 🤝 `implements`: cumprir un contrato

Con `extends` herdamos implementación. Con `implements` comprometémonos a ofrecer os membros de instancia da interface, pero non herdamos o código que os implementa.

```dart
abstract class Presentable {
  void presentarse();
}

class Profesor implements Presentable {
  // Temos que proporcionar o método que esixe o contrato.
  @override
  void presentarse() {
    print('Son Diego Rodicio.');
  }
}

void main() {
  Presentable profesor = Profesor();
  profesor.presentarse();
}
```

Toda clase define unha interface, aínda que non leve a palabra `interface`. Aquí usamos unha clase abstracta para que o contrato sexa fácil de ver. Os construtores e membros estáticos non forman parte dese contrato.

## 🔎 Recordatorio: herdanza con tipos xenéricos

No Tema 2.1 vimos tipos como `List<String>`. As clases das que herdamos tamén poden recibir un tipo. En Flutter leremos `extends State<MeuWidget>`: é a clase `State` parametrizada co tipo `MeuWidget`. Non é outra forma distinta de herdanza.

> 🔗 [Herdanza e sobrescritura — https://dart.dev/language/extend](https://dart.dev/language/extend) · [Interfaces implícitas — https://dart.dev/language/classes#implicit-interfaces](https://dart.dev/language/classes#implicit-interfaces)
