No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Curso de Dart

Curso de Dart

Argel Franco Bejarano de la Cruz

Argel Franco Bejarano de la Cruz

Clases Abstractas

21/29
Recursos

Una clase abstracta no puede ser instanciada, es decir, no se puede crear objetos, aunque puede ser extendida.

Un método abstracto es estructurado, pero no definido, deberá ser sobrescrito (override) en el futuro.

Aportes 27

Preguntas 5

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

📌 Clases Abstractas son utilizadas para indicar que una clase está incompleta y sólo se van a utilizar como una clase base. Todas las clases que hereden de una clase abstracta, tomaran sus comportamientos.

RESUMEN DE LA CLASE

Clases Abstractas: Es una clase que no puede ser instanciada.

Sintaxis

abstract class NombreDeLaClase{
	void metodoAbstracto();
}

Las clases que extiendan de una clase abstracta deberán sobrescribir todos sus métodos. Esto se hace colocando la etiqueta

@override

encima de la definición del método.

Un ejemplo mas claro de uso de las Clases Abstractas.

void main() {
  Presidente pte = new Presidente();
  pte.nombre = 'Frank';
  pte.edad = 30;
  print(pte.informacion());

  Gerente ger = Gerente();
  ger.nombre = 'Lebron';
  ger.edad = 34;
  ger.registrarEntrada();
  print(ger.informacion());

  // uso de notacion en cascada
  Director dir = Director()
    ..nombre = 'Jordan'
    ..edad = 56
    ..registrarEntrada();

  dir.registrarSalida();
  print(dir.informacion());
}

// definicion de una clase abstracta
abstract class Empleado {
  String nombre;
  int edad;
  bool laborando;
  String puesto;

  String get puestoDeTrabajo => this.puesto;
  void set puestoDeTrabajo(value) => this.puesto = value;

  // metodo abstracto
  int horasTrabajadasSemana();

  void registrarEntrada() {
    if (this.laborando == null) {
      this.laborando = true;
    }
  }

  void registrarSalida() {
    if (this.laborando == true) {
      this.laborando = false;
    }
  }

  String informacion() {
    String estado = 'No ha iniciado su jornada laboral';

    if (laborando == true) {
      estado = 'Inició su jornada laboral';
    } else if (laborando == false) {
      estado = 'Terminó su jornada laboral';
    }
    // interpolacion de cadena
    return '''
    Nombre: $nombre
    Puesto: $puestoDeTrabajo
    Edad  : $edad
    Estado: $estado
    Trabajó ${this.horasTrabajadasSemana()} esta semana
    ''';
  }
}

// heredando de la clase abstracta Empleado
class Presidente extends Empleado {
  // implementando una propiedad de la clase abstracta
  String puesto = 'Presidente';

  // implementando un metodo
  int horasTrabajadasSemana() {
    return 30;
  }

  // sobreescribiendo un metodo de la clase abstracta
  @override
  String informacion() {
    // interpolacion de cadena
    return '''
    Nombre: $nombre
    Puesto: $puestoDeTrabajo
    Edad  : $edad
    Estado: No es obligatoria su asistencia a la empresa
    Trabajó ${this.horasTrabajadasSemana()} esta semana
    ''';
  }
}

// heredando de la clase abstracta Empleado
class Director extends Empleado {
  // implementando una propiedad de la clase abstracta
  String puesto = 'Director';

  // implementando un metodo de la clase abstracta
  int horasTrabajadasSemana() {
    return 35;
  }
}

// heredando de la clase abstracta Empleado
class Gerente extends Empleado {
  // implementando una propiedad de la clase abstracta
  String puesto = 'Gerente';

  // implementando un metodo de la clase abstracta
  int horasTrabajadasSemana() {
    return 40;
  }
}

Salida en la consola:

    Nombre: Frank
    Puesto: Presidente
    Edad  : 30
    Estado: No es obligatoria su asistencia a la empresa
    Trabajó 30 esta semana
    
    Nombre: Lebron
    Puesto: Gerente
    Edad  : 34
    Estado: Inició su jornada laboral
    Trabajó 40 esta semana
    
    Nombre: Jordan
    Puesto: Director
    Edad  : 56
    Estado: Terminó su jornada laboral
    Trabajó 35 esta semana

