Programación orientada a objetos en Dart

Este es el tercer tutorial de la serie 'Mis apuntes Dart' en el cual nos adentraremos al lenguaje Dart desde lo más básico hasta conocer lo necesario para crear aplicaciones moviles con Flutter.

En este tutorial aprenderemos los elementos de la programación orientada a objetos en Dart.

Índice

  1. Clases
  2. Getter y setter en una clase
  3. La herencia
  4. Clases abstractas
  5. Interfaces
  6. Mixins

1. Clases

Para crear una clase en Dart podemos hacer lo siguiente.

class Employe{
  var id;
  var name;

  bool cumplioHorario(){
    return true;
  }

  void work(){
    print('El empleado $name ya realizo su trabajo');
  }
}

Para crear un bojeto en Dart no es necesario usar la palabra clave new. Esat palabra es opcional. Asi que podemos crear objetos a partir de clases de la siguiente manera.

Employe emp = Employe();
emp.id = 1;
emp.name = 'Andy';

Además podemos usar la notación en cascada de la siguiente forma para asignar las variables globales de clase.

Employe emp2 = Employe()
..id = 2
..name = 'AndyGeek';

2. Getter y setter en una clase

Las variables publicas en DArt se acceden mediante el punto al igual que lo hicimos en los ejemplos anteriores. Sin embargo para hacer una variable privada en Dart solo basta con colocar el guion bajo _ al inicio del nombre de la variable.

class Employe{
  var _id;
  var _name;

  bool cumplioHorario(){
    return true;
  }

  void work(){
    print('El empleado $_name ya realizo su trabajo');
  }
}

Para crear los setter y getter para estas variables usamos el set y get que nos proporciona Dart de la siguiente forma.

void set id(int id){
  _id = id;
}

int get id{
  return _id;
}

O incluso usando funciones flecha de la siguiente forma.

void set id(int id) => _id = id;
int get id => _id;

Para crear la clase y usar el set y get fuera de la clase hacemos lo siguiente.

import 'employe.dart';

void main(){
  Employe emp = Employe();
  emp.id = 1;
  print(emp.id);
}
Para que esta creación de getter y setter que aprendimos funcione las clases deben estar creadas en un archivo diferente al donde se usarán.

3. La herencia

Para que una clase herede los atributos y métodos de otra clase usamos la palabra reservada extend de la siguiente forma.

class Empleado{
  var id;
  var name;
  double salario;

  void calcularSalario(){
    print('El salario de $name es $salario');
  }
}

// Hereda de Empleado
class Chofer extends Empleado{
  String vehiculoAsignado;
  void manejar(){
    print('Manejar vehiculo');
  }
}
Recuerda comenzar con mayusculas el nombre de una clase.

Luego de aplicar herencia cuando creamos una instancia del objeto hijo podrems utilizar los métodos y variables de la clase padre.

main(){
  Chofer chofer = Chofer();
  chofer.id = 1;
  chofer.name = 'Andy';
  chofer.salario = 11.00;
  chofer.vehiculoAsignado = 'Toyota Supra';
  chofer.calcularSalario();
  chofer.manejar();
}

4. Clases abstractas

Las clases abstractas tienen la caracteristica de que no pueden ser instanciados además los métodos que solo están nombrados deben ser definidas necesariamente en las clases hijas.

Por ejemplo si tenemos la clase padre Forma que tiene a las clases hijas Cuadrado, Triangulo, etc. Y decidimos que como regla la clase Forma no tendrá instancia podemos hacer de esta clase una clase abstracta.

abstract class Forma{
  var id;
  var perimetro;
  var area;

  void calcularArea(){
    print('Calculo por defecto');
  }
  void calcularPerimetro();
}

class Cuadrado extends Forma {
  
  void calcularPerimetro() {
    // TODO: implement calcularPerimetro
  }
}

5. Interfaces

Dart no cuenta con una palabra reservada para interfaces como en otros lenguajes. Una clase normal puede funcionar como una interface , solo usaremos la palabra reservada implement en la clase que usará la interface.

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

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

class Conducta{
  void buenaConducta(){
    print('El empleado tiene buena conducta');
  }
}

class Chofer implements Conducta, Empleado {
  
  var id;

  
  var nombre;

  
  var salario;

  
  void buenaConducta() {
    // TODO: implement buenaConducta
  }

  
  void calcularSalario() {
    // TODO: implement calcularSalario
  }

}

Como puedes ver usar alguna función de interface nos obliga a redefinir o sobreescribir cada una de las funciones y a obtener cada una de las variables de las clases interface.

6. Mixins

Los Mixins son una especie de clase abstracta ya que no pueden ser instanciadas y donde puedes definir parametros y métodos que luego pueden ser sobre escritos o usados tal como estan, en caso de estar bien definidos. Sin embargo, Las clases abstractas solo pueden ser heredadas una vez. No hay herencia multiple en Dart. Pero entonces si lo que queremos es que una clase herede de multiples clases sus propiedades y métodos usamos los Mixins.

abstract class Animal {}

abstract class Mamifero extends Animal {}
abstract class Ave extends Animal {}
abstract class Pez extends Animal{}

mixin Volador {
  int id;
  void volar() => print('Estoy volando');
}
mixin Caminante {
  void caminar() => print('Estoy caminando');
}
abstract class Nadador {
  void nadar() => print('Estoy nadando');
}

class Delfin extends Mamifero with Nadador {}
class Murcielago extends Mamifero with Caminante, Volador {}
class Gato extends Mamifero with Caminante {}
class Paloma extends Ave with Caminante, Volador {}
class Pato extends Ave with Caminante, Volador, Nadador {}

Como puedes ver en el ejemplo anterior las clases pueden heredar de multiples clases mixins para obtener propiedades y métodos de estas.

Fin de este tercer tutorial sobre fundamentos de Dart, como ves Dart es bastante intuitivo asi que te animo a seguir el siguiente tutorial donde aprenderemos más sobre este fabuloso lenguaje de programación.