Está en la página 1de 16

Bienvenido al curso sobre Dart. Este curso te guía para avanzar conceptos en Dart.

Aprenderá los siguientes temas en este curso.

 Manejo de excepciones
 Conceptos avanzados de clase
 Clases invocables y aislamientos
 Genéricos
 Tipos de letra y metadatos
 Bibliotecas
 Programación asincrónica
 Generadores
Entonces comencemos.
Introducción
En el curso anterior, Dart - Guía para principiantes, aprendió acerca de Dart, utilizando tipos
incorporados, declarando variables, definiendo funciones, creando funciones usando
parámetros con nombre y posicionados opcionales, creando una clase usando un
constructor con nombre.
En este curso, aprenderá más sobre conceptos de clase, herencia, operadores
reemplazables, uso de genéricos, manejo de excepciones, mixins y programación
asincrónica.
Manejo de excepciones

Las excepciones se utilizan para indicar errores que ocurren durante el tiempo de ejecución.
Todas las excepciones en dart son excepciones no verificadas (verificaciones durante el
tiempo de ejecución). Excepción y Error
son tipos predefinidos que se utilizan
para generar excepciones. Dart también
admite la creación de excepciones
definidas por el usuario.
El programa finaliza cuando no se
detectan las excepciones.
Try, - Throw - Catch

try, throw y catch se utilizan para manejar la excepción. Try se usa para lanzar la excepción
al bloque catch. Throw se usa para lanzar una excepción explícitamente. Puede usar catch y
on para capturar la excepción que se produce mediante el bloque try. Catch se usa cuando
se necesita el objeto de excepción para el manejo, y puede manejar todo tipo de excepción.
On se usa cuando necesita especificar el tipo de excepción.

void main() {
String a = "welcome to dart";
try {
int v = int.parse(a);
print("$v");
} on IntegerDivisionByZeroException {
print("divide by zero");
} catch (e) {
print(e);
}
}

Finally
Se puede lanzar una excepción o no, pero se ejecuta el bloque finally.
Sintaxis:

try{
//statements
}
on specific_exception{
}
catch e{
}
finally{
//finally block
}
void main() {
double a = 6, b = 0;
try {
if (b == 0) {
throw IntegerDivisionByZeroException();
}
print("${a / b}");
} on IntegerDivisionByZeroException {
print("divide by zero");
} catch (e) {
print(e);
} finally {
print("Code executed");
}
}

Clase Abstracta

abstract class SampleCode {


add(dynamic a, dynamic b);
display(int c);
}
class SampImplement implements SampleCode {
add(dynamic a, dynamic b) {
return a + b;
}
display(dynamic c) {
print("$c");
}
}
void main() {
SampImplement obj = SampImplement();
obj.display(obj.add(5, 6));
obj.display(obj.add(5.8, 9.7));
obj.display(obj.add("Welcome", " dart"));
}
Interfaces implícitas
En Dart, cada clase define implícitamente una interfaz. Si una clase implementa otra clase
como interfaz, debe implementar todas las variables y métodos de la clase de interfaz.

class SampleCode {
display(String c) {
print("Class SampleCode:$c");
}
}
class SampImplement implements SampleCode {
display(String c) {
print("Class SampImplement:$c");
}
}
void main() {
SampleCode obj1 = SampleCode();
obj1.display("welcomes");
SampImplement obj2 = SampImplement();
obj2.display("Dart 2.1");
}

Herencia
Dart solo admite herencia única.Para heredar una clase, usa la palabra clave extend.
Synt:

class SubClass extends BaseClass{


// instance variables
//methods
}
class BaseCode {
int a, b;
display(int c) {
print("Result:$c");
}
}
class DerivedCode extends BaseCode {
DerivedCode(int a, int b) {
super.a = a;
super.b = b;
}
add() {
//when using the keyword super
//calls the super class function
super.display(a + b);
}
display(int c) {
print("welcome");
}
}
void main() {
DerivedCode obj = DerivedCode(10, 9);
obj.add();
}