El @override entonces sirve para:
1- Definir un método en la clase actual previamente declarada en una clase Absracta.
2- Para sobreescribir un método ya implementado en una clase padre.

Que bueno que mejoro el audio a partir de este vídeo

Una anotación acerca de @override

@override sólo señala que la función también está definida en una clase de antepasados, pero está siendo redefinida para hacer algo más en la clase actual. También se usa para anotar la implementación de un método abstracto. Su uso es opcional pero se recomienda ya que mejora la legibilidad.

from StackOverflow answer: Answer here

Las clases abstractas son clases ‘incompletas’ que, debido a detalles de su implementación, son muy generales, por lo cual no pueden instanciarse, delegando el trabajo de la implementacion a sus clases hijas (que, por naturaleza, van a ser más concretas) 😃.

No me parecio nada mal para ser mi primera vez implementando clases abstractas 😄

main(List<String>arguments){
  Gato gato = Gato();
  gato.tipo = 'gato';
  gato.nombre = 'Manchitas';
  gato.comida = 'sardinas';
  gato.amigos = 'no';
  gato.descripcion();

  Perro perro = Perro();
  perro.tipo = 'perro';
  perro.nombre = 'Lulu';
  perro.comida = 'salchichas';
  perro.amigos = 'si';
  perro.descripcion();
}

abstract class Animales{
  var tipo;
  var nombre;
  var medida;
  var comida;
  var amigos;

}

class Gato extends Animales{
  void descripcion(){
    print('$nombre es un $tipo y le gusta comer $comida y $amigos tiene muchos amigos');
  }
}

class Perro extends Animales{
  void descripcion(){
    print('$nombre es un $tipo y le gusta comer $comida y $amigos tiene muchos amigos');
  }
}

Ahora se escucha mejor, genial!

Usando herencia y polimorfismo (modificando un método con el @override). Se usa la parala “super” para decir que es el metodo que viene de la clase padre:

void main() {

  Asgardiano thor = Asgardiano()
   ..nombre = 'Thor Fransisco'
   ..arma = 'los Rayitos'
   ..padre = 'el señor Odin';    
  
  thor.ataque();
  thor.familia();
  
}

class Heroe{
  var nombre;
  var arma;

  void ataque(){
    print('$nombre usa como arma $arma');
  }
}

class Asgardiano extends Heroe{
  var padre;

  void familia(){
    print('El papi de $nombre es $padre');
  }

  @override
  void ataque(){
    super.ataque();
    print('Estoy modificando el metodo al agregar esto');
  }
}

El propósito de la clase abstracta es reutilizar código.
Por ejemplo, en una clase abstracta se puede definir propiedades y métodos de forma genérica y también se puede sobreescribir los métodos y propiedades necesarios de acuerdo a la necesidad del programador:

void main(){
  var fruta=Fruta();
  fruta.imprimir();
  fruta.imprimirPadre();
}

abstract class Alimento{
  var list;
  bool bandera=true;
  
  void imprimir(){
    print (bandera);
  }
  void imprimirPadre()=>print(list);
}

class Fruta extends Alimento{
  @override var list='Sandia';
  @override void imprimir()=>print ('Valor de bandera es: ${this.bandera}');
}```

Para que una clase sea abstracta debe tener 1 o mas métodos abstractos.

¿En una clase abstracta también se pueden tener métodos que no son abstractos (que SÍ se implementan)?

alguien me explica que hace el @override?

Para los que está trabajando con intellij les dejo este shortcuts :
Alt + Enter sobre el error que les resalta el editor en la clases:

El shortcut que menciona en el minuto 06:07 y que no lo encuentra pueden jalarlo de 2 maneras:

  • La primera con Alt+Enter sobre el nombre de la class donde les marca el error y les mostrará una solución directa para sobreescribir el método.
  • La segunda con Ctrl + O, esto desplegará un menú con todos los métodos que pueden sobreescribir dentro de la clase donde están haciendo el extends.

Estos shortcuts son para productos de JetBrains, en este caso IntellijIdea, WebStorm, etc.

Aunque una clase abstracta no se puede instanciar directamente, si es posible declarar variables con el tipo de dato de la clase abstracta.

main() {
  Empleado chofer = Chofer();
  chofer.id = 1;
  chofer.nombre = 'Roberto';
  chofer.salario = 100;
  chofer.calcularSalario();
  chofer.actividad();

  Empleado cajero = Cajero();
  cajero.id = 2;
  cajero.nombre = 'Pedro';
  cajero.salario = 100;
  cajero.calcularSalario();
  cajero.actividad();
}
void main(List<String> args) {
  var bombero = Bombero();
  bombero.id = 1;
  bombero.nombre = 'Roberto';
  bombero.salario = 100;
  bombero.calcularSalario();
  bombero.quitarFuego();
  bombero.actividad();

  print('');

  var enfermero = Enfermero();
  enfermero.id = 2;
  enfermero.nombre = 'Carlos';
  enfermero.salario = 120;
  enfermero.calcularSalario();
  enfermero.curar();
  enfermero.actividad();

}

//No puede ser instanceada
abstract class Empleado {
  var id;
  var nombre;
  var salario;
  var _multiplicador = 5.5;

  void calcularSalario() {
    print('El salario de $nombre es ${salario * _multiplicador}');
  }

  void actividad();
}

class Bombero extends Empleado {
  var region;

  void quitarFuego() => print('Extinguiendo...');

  @override
  void actividad() {
    print('Entrenando...');
  }
  
}

class Enfermero extends Empleado {
  var especialidad;

  Enfermero() {
    super._multiplicador = 100;
  }

  void curar() => print('Curando...');

  @override
  void actividad() {
    print('En guardia...');
  }
}```

Muchas gracias

Comportamiento de la clase a

Entendido!

//Una clase abstracta a diferencia de una normal no puede ser instanciada, es decir, no puede crear objetos
main(List<String> args) {
  Chofer chofer = Chofer();
  chofer.id = 1;
  chofer.nombre = 'Roberto';
  chofer.salario = 100.0;

  chofer.calcularSalario();
  chofer.actividad();

  Cajero cajero = Cajero();
  cajero.id = 2;
  cajero.nombre = 'Pedro';
  cajero.salario = 120.0;

  cajero.calcularSalario();
  cajero.actividad();
}

abstract class Empleado {
  var id;
  var nombre;
  var salario;

  void calcularSalario() {
    print('El salario de el empleado es ${salario * 5.5}');
  }

  //Definir funcion abstract
  void actividad();
}

class Chofer extends Empleado {
 var vehiculo;

 void manejar() {
   print('Manejando...');
 }

  //Se ocupa de nuestra clase abstract
  @override
  void actividad() {
    print('Pasear por la ciudad');
  } 
}

class Cajero extends Empleado {
  var cajaAsignada;

  void cobrar() {
    print('Cobrando...');
  }

  //Se ocupa de nuestra clase abstract
  @override
  void actividad() {
    print('Cobrar a las personas');
  }

  //Se puede sobreescribir del original
  @override
  void calcularSalario() {
    print('El salario de el empleado es ${salario * 5.5}');
  }
}
main(){

// Map<int, dynamic> map;
// map={1:'rojo',2:'verde'};
// print(map);

Chofer chofer=Chofer();
chofer.id=1;
chofer.nombre="Roberto";
chofer.salario=100.0;
chofer.calcular_salario();
chofer.actividad();

Vendedor vendedor=Vendedor();
    vendedor.id=1;
    vendedor.nombre="Pedro";
    vendedor.salario=100.0;
    vendedor.calcular_salario();
    vendedor.actividad();


}

abstract class Empleado{
    var id;
    var nombre;
    var salario;
    void calcular_salario(){
        print('El trabajador tiene un salario de ${salario*5.5}');
    }
    void actividad();

}

class Chofer extends Empleado{
    String vehiculoAsignado;
    void manejarVehiculo(){
        print('Manejando...');
    }
    @override
    void actividad(){
        print('Pasear por la ciudad');
    }
}
class Vendedor extends Empleado{
    String idCliente;
    void venderACliente(){
        print('Vender...');
    }
    @override
    void actividad(){
        print('Cobrar a las personas');
    }
    void calcular_salario(){
        print('El vendedor tiene un salario de ${salario*5.5+100}');
    }
 }

¿De la generalización a la especialización o viceversa?

