Herança de classes e sobrescrita de membros

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

  1. 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.
  2. 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: intnum. num é supertipo de int e é válido.)
  3. 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.
  4. 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)
  1. O tipo estático do receptor da chamada é dynamic ;
  2. 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 do Object.

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

Next:

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *