3
respostas

[Dúvida] Exercício proposto Faça como eu fiz: Classes e heranças

Olá outra vez!

Espero que tenha cumprido o que o exercício propôs, quis ir mais além porém, por isso tentei colocar todos os atributos nomeados, acho que fica mais legível na construção do objeto, apanhei bastante, mas graças ao vscode consegui(por favor olha comentário do código), também achei algumas informações sobre o mixin, então tive a ideia de criar uma classe mixin ParaVeiculosTerrestres, no qual conteria o método frear, porém não consegui fazer com que este método alterasse a variável da classe Veiculo, então desisti por enquanto e criei uma outra classe VeiculoTerrestre, espero que mais a frente também aprenderemos sobre mixin e porque é necessária. Ainda não consigo ver a necessidade de ter o construtor que praticamente nos faz repetir os atributos, piora quando é sobre os atributos do pai, só gostaria de entender o por que disso.\n Obs: Falhas, melhorias e ou Dicas não existe em me informar, não coube todo o código então repartir em dois sendo a segunda parte nos comentários. link do exercício completo

//importação do VS code não sei ainda
//import 'package:veiculos/veiculos.dart' as veiculos; 
//importação para ter o pause em segundos
import 'dart:io'; 
void main(List<String> arguments) {
  Carro gol =
      Carro(modelo: "gol", marca: "VW", cor: "Azul", velocidadeMaxima: 180);
  gol.ligar();
  gol.desligar();
  gol.acelerar(forca: 1);
  gol.ligar();
  gol.acelerar(forca: 1);
  gol.acelerar(forca: 1);
  gol.getVelocidadeAtual();
  gol.frear();
  gol.desligar(); 
  Barco lancha = Barco(
      modelo: "Lanchax1",
      marca: "Tupiniquin",
      cor: "preta",
      velocidadeMaxima: 120,
      velocidadeAtual: 0,
      estaLigado: true);
  lancha.acelerar(forca: 1);
  lancha.levantarAncora(); 
  while (lancha.velocidadeAtual < lancha.velocidadeMaxima) {
    lancha.acelerar(forca: 1);
    lancha.getVelocidadeAtual();
  }
  lancha.desligar();
} 
class Veiculo {
  String modelo;
  String marca;
  String cor; 
  double velocidadeMaxima;
  double velocidadeAtual; 
  bool estaLigado; 
  Veiculo(
      {required this.modelo,
      required this.marca,
      required this.cor,
      this.velocidadeAtual = 0,
      required this.velocidadeMaxima,
      this.estaLigado = false}); 
  void ligar() {
    if (!estaLigado) {
      print("Ligando o veiculo!");
      sleep(const Duration(seconds: 2));
      estaLigado = true;
      print("O motor do veiculo esta ligado!");
    }
  } 
  void desligar() {
    if (estaLigado) {
      print("Desligando o veiculo!");
      sleep(const Duration(seconds: 1));
      estaLigado = false;
      print("O motor do veiculo esta desligado!");
    }
  } 
  void acelerar({double forca = 0.1}) {
    if (estaLigado) {
      print("Veiculo acelerando...");
      sleep(const Duration(seconds: 1));
      velocidadeAtual += forca * 10;
    } else {
      print("O veiculo não pode ser acelerado, pois está desligado!");
    }
    //Garantindo que o veiculo não passe da Velociade maxima
    if (velocidadeAtual > velocidadeMaxima) {
      velocidadeAtual = velocidadeMaxima;
    }
    //Na frenagem garantir a velociadade não seja negativa
    if (velocidadeAtual < 0) velocidadeAtual = 0;
  } 
  void getVelocidadeAtual() {
    print("O veiculo está a $velocidadeAtual" "Km/h");
  }
} 
class VeiculosTerrestres extends Veiculo {
  VeiculosTerrestres({
    required String modelo,
    required String marca,
    required String cor,
    required double velocidadeMaxima,
    double velocidadeAtual = 0,
    bool estaLigado = false,
  }) : super(
            modelo: modelo,
            marca: marca,
            cor: cor,
            velocidadeMaxima: velocidadeMaxima,
            velocidadeAtual: velocidadeAtual,
            estaLigado: estaLigado);
  //O por que desses dois pontos e qual o nome disso 
  //gostaria de saber, se não for ter nas proximas aulas 
  void frear() {
    print("Freando o veiculo!");
    sleep(const Duration(seconds: 2));
    super.velocidadeAtual = 0;
    print("Veiculo parado!");
  }
} 
class Carro extends VeiculosTerrestres {
  //estes atributos teram um valor padrão
  int qtdPortas;
  int qtdBancos;
  bool temPortaMalas; 
  Carro(
      {required String modelo,
      required String marca,
      required String cor,
      required double velocidadeMaxima,
      double velocidadeAtual = 0,
      bool estaLigado = false,
      this.qtdBancos = 1,
      this.qtdPortas = 0,
      this.temPortaMalas = true})
      : super(
            modelo: modelo,
            marca: marca,
            cor: cor,
            velocidadeMaxima: velocidadeMaxima,
            velocidadeAtual: velocidadeAtual,
            estaLigado: estaLigado); 
  abrirPortasMalas() {
    if (temPortaMalas) print("Porta-malas aberto!");
  }
} // Continua
3 respostas
class Barco extends Veiculo {
  //estes atributo teram um valor padrão
  int qtdLugares;
  bool ancoraLevantada = false; 
  Barco(
      {required String modelo,
      required String marca,
      required String cor,
      required double velocidadeMaxima,
      required double velocidadeAtual,
      required bool estaLigado,
      this.qtdLugares = 1,
      this.ancoraLevantada = false})
      : super(
            modelo: modelo,
            marca: marca,
            cor: cor,
            velocidadeMaxima: velocidadeMaxima,
            velocidadeAtual: velocidadeAtual,
            estaLigado: estaLigado); 
  levantarAncora() {
    if (!ancoraLevantada) {
      print("Levantando ancora!");
      sleep(const Duration(seconds: 2));
      ancoraLevantada = true;
      print("Ancora levantada!");
    }
  } 
  abaixarAncora() {
    if (ancoraLevantada) {
      print("Abaixando ancora!");
      sleep(const Duration(seconds: 1));
      ancoraLevantada = false;
      print("Ancora abaixada!");
    }
  } 
//Foi preciso alterar o metodo acelerar para não funcionar 
//quando a ancora do navio estiver abaixada
  @override
  acelerar({double forca = 0.1}) {
    if (ancoraLevantada) {
      print("Barco acelerando...");
      sleep(const Duration(seconds: 1));
      velocidadeAtual += forca * 10;
    } else {
      print("Barco não pode se mover, levante a ancora primerio!");
    }
    //Garantindo que o veiculo não passe da Velociade maxima
    if (velocidadeAtual > velocidadeMaxima) {
      velocidadeAtual = velocidadeMaxima;
    }
  }
}