En ocasiones no es posible especializar una clase, debido a su nivel de abstracción tan genérica que se complica determinar su valor, solamente el tipo (e incluso tampoco el tipo, por ello utilizamos el operador diamante <T>).

Piensen en lo siguiente:

Todos lo animales tienen por lo menos un sonido y por lo menos están categorizados en un cierto tipo (terrestre, acuático, etc.).

Por ello, su definición en Dart con OOP:

abstract class Animal {
  String sound;
  String typeAnimal;
  Animal(this.sound, this.typeAnimal);
  void getSound();
}

Y ciertamente, no es posible instanciar de una clase abstracta un objeto (y mas que obvio porque una instancia es determinar una especialización y no una generalización). Por ello, un ejemplo de un animal es el siguiente:

class Dog extends Animal {
  String name;
  Dog(this.name) : super("Wauu!", "Overland");
  @override
  getSound() => print("$name sounds $sound");
}

Cabe mencionar que el operador @override es opcional.

Siendo prácticos, hasta aquí se utiliza una herencia. Sin embargo, UNA CLASE ABSTRACTA TEORICAMENTE ES INSTANCIADA, pero en práctica no lo es. En contexto porque se definió un constructor.

Su implementación en main:

void main() {
  var doggy = Dog("Duck");
  doggy.getSound();
}```

Codigo de la clase:

  
  //Clases abstractas
  /** Una clase abstracta no puede ser instanciada, es decir, no puede crear objetos, aunque puede ser extendida.
   * Un metodo abstracto es estructurado, pero no definido, debera ser sobrescrito 'override' en el futuro
   * */
  
  //Creamos un nuevo objecto cuando la clase Empleado no sea de tipo abstract
  //Empleado emp = Empleado(); --No puede ser instanciada
  
  //Creamos nuevos objectos con las clases hijas
  Chofer chofer = Chofer()
  //Notacion en cascada
  ..id = 1
  ..nombre = "Pepa"
  ..salario = 100;
  
  chofer.calcularSalario();
  chofer.actividad();
 
  Cajero cajero = Cajero()
  ..id = 2
  ..nombre = "Pipa"
  ..salario = 100; //Asignamos el mismo salario del empleado chofer 
  
  cajero.calcularSalario(); //Utilizamos el mismos metodo que se encuentra sobrescrito
  cajero.actividad();
  
  
}


//Clase padre - abstracta
abstract class Empleado {
  int id;
  String nombre;
  double salario;
  
  //Metodo
  void calcularSalario() {
    print("El salario del empleado $nombre es: ${salario * 5.5}");
  }
  
  //Metodo abstracto estructurado
  void actividad();
}

//Clase hija
class Chofer extends Empleado{
  String vehiculoAsignado;
  
  
  //Metodo propio
  void manejar() {
    print("Manejando...");
  }
  
  //Sobrescribimos
  @override
  void actividad() {
    print("Se dedica a: pasear por la ciudad");
  }
}

//Clase hija
class Cajero extends Empleado{
  String cajaAsignada;
  
  //Metodo propio
  void cobra() {
    print("Cobrando...");
  }
  
  //Sobrescribimos
  @override
  void actividad() {
    print("Se dedica a: cobrar a las personas");
  }
  
  //Obtenemos el metodo de la clase padre y agregamos una funcionalidad extra
  @override
  void calcularSalario() {
    //super.calcularSalario -> Ejecutara todo lo que tiene la clase padre
    print("El salario del empleado $nombre es: ${salario * 5.5 + 100 } ");
  }
}

Una explicación más sencilla https://www.youtube.com/watch?v=WRE3BbXPZNY les dejo el enlace
Y un complementario de override https://www.youtube.com/watch?v=X1HP0quXScE
(Tengo entendido que escribir “@override” es solo una buena práctica para indicar que un elemento de la clase padre fue modificado,
no les dará error si no hacen)

Para aquellos que no sepan y tengan curiosidad de que es @override; se trata de un decorador y se utiliza para cambiar el comportamiento de una función, el ejemplo esta para python pero ahora me doy cuenta que otros lenguajes también lo implementan 😉

https://realpython.com/primer-on-python-decorators/#simple-decorators
https://platzi.com/clases/1378-python-practico/14176-decoradores0075/