Miembros primordiales

Una clase puede anular sus miembros de clase base.Para indicar que está anulando un
miembro, use la anotación @override.
Operadores anulables
Los operadores pueden ser anulados.
Los operadores reemplazables son <, +, |, [],>, /, ^, [] =, <=, ~ /, &, ~,> =, *, <<, ==, -,%, >>
class DerivedCode {
int a;
DerivedCode(this.a);
operator +(DerivedCode obj) {
return this.a + obj.a;
}
}
void main() {
DerivedCode obj1 = DerivedCode(6);
DerivedCode obj2 = DerivedCode(7);
// + operator overrided
int sum = obj1 + obj2;
print("Sum:$sum");
}

Enums

Los tipos enumerados son un tipo especial de clase. Se utiliza para representar valores
constantes. Use la palabra clave enum para declarar enumeraciones.
Sintaxis :
enum enum_name {const_values, const_values ...}
P.ej. enum Cars {hatchback, sedán, suv}

Mixins
Mixin se usa para reutilizar el código de clase en varias clases.Use la palabra clave with
seguido de nombres mixin.
Sintaxis:
class ClassName with mixin_name {}
La clase mixin debería extender la clase Object y los constructores no deberían
declararse.También puede usar la palabra clave mixin para la clase mixin en lugar de la
palabra clave class.

class SampA {
dynamic disp;
void display() {
print("Result:$disp");
}
}
class SampB with SampA {
add(int a, int b) {
disp = a + b;
}
}
main() {
SampB obj = SampB();
obj.add(5, 8);
obj.display();
}

En lugar de clase, puede usar la palabra clave mixin para SampA.

Clase Callable en Dart

Las clases se pueden llamar como una función implementando el método call () dentro de la
clase.El método call () se usa para emular una función.
Considere que se evalúa samp (int a, int b). Si es una función normal, se llama de lo
contrario, intenta invocar el método call (). Si se implementa samp con el método call (), se
invoca.

class SampCallable {
call(String val) {
print(val);
}
}

void main() {
SampCallable obj = SampCallable();
//Callable class
obj("welcome to dart 2");
}

El código anterior usa la clase callable mediante la implementación del método call (). El
método de llamada toma una cadena e imprime.

Aislamientos

En la mayoría de las computadoras y


móviles, se utiliza CPU de múltiples
núcleos. Tradicionalmente, los subprocesos
de memoria compartida se utilizan para
hacer que todos los núcleos sean
utilizables, que son propensos a errores y
conduce a un código complicado.
Se utilizan aislamientos en lugar de hilo.
Cada aislamiento tiene su memoria de
almacenamiento dinámico y garantiza que
otros aislamientos no puedan acceder al
estado de un aislamiento.
Genéricos
En la documentación de la API de dardos, verá la notación <..> que se marca como un tipo
genérico. La clase Lista en la documentación tiene Lista <E>.
Las variables de tipo tienen nombres de una letra, como T, S, K, V y E. Ej .: Mapa <K, V>, Lista
<E>, Conjunto <E> e Iterador <E>.
Se usa para la seguridad de tipos y también se puede usar para reducir la duplicación de
código.

Colección Literales
En Dart, la lista y el mapa se pueden parametrizar.Los literales parametrizados son como
literales.

List car_type = <String>['hatchback', 'SUV', 'sedan'];


Map department = <int,String>{1: 'sales', 2: 'marketing', 3: 'admin'};
Métodos genéricos
Puede usar el genérico para los métodos.

add_t<T>(List lst) {
dynamic v = (T == int) ? 0 : "";
lst.forEach((val) {
v += val;
});
return v;
}

void main() {
List list1 = [1, 2, 3, 4, 5];
List list2 = ["welcome", "to", "dart"];
int res1 = add_t<int>(list1);
String res2 = add_t<String>(list2);
print("Sum:$res1");
print("$res2");
}