Olá, Wellington! Tudo bem?

Primeiramente peço desculpas pela demora em dar um retorno.

Parabéns pela criatividade no seu código, testei ele no meu computador e adorei a ideia, ficou ótimo!

Vi que você tentou implementar o mixin , achei bastante legal a sua iniciativa, infelizmente, na formação de Dart, acredito que não vemos exemplos sobre ele, é um assunto mais avançado para ser abordado em OO.

Mas sobre a utilidade do mixin, ele é usado em casos onde a Herança não é a melhor solução. Por exemplo, se tivermos uma classe mãe chamada Animal e duas classes filhas chamadas Gato, Cachorro e Lobo, e queiramos que apenas as classes Cachorro e Lobo tenham um método chamado uivar e cavarBuraco, podemos criar um mixin para isso.

Com o mixin podemos reutilizar o código e não repetir instruções em cada classe que precisar implementar a mesma coisa.

Sobre o construtor, vi que você comentou no código "O por que desses dois pontos e qual o nome disso". Essa dúvida pode ter surgido em duas situações:

  1. Se estiver se referindo aos : depois de cada nome das variáveis, a justificativa é porque você está usando um construtor com parâmetros nomeados na sua classe mãe Veiculo, então as classes filhas estão implementando um construtor que precisa ter nomes.

  2. Se estiver comentando sobre os : logo antes da palavra super(...), então a explicação é que estamos usando um construtor de redirecionamento devido a herança, estamos recebendo os valores em nosso construtor e redirecionando para o construtor da classe mãe.

Outra forma de fazer a mesma coisa porém utilizando um construtor com parâmetros posicionais seria:

  • Construtor na classe Veiculo:

    Veiculo(
       this.modelo, 
       this.marca, 
       this.cor, 
       this.velocidadeMaxima, 
       this.estaLigado,
       [this.velocidadeAtual = 0]);
  • Construtor na classe Barco:

    
    Barco(
    super.modelo, 
    super.marca,
    super.cor, 
    super.velocidadeMaxima,
    super.estaLigado,
    [this.qtdLugares = 0, 
    this.ancoraLevantada = false]
    );
  • Como ficaria na criação do objeto Barco:

    Barco lancha = Barco("Lanchax1", "Tupiniquin", "preta", 120, true, 0);

Repare que:

  1. Estamos usando [] para as variáveis que devem ser posicionais e opcionais, nas outras não utilizamos nada e elas são posicionais e obrigatórias;
  2. Usamos super.nomeDaVariavel quando estamos referenciando variáveis da classe mãe;
  3. Usamos this.nomeDaVariavel quando estamos referenciando uma variável da nossa própria classe.

Você também pediu dicas e eu pensei em uma que talvez goste! Vi que utilizou o sleep quando queria que o código esperasse determinado tempo (adorei, inclusive!), outra solução para isso, é usar Future.delayed(), nas chamadas funções assíncronas. Fiz um exemplo utilizando sua função levantarAncora, veja:

//Aqui adicionei Future<void> e async
  Future<void> levantarAncora() async {
    if (!ancoraLevantada) {
      print("Levantando ancora!");
      // Aqui usei await e o Future.delayed para esperar 2 segundos
      await Future.delayed(Duration(seconds: 2));
      ancoraLevantada = true;
      print("Ancora levantada!");
    }
  }

Vemos que as alterações feitas foram:

  1. Utilizei o Future<void> na declaração da sua função, para informar que ela é uma função do tipo Future mas que não retorna nada (<void>);
  2. Utilizei async antes de abrir as {} da função, pois ela é uma função assíncrona e utilizei await pois a instrução Future.delayed(Duration(seconds: 2)); deve ser esperada, só ao fim dela o código deve continuar.

E quando for usar o método do tipo Future não se esqueça de usar async e await também:

void main() async {
//...
  await lancha.levantarAncora();
//...
}

Esse tipo de implementação é bastante utilizada quando consumimos dados externos, da internet, por exemplo, e esse assunto é melhor abordado no curso Dart: aplicando assincronismo, caso tenha interesse.

Espero ter ajudado, bons estudos!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado. ✓

Muito agradecido, resposta superou minhas expectativas, muito obrigado, conserteza vou Estudar sobre assincronismo no dart.