Podemos hacer console.log del objeto
También podemos hacer console.table de ese mismo objeto
Y como tenemos un array en el objeto, podemos hacer también console.table de ese array dentro del objeto.
el table es un trucazo
Para la clase de Album inicializa el arreglo pictures en el constructor .
Me surgió la pregunta de: ¿Cuál seria la diferencia entre inicializar una variable en el constructor...
... o inicializarla en la definición de la variable?
classAlbum{pictures:Picture[]=[]constructor(){}}
¿Sera alguna cuestión de rendimiento, funcionalidad o es por buena práctica?
A mi entender es un tema de gusto, porque por ejemplo: imagina que tienes dos constructores, seria mas efectivo inicializar la propiedad en la declaración en vez de hacerlo en ambos constructores.
Niguna. No hay diferencias. Hacen lo mismo al igual cuando estas creando variables normales.
letejemplo: number;number =2;
es lo mismo que
letejemplo:number =2;
MY NOTES FOR CLASES
Definiendo Clases y Constructores
A partir de ECMAScript 2015 es posible construir clases y hacer uso del paradigma de la Programación Orientada a Objetos en Javascript
Typescript permite aplicar estas técnicas sin tener que es esperar por otra versión.
export{}enumPhotoOrientation{Landscape,Portrait,Square,Panorama}classPicture{//Propiedades id:number; title:string; orientation:PhotoOrientation;constructor(id:number,title:string,orientation:PhotoOrientation){this.id= id;this.title= title;this.orientation= orientation;}//Comportamiento de nuestra clase que estara definido por funcionestoString(){return`[id ${this.id},
title: ${this.title},
orientation: ${this.orientation}]`;}}classAlbum{ id:number; title:string; pictures:Picture[];//Usamos el constructor el cual nos permitira crear objetos de esta claseconstructor(id:number, title:string){this.id= id;this.title= title;this.pictures=[];}addPicture(picture:Picture){this.pictures.push(picture);}}//Creamos un nuevo a partir de la instancia de la claseconst album:Album=newAlbum(1,'personal pictures');const picture:Picture=newPicture(1,'Platzi session',PhotoOrientation) album.addPicture(picture);console.log(album);
Excelentes notas ! muchas gracias.
Gracias por el aporte. nada más me fijé que te hizo falta agregar el tipo de PhotoOrientation en la const picture.
Las interfaces estan más orientadas en comportamientos, es decir, en métodos que pueden estar en más de una familia. Por ejemplo: Puedes tener las familias de clases Medicinas y Comida, en principio tienen atributos muy distintos, pero comparten el comportamiento de "ingerirse".
Las clases definen atributos y comportamientos que pueden heredarse a clases hijas, pero no a clases que esten en otras familias; las interfaces pueden heredarse o usarse independientemente de la familia de clases en la que se llame.
Espero que te pueda ayuda, suerte en tu aprendizaje :D
Una interfaz no define lo que hacen los métodos, solamente define la estructura que deben tener las clases que implementan dicha interfaz (es decir, define qué funciones debes de implementar obligatoriamente, pero no te especifica lo que deban hacer exactamente).
En cambio, si heredas una clase, entonces estás heredando también los comportamientos definidos en esas funciones. Es decir, si la clase que heredaste tiene algunas funciones con código definido, entonces estarás heredando también esos comportamientos con código definido.
Una interfaz te obliga a que definas esas funciones, pero el heredar una clase, no te obliga a que definas esos comportamientos, porque ya están heredados.
El ejemplo del profesor un llevado un poco más allá:
Las clases y a la POO, se puede conectar las diferentes entidades y se puede relacionar
Una clase es la asbtracción de un conjunto de objetos
ejemplo:
Para definir una entidad usuario, se hace uso de una clase: Se debe definir una clase que
dentro tenga una función que permita crear objetos a partir de esta Clase y poder interactuar con ellos.
export{}enumPhotoOrientation{Landscape,Portrait,Square,Panorama,};classPicture{// propertiesid: number;title: string;orientation:PhotoOrientation;//constructorconstructor(id: number,title: string,orientation:PhotoOrientation){this.id= id;this.title= title;this.orientation= orientation;}//PerformancetoString(){return`[id: ${this.id}, title: ${this.title}, orientation: ${this.orientation}]`}}classAlbum{id: string;title: string;pictures:Picture[];constructor(id: string,title: string){this.id= id;this.title= title;this.pictures=[];}addPicture(picture:Picture){this.pictures.push(picture);}}letalbum:Album=newAlbum('stories-1','Photos of mine');constnewPic:Picture=newPicture(2,'my new pic!',PhotoOrientation.Panorama);constnew2Pic:Picture=newPicture(3,'my 2nd new pic!',PhotoOrientation.Portrait);constnew3Pic:Picture=newPicture(4,'my 3rd new pic!',PhotoOrientation.Portrait);album.addPicture(newPic);album.addPicture(new2Pic);album.addPicture(new3Pic);console.log('album -> ', album);
muy buen resumen bro, gracias :D
Tipea las clases User, Album, Picture. La única diferencia con javascript es que usa tipos en los args.
Buena observación.
Tengo la siguiente duda. ¿Cuál es la diferencia que hay de declarar el objeto de la forma 1 a la forma 2?
Puedo omitir el tipo de dato ya que especifico que es un objeto instanciado de la clase Albúm?
Me encanta lo parecido que tiene a Java 😍
Demasiado pero más sencillo xD
tengo una pregunta referente al ejemplo del álbum. el profesor definió el tipo de type de las variables antes de la funcion. Es necesario definir el type en los parámetro () ya estando definido antes. no se debería haberse guardado la referencia antes.
No sé si han sido curiosos, pero nos estamos ahorrando mucho código en JS con el poder de TS, solamente comparen:
Código en TS:
export{}enumPhotoOrientation{Landscape,Portrait,Square,Panorama}classPicture{//* Propiedades id:number title:string orientation:PhotoOrientation//*Atributos que se consideran necesarios para construir objetosconstructor(id:number, title:string, orientation:PhotoOrientation){this.id= id
this.title= title
this.orientation= orientation
}//*ComportamientotoString(){return` [
id: ${this.id},
title: ${this.title},
orientation: ${this.orientation} ]
`}}classAlbum{ id:number title:string pictures:Picture[]constructor(id:number, title:string){this.id= id
this.title= title
this.pictures=[]//*Inicializamos el array vacío}addPicture(picture:Picture){this.pictures.push(picture)}}const album:Album=newAlbum(1,'Personal Pictures')const picture:Picture=newPicture(1,'Selfie',PhotoOrientation.Square)album.addPicture(picture)//console.table(album)//console.table(picture)//console.table({picture})console.log(album)//* Imprime el objetoconsole.table({album})//* Como manejamos un objeto, podemos usar console.tableconsole.table(album.pictures)//* Como tenemos un array dentro del objeto, también podemos usar console.table
Código en JS:
"use strict";Object.defineProperty(exports,"__esModule",{value:true});varPhotoOrientation;(function(PhotoOrientation){PhotoOrientation[PhotoOrientation["Landscape"]=0]="Landscape";PhotoOrientation[PhotoOrientation["Portrait"]=1]="Portrait";PhotoOrientation[PhotoOrientation["Square"]=2]="Square";PhotoOrientation[PhotoOrientation["Panorama"]=3]="Panorama";})(PhotoOrientation||(PhotoOrientation={}));classPicture{//*Atributos que se consideran necesarios para construir objetosconstructor(id, title, orientation){this.id= id;this.title= title;this.orientation= orientation;}//*ComportamientotoString(){return` [
id: ${this.id},
title: ${this.title},
orientation: ${this.orientation} ]
`;}}classAlbum{constructor(id, title){this.id= id;this.title= title;this.pictures=[];//*Inicializamos el array vacío}addPicture(picture){this.pictures.push(picture);}}const album =newAlbum(1,'Personal Pictures');const picture =newPicture(1,'Selfie',PhotoOrientation.Square);album.addPicture(picture);//console.table(album)//console.table(picture)//console.table({picture})console.log(album);//* Imprime el objetoconsole.table({ album });//* Como manejamos un objeto, podemos usar console.tableconsole.table(album.pictures);//* Como tenemos un array dentro del objeto, también podemos usar console.table
Me ha gustado la forma en que se dan las clases, primero teoría y luego un ejemplo sencillo.
Agregó un aporte de como utilizar el ejemplo de clases a partir de un caso diferente (Pedidos de Comida)
// CLASSES/* Las clases y en general la POO pueden ser usadas
a partir de ES5, así como todos sus conceptos.
*//**
* A partir de un ejemplo con una aplicacion de pedidos de comida
* existen varias entidades:
* Usuarios: Quies hacen los pedidos
* order_status: Enum con estado de los pedidos
* Pedidos: La conjuncion de los pedidos que se van a ordenar
* Comida: La comida que se esta pidiendo
*
* Usuario ---> Comida --> Orden --> Status
*/// tipo de dato enum para almacenar es estado de las ordenesenumOrderStatus{ not_attended =0, attended =1, ready =2, done =3}// CLASE DE FOOD PARA CREAR NUEVOS ALIMENTOSclassFood{id_food: number;food_name: string;price: number;description: string;constructor(id_food: number,food_name: string,price: number,description: string){this.id_food= id_food;this.food_name= food_name;this.price= price;this.description= description;}}// CLASE PARA GUARDAR LAS ORDENES DE LOS USUARIOSclassUserOrders{id_order: number;id_user:User;order_status:OrderStatus;food_order:Array<[Food]>=[];constructor(id_order: number,id_user:User,order_status:OrderStatus){this.id_order= id_order;this.id_user= id_user;this.order_status= order_status;}addNewFoodToOrder(food:Food){this.food_order.push([food]);}}//CLASE DE USER PARA MANEJAR A LOS USUARIOSclassUser{id_user: number;user_name: string;isPro: boolean;constructor(id_user: number,user_name: string,isPro: boolean){this.id_user= id_user;this.user_name= user_name;this.isPro= isPro;}getMyUser(){console.log(this.id_user,this.user_name,this.isPro);}}// CREAMOS NUESTRO USUARIO QUE CREARA LOS PEDIDOSconstmy_new_user:User=newUser(1,'Mike',true);console.table(my_new_user);// CREAMOS LOS PLATILLOS EXISTENTESconstplatillo_1:Food=newFood(1,'Tortas',20.00,'Tortas de un Ingrediente');console.table(platillo_1);constplatillo_2:Food=newFood(2,'Enchiladas',10.00,'Orden de 4 enchiladas.');console.table(platillo_2);// CREAMOS UNA NUEVA ORDEN DE COMIDAconstnueva_orden:UserOrders=newUserOrders(1, my_new_user,OrderStatus.not_attended)nueva_orden.addNewFoodToOrder(platillo_1);nueva_orden.addNewFoodToOrder(platillo_2);console.log(nueva_orden.food_order);
"Pero veámoslo de una manera práctica"... Me encanta aprender practicando
Pracmaticidad es lo tuyo !
Clases
Diferentes entidades que guardan relación en común. Abstracción de un conjunto de objetos. Propiedades & funciones. Para crear objetos con estas clases constructor(función), valores que recibo como parámetro y asignarlos a las propiedades this.propiedades.
El tipo de dato Album y Picture ¿de dónde salen?, ya que no vi que haya definido una interfaz.
A la manera que yo lo interpreto es que a las clases, en TypeScript, también se las pueden usar como interfaces. Corríjanme si estoy mal.
Gracias. :D