Typedefs
Las funciones son objetos en Dart.Un typedef le da un nombre al tipo de función.Se utiliza
para declarar campos y tipos de retorno.

class SampTypedef {
Function addition;
SampTypedef(int func(int a, int b)) {
addition = func;
}
}
int add(int a, int b) => a + b;
main() {
SampTypedef obj = SampTypedef(add);
print("${obj.addition(5, 7)}");
}

Metadatos

Los metadatos proporcionan información adicional.Una anotación de metadatos comienza


con @ seguido de una referencia a una constante de tiempo de compilación (en desuso) o
una llamada a un constructor constante.@deprecated y @override son las dos anotaciones
que están disponibles para todos los códigos de dardos.

class Arithmetic {
/// _Deprecated: Use [add] instead._
@deprecated
sum(int a, int b) {
return add(a, b);
}

add(int a, int b) => a + b;


}

Metadatos definidos por el usuario

Puede crear su propia anotación de metadatos. Archivo de la biblioteca

library sample_lib;
class SampleCode{
final String name;
const SampleCode(this.name);
}

Código para usar anotaciones.

import 'sample_lib.dart';
@SampleCode("userdefined_annotation")
display()
{
print("welcome to dart");
}

Librerías
Las directivas de importación y biblioteca ayudan a crear una base de código modular y
compartible. Los identificadores que comienzan con un guion bajo “_” solo son visibles
dentro de la biblioteca que proporciona una unidad de privacidad. Cada aplicación Dart es
una biblioteca y las bibliotecas se pueden distribuir mediante paquetes. Para usar la
biblioteca dentro del programa, use importar para especificar paquetes o biblioteca. Por
ejemplo: importar 'dart: html'; importar 'dart: async' ;, etc.
Especificar un prefijo de biblioteca
Al importar dos bibliotecas puede haber identificadores en conflicto, en ese caso, puede
especificar un prefijo para una o ambas bibliotecas.

import 'package:lib/samp1.dart';
import 'package:lib/samp2.dart' as samp2;

// Uses SampCode from lib.


SampCode obj1= SampCode();

// Uses SampCode from lib.


samp2.SampCode obj2 = lib2.SampCode();

Importar solo parte de una biblioteca


Solo puede importar parte de una biblioteca.

// Import only action.


import 'package:lib/samp1.dart' show action;

// Import all names EXCEPT display.


import 'package:lib/sam2.dart' hide display;

Paquetes de biblioteca
Para crear código modular, use bibliotecas que se puedan compartir fácilmente. En Dart, las
bibliotecas se crean y distribuyen como paquetes. Dart tiene dos tipos de paquetes:
paquetes de aplicación (incluye biblioteca local) paquetes de biblioteca

Diseño de paquete de biblioteca


El archivo pubspec y el directorio lib son los
requisitos mínimos necesarios para una biblioteca.
Para una biblioteca, el archivo pubspec.yaml es el
mismo que para un paquete de aplicación, no hay
una designación especial para indicar que el
paquete es una biblioteca.
Todos los códigos de la biblioteca son lugares dentro
del directorio lib y es público para otros paquetes.
Los códigos de implementación se colocan dentro del directorio lib / src y se consideran
privados. Para hacerlo público, exporte los archivos lib / src. por ejemplo, exportar
"samp.dart";
Ejemplo de biblioteca

library sample_lib;

class SampleCode {
display() {
print("welcome to dart");
}
}

El código anterior es un ejemplo de creación de un archivo de biblioteca.

import 'sample_lib.dart';

main() {
SampleCode obj = SampleCode();
obj.display();
}

