Fazer download em pdf ou txt
Fazer download em pdf ou txt
Você está na página 1de 29

Dart POO

Classes
import 'camiseta.dart';

void main() {
// assim cria uma instancia da classe camiseta
var camisetaNike = Camiseta();
camisetaNike.tamanho = 'G';
camisetaNike.cor = 'Preta';
camisetaNike.marca = 'Nike';

print('''
Camiseta:
Tamanho ${camisetaNike.tamanho}
Cor: ${camisetaNike.cor}
Marca: ${camisetaNike.marca}
tipoLavagem: ${camisetaNike.tipoLavagem()}
''');

//! Metodos e atributos de instancia são unicos para todo o sistema


print(Camiseta.nome);
print(Camiseta.recuperarNome());
}

'camiseta.dar

// Publico public
// Privado private

// Caracteristicas
// Comportamentos
class Camiseta {
// Atributos de instância
String? tamanho;
// colocando como privado
String? _cor;
String? marca;

// encapsulamento
// metodos para ser acessado
String? get cor => _cor;
set cor(String? cor) {
if (cor == 'Verde') {
throw Exception('Não pode ser Verde');
}
}

// Atributo de classe
//! boa pratica todo atributo static deve ser const
static const String nome = 'Camiseta';

// Metodos de classe
static String recuperarNome() => nome;

// Funcoes dentro de classes


// São chamados de Métodos de instancia
String tipoLavagem() {
if (marca == 'Nike') {
return 'Não pode lavar na maquina';
} else {
return 'Pode lavar na maquina';
}
}
}

// classe privada
class _Camiseta1 {
void recuperadorCor() {
var camiseta = Camiseta();
camiseta._cor = 'Verde';
}
}

Construtores
import 'pessoa.dart';

void main() {
var pessoa = Pessoa(
nome: 'Rodrigo Rahman',
idade: 38,
sexo: 'Masculino',
);

print(pessoa.nome);
// chamar construtor nomeado
var pessoaNomeado = Pessoa.semNome(idade: 38, sexo: 'Feminino');
}

'pessoa.dart'

class Pessoa {

// construtor serve ara criar um padrão, pois podemos definir quais


atributos devemos trabalhar

String? nome;
int? idade;
String? sexo;

// Construtor default todas as classes já tem automaticamente


/**Pessoa();

Pessoa({
required String nomeConstrutor,
required int idadeConstrutor,
required String sexoConstrutor,
}) {
nome = nomeConstrutor;
idade = idadeConstrutor;
sexo = sexoConstrutor;
}**/

Pessoa({
required this.nome,
required this.idade,
required this.sexo,
});

// construtor nomeado
Pessoa.semNome({
required this.idade,
required this.sexo,
});

Pessoa.vazia();

// factory = fabrica
// fabrica uma instancia de uma pessoa
//! utilizado para quando precisamos criar uma regra para criação da
nossa classe
factory Pessoa.fabrica(String nomeConstruc){
var nome = nomeConstruc + '_Fabrica';
var pessoa = Pessoa.vazia();
pessoa.nome = nome;

return pessoa;
}
}

Inicializadores
class Produto {
final int? _id;
final String? nome;
final double? _preco;

Produto({required int? id, required this.nome, required double?


preco,}) : _id = id, _preco = preco {
print(_id);
print(_preco);
}
}

Herança
import 'cachorro.dart';

void main(){
var cachorro = Cachorro(idade: 10);
cachorro.tamanho = 'Grande';

print('''
Cachorro:
Tamanho: ${cachorro.tamanho}
Idade: ${cachorro.idade}
Idade Humana: ${cachorro.calcularIdadeHumana()}
''');
}
'cachorro.dart'

import 'animal.dart';

