Estender uma classe Extend a class
Use a palavra-chave extends para criar uma subclasse derivada de uma superclasse (classe pai).
Utilize a palavra-chave super para acessar membros da classe pai (métodos, construtores etc.) dentro de uma subclasse.
class Television {
void turnOn() {
...
// Código executado no método da classe pai
}
}
// SmartTelevision é a subclasse, Television é a superclasse
class SmartTelevision extends Television {
@override
void turnOn() {
super.turnOn(); // Chama o método turnOn da classe pai
// Código exclusivo da subclasse
...
}
}Code language: Dart (dart)
Por exemplo, uma televisão convencional funciona como classe pai e uma smart TV como subclasse; a smart TV herda recursos da televisão convencional.
extends tem outro cenário de uso: conteúdos relacionados aos tipos parametrizados vistos no capítulo de genéricos.
Exemplo prático
class Television {
void turnOn() {
print("Ligar televisão, iniciar saída de imagem básica");
}
}
// SmartTelevision é a subclasse, Television é a superclasse
class SmartTelevision extends Television {
@override
void turnOn() {
super.turnOn(); // Chama o método turnOn da classe pai
// Código exclusivo da subclasse
print("Smart TV: ativar módulo de rede, carregar tela inicial do sistema inteligente");
}
}
void main() {
// Instância de televisão comum
Television normalTv = Television();
print("===== Ligar televisão convencional =====");
normalTv.turnOn();
// Instância de smart TV
SmartTelevision smartTv = SmartTelevision();
print("\n===== Ligar smart TV =====");
smartTv.turnOn();
}Code language: Dart (dart)
Resultado da execução
D:\dartdemo\firstdart>dart run
Building package executable... (1.4s)
Built firstdart:firstdart.
===== Ligar televisão convencional =====
Ligar televisão, iniciar saída de imagem básica
===== Ligar smart TV =====
Ligar televisão, iniciar saída de imagem básica
Sobrescrita de membros Overriding members
1. Elementos que podem ser sobrescritos
Uma subclasse pode sobrescrever: métodos de instância (incluindo operadores), getters e setters.
2. A anotação @override
Função: declarar explicitamente que este método sobrescreve deliberadamente um membro da classe pai, permitindo validações pelo compilador.
class Television {
set contrast(int value) {}
}
class SmartTelevision extends Television {
@override // Informa ao compilador que esse método sobrescreve o método da classe pai
set contrast(num value) {}
}
Code language: JavaScript (javascript)
3. Regras obrigatórias para sobrescrita
- Tipo de retorno: O tipo de retorno do método sobrescrito deve ser igual ao método da classe pai ou ser um subtipo dele.
- Tipo de parâmetro: O tipo de parâmetro do método sobrescrito deve coincidir com o da classe pai ou ser um supertipo. (Exemplo:
int→num. num é supertipo de int e é válido.) - Quantidade de parâmetros posicionais: Se o método original tiver n parâmetros posicionais, o método sobrescrito também deve declarar n parâmetros posicionais.
- Restrições de genéricos: Um método genérico não pode sobrescrever um método não genérico e vice-versa.
4. Palavra-chave covariant (caso especial de restrição de tipo)
As regras padrão proíbem reduzir o tipo de parâmetro (conversão para subtipo pode causar erros de tipo em tempo de execução) ;
Se o desenvolvedor garantir que não ocorrerão erros de tipo, marque o parâmetro com covariant para possibilitar a redução do tipo de parâmetro.
Ao sobrescrever o operador ==, você também precisa sobrescrever obrigatoriamente o getter hashCode herdado de Object.
noSuchMethod ()
1. Propósito
Quando o código tenta chamar um método de instância / variável de instância inexistente, você pode sobrescrever noSuchMethod() para interceptar a chamada e executar uma lógica personalizada.
Sem sobrescrita, acessar membros inexistentes lançará diretamente um erro NoSuchMethodError.
class A {
@override
void noSuchMethod(Invocation invocation) {
print('You tried to use a non-existent member: ${invocation.memberName}');
}
}
Code language: JavaScript (javascript)
- Objeto
Invocation: Armazena todas as informações da chamada (nome do membro, parâmetros, etc.)
2. Dois pré-requisitos para chamar métodos não implementados (basta satisfazer um)
- O tipo estático do receptor da chamada é
dynamic; - O tipo estático do receptor declara esse método não implementado (pode ser um método abstrato), e o tipo dinâmico do receptor tem uma implementação de
noSuchMethod()diferente da versão padrão doObject.
Exemplo
class A {
@override
void noSuchMethod(Invocation invocation) {
print('You tried to use a non-existent member: ${invocation.memberName}');
// Imprime parâmetros e tipo da chamada para exibir todas as informações
print('Parâmetros da chamada:${invocation.arguments}');
print('Tipo de invocação:${invocation.runtimeType}');
}
}
void main() {
A obj = A();
// Chamada de método inexistente, aciona noSuchMethod
obj.hello("test", 123);
// Acesso a propriedade inexistente
obj.unknownValue;
}Code language: Dart (dart)
D:\dartdemo\firstdart>dart run
Building package executable...
Failed to build firstdart:firstdart:
bin/firstdart.dart:6:30: Error: The getter 'arguments' isn't defined for the type 'Invocation'.
- 'Invocation' is from 'dart:core'.
Try correcting the name to the name of an existing getter, or defining a getter or field named 'arguments'.
print('cal:${invocation.arguments}');
^^^^^^^^^
bin/firstdart.dart:14:7: Error: The method 'hello' isn't defined for the type 'A'.
- 'A' is from 'bin/firstdart.dart'.
Try correcting the name to the name of an existing method, or defining a method named 'hello'.
obj.hello("test", 123);
^^^^^
bin/firstdart.dart:16:7: Error: The getter 'unknownValue' isn't defined for the type 'A'.
- 'A' is from 'bin/firstdart.dart'.
Try correcting the name to the name of an existing getter, or defining a getter or field named 'unknownValue'.
obj.unknownValue;Code language: PHP (php)
Herança de classes e sobrescrita de membros