Programación asincrónica
La programación asincrónica se utiliza para ejecutar la operación de forma asincrónica sin
hacer que la otra operación espere.
La programación asincrónica se caracteriza por las clases Future y Stream. El programa
asincrónico se utiliza para operaciones que requieren mucho tiempo, como E / S.
Las palabras clave asíncrona y en espera se utilizan para la programación asincrónica que
ayuda a escribir código asincrónico.
Future and Stream
En dart, todas las funciones de la biblioteca devuelven objetos futuros o continuos.Una
función Future calcula el código que no se completa de inmediato.La función Future
devuelve un objeto futuro que contiene el mismo resultado que una función normal.Una
secuencia de eventos asincrónicos es una secuencia.
Future
En Dart, la ejecución del código es de un solo subproceso que hace que el programa se
congele cuando el código bloquea el subproceso.
Future representa los resultados de las operaciones asincrónicas. Una función asíncrona
debe marcarse con un modificador asíncrono y también hace que la función devuelva un
futuro. Use wait en una función asíncrona para suspender la ejecución hasta que termine el
futuro.

Future display() async {


var sum = 0;
for (int i = 1; i < 10; i++) {
sum += i;
}
return sum;
}

void main() {
display().then(print);
print("welcome to dart");
}

En el código anterior, la función display () usa el tipo futuro que hace asíncrono.
Usando await
Await espera a que se complete la función asincrónica.Await solo se puede usar dentro de
una función asíncrona.
Future display() async {
var sum = 0;
for (int i = 1; i < 10; i++) {
sum += i;
}
return sum;
}

main() async {
await display().then(print);
print("welcome to dart");
}

Stream
Streams proporcionan una secuencia asíncrona de datos, como eventos generados por el
usuario, que leen un archivo. Await of o listen() se puede usar para procesar una secuencia.
Hay dos tipos de transmisiones: suscripción única y transmitir (single subscription –
broadcast )

import 'dart:async';
Future<int> sumStream(Stream<int> stream) async {
var sum = 0;
await for (var value in stream) {
sum += value;
}
return sum;
}
//tests by generating a simple stream of integers
Stream<int> countStream(int to) async* {
for (int i = 1; i <= to; i++) {
yield i;
}
}
main() async {
var stream = countStream(5);
var sum = await sumStream(stream);
print(sum); // 15
}

Single Subscription Streams


Las secuencias de suscripción única se utilizan para los eventos que deben entregarse en el
orden correcto y sin perder ningún dato. Escucha eventos solo una vez, como leer un
archivo o recibir una solicitud web. Obtiene los datos una vez que comenzó a escuchar.

Broadcast Streams
Las transmisiones se utilizan para manejar mensajes individuales uno a la vez. Puede
comenzar a escuchar en cualquier momento y uno o más oyentes pueden usarse para
escuchar al mismo tiempo.Se puede usar para eventos como eventos del mouse.

Generadores
Los generadores se utilizan para producir perezosamente (lentamente) una secuencia de
valores.Hay dos tipos de funciones generadoras. Synchronous generator: devuelve un
objeto Iterable. Asynchronous generator: devuelve un objeto Stream.

Generador síncrono
Un generador síncrono produce valores bajo demanda y los consumidores extraen los
valores del generador.Para implementar una función de generador síncrono, el cuerpo de la
función debe marcarse con sync * y usar el rendimiento para entregar valores.

IIterable<int> walkto(int limit) sync* {


for (int index = 0; index < limit; index++) {
yield index;
}
}
void main() {
Iterable itr = walkto(3);
itr.forEach((val) {
print("$val");
});
print("welcome to dart");
}
Generador asincrónico
Un generador asíncrono produce valores a su propia velocidad y los valores se expulsan
donde los consumidores pueden encontrarlos.
Para implementar una función generadora asíncrona, el cuerpo de la función se marca con
asíncrono * y usa el rendimiento para entregar valores.

Stream<int> asyncwalkto(int limit) async* {


for (int index = 0; index < limit; index++) {
yield index;
}
}
void main() {
Stream str = asyncwalkto(3);
str.forEach((val) {
print("$val");
});
print("Welcome to dart");
}

También podría gustarte