class Cachorro extends Animal {

Cachorro({required super.idade});
//Cachorro({required int idade}) : super(idade: idade);

@override // metadados
int calcularIdadeHumana() {
return idade * 7;
}

'animal.dart'

// usando abstract forço a class que herdam a reescrever no caso


calcularIdadeHumana
abstract class Animal {

String? tamanho;
int idade;

Animal({required this.idade});

int recuperarIdade(){
return idade;
}

// metodo que deve ser reescrito


int calcularIdadeHumana();
}

Herança Covariante
import 'fruta.dart';
import 'humano.dart';

import 'banana.dart';
import 'macaco.dart';

void main(){
var humano = Humano();
humano.comer(Fruta());

var macaco = Macaco();


macaco.comer(Banana('nanica'));
}

'humano.dart'

import 'fruta.dart';
import 'mamifero.dart';

class Humano extends Mamifero{


@override
void comer(Fruta fruta) {
}

'fruta.dart'

class Fruta{

'mamifero.dart'

import 'fruta.dart';

abstract class Mamifero {

// com a palavra reservada COVARIANT o dart deixa trabalhar desde que


seja filha
// uso muita especifica, quando quero aceitar uma sobreescrita com
classes filhas do que você está trabalhando
void comer(covariant Fruta fruta);
}
'macaco.dart'

import 'banana.dart';
import 'mamifero.dart';

class Macaco extends Mamifero{


@override
void comer(Banana fruta) {
print(fruta.tipo);
}
}

'banana.dart'

import 'fruta.dart';

class Banana extends Fruta{


final String tipo;

Banana(this.tipo);
}

Associação
class Pessoa{
String? nome;

//! Temos dois tipo de associação, por meio de composição e agregação


// Composicao
// Quando um atributo de associação é obrigatório
// Nós estamos falando de composição !!!
Endereco endereco = Endereco();
CPF cpf = CPF();

// Agregação
// Quando um atributo de associação não é obrgatório
// Nós estamos falando de agregação !!!
Telefone? relefone;
}

class Endereco{}
class CPF{}
class Telefone{}
Polimorfismo
import 'anestesista.dart';
import 'obstreta.dart';
import 'pediatra.dart';
import 'residenteDeAnestesia.dart';

import 'medico.dart';

void main(){
// O polimorfismo permite que classes abstratas consigam receber
comportamentos através de classes concretas.
// Parto

var medicos = <Medico>[


ResidenteDeAnestesia(),
Anestesista(),
Obstreta(),
Pediatra(),
];

// Realizar um parto
for(var medico in medicos){
medico.operar();
}
}

anestesista.dart

import 'medico.dart';

class Anestesista extends Medico{


@override
void operar() {
// Anestesiar a paciente
print('Prepara o paciente e aplica anestesia');
}
}

medico.dart

abstract class Medico{


void operar();
}
obstreta.dart

import 'medico.dart';

class Obstreta extends Medico{


@override
void operar() {
// realiza a cirurgia
print('realiza a cirurgia');
}

pediatra.dart

import 'medico.dart';

class Pediatra extends Medico{


@override
void operar() {
// Examina a criança
print('Examina a criança após o nascimento');
}

residenteDeAnestesia.dart

import 'anestesista.dart';

class ResidenteDeAnestesia extends Anestesista{


@override
void operar() {
print('Preparar e esterelizar os equipamentos');
}
}
Interfaces
import 'carro.dart';
import 'gol.dart';

void main(){
var gol = Gol();

printDadosDoCarro(gol);
}

void printDadosDoCarro(Carro carro){


print('''
Carro:
Tipo: ${carro.runtimeType}
Portas: ${carro.portas}
Rodas: ${carro.rodas}
Motor: ${carro.motor}
Velocidae: ${carro.velocidadeMaxima()}
''');
}

carro.dart

// Isso aquie é uma class abstrata


// pois tem métodos implementado !!!

abstract class CarroClassAbstrata {


void velocidadeMaxima(){}
}

// Isso aqui é uma interface


// Pois não tem nunhum método implementado!!!
abstract class Carro{

abstract int portas;


abstract int rodas;
abstract String motor;

int velocidadeMaxima();
}
gol.dart

import 'carro.dart';

class Gol implements Carro {


@override
String motor = '2.0';

@override
int portas = 4;

@override
int rodas = 4;

@override
int velocidadeMaxima() {
return 120;
}

uno.dart

import 'carro.dart';

class Uno implements Carro {


@override
String motor = '1.0';

@override
int portas = 4;

@override
int rodas = 4;

@override
int velocidadeMaxima() {
return 80;
}

}
Auto promoção
import 'uno.dart';
import 'carro.dart';
import 'gol.dart';

void main(){
var gol = Gol();
var uno = Uno();

Carro golCarro = Gol();

printDadosDoCarro(gol);
printDadosDoCarro(uno);

// Quando checamos se a variavel é(is) de um tipo


// Caso ela seja o dart vai automaticamente converter
// essa instancia para a classe do Tipo!!!
if(golCarro is Gol) {
golCarro.tipoDeRodas();
}
}

void printDadosDoCarro(Carro carro){


print('''
Carro:
Tipo: ${carro.runtimeType}
Portas: ${carro.portas}
Rodas: ${carro.rodas}
Motor: ${carro.motor}
Velocidae: ${carro.velocidadeMaxima()}
Tipo de Rodas: ${carro is Gol ? carro.tipoDeRodas() : 'Não
disponivel'}
''');
}

carro.dart

// Isso aquie é uma class abstrata


// pois tem métodos implementado !!!

abstract class CarroClassAbstrata {


void velocidadeMaxima(){

}
}
// Isso aqui é uma interface
// Pois não tem nunhum método implementado!!!
abstract class Carro{

abstract int portas;


abstract int rodas;
abstract String motor;

int velocidadeMaxima();
}

import 'carro.dart';

class Gol implements Carro {


@override
String motor = '2.0';

@override
int portas = 4;

@override
int rodas = 4;

@override
int velocidadeMaxima() {
return 120;
}

String tipoDeRodas(){
return 'Esportes';
}

uno.dart

import 'carro.dart';

class Uno implements Carro {


@override
String motor = '1.0';

@override
int portas = 4;
@override
int rodas = 4;

@override
int velocidadeMaxima() {
return 80;
}

Mixins
import 'joao.dart';

void main(){
var joao = Joao();

print('''
João:
Habilidade: ${joao.habilidade()}
Cantar: ${joao.cantar()}
Dançar: ${joao.dancar()}
''');
}

joao.dart

import 'artista.dart';
import 'cantar.dart';
import 'dancar.dart';

// Não pode extender um mixin


class Joao extends Artista with Dancar, Cantar implements
ArtistaInterface{

abstract class ArtistaInterface{}


artista.dart

abstract class Artista{


String habilidade(){
return 'Artista Geral';
}
}

cantar.dart

abstract mixin class Cantar{


String cantar(){
return 'Rock';
}
}

dancar.dart

import 'artista.dart';

mixin Dancar on Artista{


String dancar(){
return 'Forró';
}

@override
String habilidade(){
return 'Dançar';
}
}

Cascade notation
void main() {

// Cascade Notation é usar o (..)


var pessoa = Pessoa()
..nome = 'Rodrigo Rahman'
..email = 'rodrigorahman@academiadoflutter.com.br'
..site = 'academiadoflutter.com.br';

// usando Cascade Notation


var mapa = <String, String>{}
..putIfAbsent('nome', () => 'Rodrigo')
..putIfAbsent('email', () => 'null')
..putIfAbsent('site', () => '');

print('''
Pessoa:
Nome: ${pessoa.nome}
Email: ${pessoa.email}
Site: ${pessoa.site}
''');
}

class Pessoa{
String? nome;
String? email;
String? site;
}

Callable class
import 'enviar_email.dart';

void main(){
var enviarEmail = EnviarEmail();

enviarEmail('alex.sdmg@gmail.com');
}

enviar_email.dart

class EnviarEmail{

bool call(String email){


print('Chamando método call');
return enviar(email);
}

bool enviar(String email){


print('Chamando método enviar');
return true;
}
}
Operator methods
import 'numero.dart';

void main() {
var num1 = Numero(10);
var num2 = Numero(20);

var totalSoma = num1 + num2;


print(totalSoma.i);
}

numero.dart

class Numero{
int i;

Numero(this.i);

Numero operator +(Numero numero2){


return Numero(i + numero2.i);
}
}

Assignment operators
void main(){
// = -= /= %= >>= ^=
// += *= ~/= <<= &= |=

var numero = 1;

numero = numero + 2;

// assignment operators
numero += 2;

print(numero);
}
Equals hashcode
import 'pessoa.dart';

void main() {
var p1 = Pessoa(nome: 'Rodrigo', email:
'rodrigorahman@academiadoflutter.com');
var p2 = Pessoa(nome: 'Rodrigo', email:
'rodrigorahman@academiadoflutter.com');

print(p1.hashCode);
print(p2.hashCode);

print(p1);

if(p1 == p2){
print('É igual');
} else {
print(' Não é igual');
}
}

pessoa.dart

class Pessoa {
String nome;
String email;

Pessoa({
required this.nome,
required this.email,
});

@override
bool operator ==(Object other) {
if (identical(this, other)) return true;

return other is Pessoa &&


other.nome == nome &&
other.email == email;
}

@override
int get hashCode => nome.hashCode ^ email.hashCode;

@override
String toString() {
return '''
Pessoa:
nome: $nome,
email: $email

''';
}
}

Ordenação default
import 'cliente.dart';

void main(){
var c1 = Cliente(nome: 'Alex', telefone: '123456798');
var c2 = Cliente(nome: 'Kenia', telefone: '646131451');
var c3 = Cliente(nome: 'Gabriela', telefone: '98423123');
var c4 = Cliente(nome: 'Jacqueline', telefone: '564642135');

var lista = [c1, c2, c3, c4];

print(lista);
lista.sort();
print(lista);
}

cliente.dart

class Cliente implements Comparable<Cliente>{


String nome;
String telefone;

Cliente({
required this.nome,
required this.telefone,
});

@override
String toString() => 'Cliente(nome: $nome, telefone: $telefone)';

@override
int compareTo(Cliente other) {
return nome.compareTo(other.nome);
}
}
Asserts
import 'cliente.dart';

void main(){
var cli = Cliente(
cpf: '13213',
nome: 'salslaslas',
//razaoSocial: 'kfkkdfd',
//cnpj: '132454'
);
}

cliente.dart

class Cliente {
String? nome;
String? cpf;

String? razaoSocial;
String? cnpj;

Cliente({
this.nome,
this.cpf,
this.razaoSocial,
this.cnpj,
}) : assert((cpf != null) ? nome != null && razaoSocial == null && cnpj
== null : true, 'Você enviou cpf junto com cnpj');
}

Modificadores
import 'pessoa.dart';

void main(){
var p1 = const Pessoa(nome: 'Rodrigo', idade: 37);
var p2 = const Pessoa(nome: 'Rodrigo', idade: 37);

print(p1 == p2);
}
pessoa.dart

class Pessoa{
final String nome;
final int idade;

const Pessoa({
required this.nome,
required this.idade
});
}

Extension
import 'pessoa.dart';
import 'pessoa_saudacao_extension.dart';
import 'saudacao_string_extension.dart';

void main(){
// extensions é a capacidade de adicionar funcoes dentro de classes que
você não tem o codigo fonte
var nome = 'Rodrigo Rahman';

// aqui adicionamos um metodo dentro de uma classe que não temos o


codigo fonte
print(nome.saudacao());

var p1 = Pessoa(nome: 'Alex Sander');

print(p1.saudacao());
}

pessoa.dart

class Pessoa{
String nome;

Pessoa({
required this.nome
});

}
pessoa_saudacao_extension.dart

import 'pessoa.dart';

extension PessoaSaudacaoExtension on Pessoa {


String saudacao(){
return 'Olá $nome bem viando a academia do flutter';
}
}

saudacao_string_extension.dart

extension SaudacaoStringExtension on String {


String saudacao(){
return 'Olá $this bem vindo a academia do flutter';
}
}

Metadatas
import 'dart:mirrors';

import 'fazer.dart';
import 'pessoa.dart';

void main() {
final p1 = Pessoa();

InstanceMirror instanceMirror = reflect(p1);

ClassMirror classMirror = instanceMirror.type;

classMirror.metadata.forEach((annotation) {
var instanceAnnotation = annotation.reflectee;

if(instanceAnnotation is Fazer){
print('Quem: ${instanceAnnotation.quem}');
print('O Que: ${instanceAnnotation.oque}');
}
});

classMirror.declarations.values.forEach((declarationMirror) {
if(declarationMirror is VariableMirror){
declarationMirror.metadata.forEach((annotation) {
var instanceAnnotation = annotation.reflectee;

if(instanceAnnotation is Fazer){
print('VARIAVEIS!!!!');
print('Quem: ${instanceAnnotation.quem}');
print('O Que: ${instanceAnnotation.oque}');
}
});
} else if(declarationMirror is MethodMirror){
declarationMirror.metadata.forEach((annotation) {
var instanceAnnotation = annotation.reflectee;

if(instanceAnnotation is Fazer){
print('METODOS!!!!');
print('Quem: ${instanceAnnotation.quem}');
print('O Que: ${instanceAnnotation.oque}');
}
});
}
});
}

fazer.dart

class Fazer{
final String quem;
final String oque;

// Para fazer uma notacao o construtor tem que ser const


const Fazer({
required this.quem,
required this.oque
});

pessoa.dart

import 'package:dart_poo/20_metadatas/fazer.dart';

// quando isso é utilizado


// quando utilizamos package de terceiros, ou quando fazemos package para
geradores de codigos ler essas anotaoes
@Fazer(quem: 'Alex Sander na class', oque: 'tentando ler a anotacao da
classe')
class Pessoa {

@Fazer(quem: 'Alex Sander no atributo', oque: 'tentando ler a anotacao


do atributo')
String? nome;

@Fazer(quem: 'Alex Sander no método', oque: 'tentando ler a anotacao do


método')
void fazerAlgo(){

}
}

Getters Setters
void main() {
var pessoa = Pessoa();
print(pessoa.nome);
pessoa.nome = 'Rodrigo Rahman';
}

//! uso de get e set só usar quando tiver regra de negocio como o exemplo
abaixo
class Pessoa {
String? _nome;

String? get nome => _nome;


set nome(String? nome){
if(nome != null && nome.length > 3) {
_nome = nome;
}
}
}

Construtor tear off


void main() {

final nomes=['Rodrigo', 'Guilherme', 'Renato', 'Sandra'];

// antes do flutter 2.15


final pessoasDartAntesDa215 = nomes.map((nome) =>
Pessoa(nome).toString());
// depois do flutter 2.15
// usando construtor nomeado
final pessoas = nomes.map<Pessoa>(Pessoa.nome).toList();

// usando construtor Default


final pessoasConstrutorDefault =
nomes.map<Pessoa>(Pessoa.new).toList();

for(var pessoa in pessoas) {


print('Olá ${pessoa.nome}');
}
}

class Pessoa {
String nome;

Pessoa(this.nome);
Pessoa.nome(this.nome);
}

Tipos genéricos
void main() {
final caixa = Caixa<Bola>();
caixa.adicionar(Bola());
Bola? itemCaixa = caixa.getItem();

final caixaBoneca = Caixa<Boneca>();


caixaBoneca.adicionar(Boneca());
Boneca? itemBoneca = caixaBoneca.getItem();
}

//! deixar a class generica


// Utilizado muito em estrutura de CORE
class Caixa<I extends Item> {
I? _item;

void adicionar(I item){


_item = item;
}

I? getItem() {
return _item;
}

double alturaItem() {
return _item?.altura() ?? 0;
}
}

abstract class Item {


double altura();
}

class Bola extends Item{


@override
double altura() {
return 20.0;
}
}

class Boneca extends Item{


@override
double altura() {
return 60.0;
}
}

Part of
import 'cpf.dart';

//! sempre ficar após o import


part 'endereco.dart';

// Utilizando part tenho como juntar mais de uma class em um mesmo


arquivo
// arquivo principal
class Pessoa {
String? nome;

_Endereco endereco = _Endereco();


Cpf cpf = Cpf();
}

endereco.dart

part of 'pessoa.dart';

//! se precisar de importar algo tem que ser pela class principal
class _Endereco {}
cpf.dart

class Cpf {

Conversões
import 'aluno.dart';

void main() {

var frutas = [
Fruta('Banana'),
Fruta('Abacaxi'),
Fruta('Laranja')
];

var frutasMap = [
{'nome': 'B anana'},
{'nome': 'Abacaxi'},
{'nome': 'Laranja'}
];

var sucos = frutas.map((fruta) {


return Suco(sabor: fruta.nome);
}).toList();

var sucos2 = frutasMap.map((frutasMap) => Suco(sabor: frutasMap['nome']


?? 'Sem Sabor'));

print(sucos);
print(sucos2);

var alunosAdf = <String, Object> {


'nome': 'Rodrigo Rahman',
'cursos': [
{
'nome': 'Academia do flutter',
'descricao': 'Melhor curso de flutter do Brasil!!!'
},
{
'nome': 'Imersao GetX',
'descricao': 'Imersão em GetX'
}
]
};
final cursosMap = alunosAdf['cursos'] as List<Map<String, String>>;
final cursos = cursosMap.map((curso) {
var nome = curso['nome'] as String;
var descricao = curso['descricao'] as String;

return Curso(nome: nome, descricao: descricao);


}).toList();

final nomeAluno = alunosAdf['nome'].toString();

final aluno = Aluno(nome: nomeAluno, cursos: cursos);


print(aluno);

class Suco {
String sabor;

Suco({
required this.sabor,
});

@override
String toString() {
return 'Suco{sabor=$sabor}';
}
}

class Fruta {
String nome;

Fruta(this.nome);

aluno.dart

class Aluno {
String nome;
List<Curso> cursos;

Aluno({
required this.nome,
required this.cursos,
});
@override
String toString() => 'Aluno(nome: $nome, cursos: $cursos)';
}

class Curso {
String nome;
String descricao;

Curso({
required this.nome,
required this.descricao,
});

@override
String toString() => 'Curso(nome: $nome, descricao: $descricao)';
}

Você também pode gostar