Bueno aunque parezca cliché como todos ponen sus comentarios mi resúmen es:
asbtract: cuando requeires que una clase no sea instanciada
protected: atributo de los miembros para que puedan ser accedidos desde su propia clase y también que puedan ser solo accedidos a quienes heredan esa clase con implements(herencia)
implements: herencia claseA extends claseB { ... }
static: para poder acceder a métodos/propiedades de una clase sin la necesidad de la instancia(new ClaseA()) sino const a = ClaseA.propiedad
En qué momento utilizó implements? implements no se debería utilzar para implementar interfaces, mas no clases?
Compañero tu definición de implements es incorrecta, a lo que te refieres es a la herencia con extends
Nota: Por convención los nombres de las clases siempre deben ir con inicial mayúscula.
Correcto y seguir la convención UpperCamelCase
Seria lo ideal pero ni los mismos que diseñan las librerías en JS a veces hacen caso de esto 😒, vengo de Java
Herencia de clases y miembros protegidos
Typescript soporta este patrón común en el mundo de la POO
Implementa la habilidad de extender codigo de clases existentes a través de la herencia.
Utilizamos la palabra extends para heredar
Se heredan solo los atributos public o protected
tenemos acceso al constructor de la clase padre super()
classPerson{protectedid:number;protectedname:string;constructor(id:number,name:string){}}classStudentextendsPerson{privateactive:boolean
constructor(id:number,name:string,active:boolean){super(id,name)this.active= active
}}
Clases abstractas: Las clases abstractas son la base de donde otras clases podrian derivarse. A diferencia de una interfaz, una clase abstracta puede implementar funciones para sus instancias.
La palabra reservada es abstract
abstract classmyClass{}
++Recordar que las clases abstractas no se pueden instanciar++
Propiedades estaticas y de solo lectura
Las clases por lo general definen atributos y métodos aplicables a las instancias de las mismas. A través de la palabra reservada **static ** se puede definir un miembro visible a nivel de clase
Al igual que las interfaces, podemos usar la palabra reservada readonly para marcar el miembro de una clase como solo lectura
classPerson{staticpersonQuantity: number =0protected readonly id: number
}
a las propiedades static se las accede a través de la clase
console.log(Person.personQuantity)
a las propiedades readonly no se las puede modificar
Abstract, protected, extends, static, readonly
Abstract = cuando requieres que una clase no sea instanciada
Protected = Entre público y privado, para que los elementos puedan ser accedidos por la clase y subclases
Extends = herencia de SUPER clase a subclases, para invocar al constructor de la SUPERclase en las subclases usar super(propiedades)
Static = Puede acceder a métodos y propiedades de una clase sin instanciarla
Readonly = Indica propiedades que solo se pueden leer
Gran resumen !
y cuando es un método abstract?
JavaScript en su definición tan dinámica, sin tipado, tan milenial y viene Microsoft con TypeScript y le pone orden a todo ese relajo......
Hasta ahora que ya se como se usan las clases abstractas
Se deben utilizar cuando no queremos que se creen instancias de esta clase debido a que son demasiado generales.
Excelente explicación.
Esta clase bien podría estar en un curso de OOP, impresionante clase, explicada de manera sólida, sencilla y con código.
ahora ya hay 2 cursos de poo en javascript
Tienes toda la razón, tenía un poco de enredos en mi cabeza con este tema de la herencia y en una sola clase lo entendí.
export{};enumPhotoOrientation{Landscape,Portrait,Square,Panorama}// SUPERclaseabstract classItem{protected readonly _id: number;protected_title: string;constructor(id: number,title: string){this._id= id;this._title= title;}getid(){returnthis._id;}// set id(id: number) {// this._id = id;// }gettitle(){returnthis._title;}settitle(title: string){this._title= title;}}// get y setclassPictureextendsItem{publicstatic photoOrientation =PhotoOrientation;// Propiedadesprivate_orientation:PhotoOrientation;publicconstructor(id: number,title: string,orientation:PhotoOrientation){super(id, title);this.orientation= orientation;}getorientation(){returnthis._orientation;}setorientation(o:PhotoOrientation){this._orientation= o;}// ComportamientopublictoString(){return`[id: ${this.id},
title: ${this.title},
orientation: ${this.orientation}]`;}}classAlbumextendsItem{privatepictures:Picture[];publicconstructor(id: number,title: string){super(id, title);// constructor de SUPER clasethis.pictures=[];}publicaddPicture(picture:Picture){this.pictures.push(picture);}}constalbum:Album=newAlbum(1,'Personal Pictures');constpicture:Picture=newPicture(1,'Platzi session',PhotoOrientation.Square);album.addPicture(picture);console.log('album', album);// Accediendo a los miembros publicosconsole.log('picture.id', picture.id);// get id()// picture.id = 100; // private, set id(100);picture.title='Another title';// privatealbum.title='Personal Activities';//privateconsole.log('album', album);// const item = new Item(1, 'Test title');// console.log('item', item);// Probar el miembro estaticoconsole.log('PhotoOrientation',Picture.photoOrientation.Landscape);
Como saber cuando usar Interfaces y cuando usar Clase???
Utiliza interfaces siempre. Cuando la complejidad de lo que estás haciendo te requiera usar modelos con clases entonces sí, usa clases 🔥
No nos vayamos a los extremos... Las interfaces se crearon para alojar la shape (forma) de objetos puntuales; decir que siempre se deben utilizar interfaces es como decir que siempre se deben utilizar objetos literales.
Las clases no son propias de TypeScript, son propias de JavaScript, e incluso, por su funcionamiento "under the hood" (por detrás), pueden optimizar el uso de memoria y rendimiento.
Las interfaces se deben utilizar siempre como la forma de "tipar" un objeto en TypeScript, nunca llegarán a reemplazar una clase (ni sencilla ni compleja). Incluso, una instancia de una clase se puede tipar a través de una interface.
Siempre que vayas a hacer Programación orientada a objetos, y tengas varios "moldes" (clases) de los cuales se vayan a instanciar constantemente objetos, usa Clases, tanto en TypeScript como en JavaScript.
la verdad si le da un plus en POO a JS
Totalmente, hace muy práctico.
Super Clases:
Al igual que las interfaces, las clases también pueden heredar atributos y propiedades.
|-> Implementa la habilidad de extender código de clases existentes a través de la herencia
Modificador de acceso protected que permite un acceso ni público ni privado. Dan acceso a los miembros cuando las subclases requieran usarlos.
super(): Sirve para invocar al constructor de una SUPERCLASE. Un objeto que instancie la (super)clase, va a tener inicializado las variables que dentro de la superclase fueron declaradas
Clases Abstractas:
Son la base de donde otras clases pueden derivarse. Implementa funciones para sus instancias . abstract es la palabra reservada
Se usan cuando una super clase llega a ser demasiado general y queremos evitar crear instacias a partir de la misma.
La palabra reservada static se usa para definir un miembro visible a nivel de clase.
Se usa la palabra reservada readonly para marcar un miembro de una clase como solo lectura.
export{}enumPhotoOrientation{Landscape,Portrait,Square,Panorama,};//superclaseabstract classItem{protected readonly _id: number;protected_title: string;constructor(id: number,title: string){this._id= id;this._title= title;}getid(){returnthis._id}// set id(id: number) {this._id = id} // La definición de _id es inservible.gettitle(){returnthis._title}settitle(t: string){this._title= t}}// clase pictureclassPictureextendsItem{publicstatic photoOrientation =PhotoOrientation;private_orientation:PhotoOrientation;publicconstructor(id: number,title: string,orientation:PhotoOrientation){super(id, title);this._orientation= orientation;}privatetoString(){return`[id: ${this._id}, title: ${this._title}, orientation: ${this._orientation}]`}}// clase albumclassAlbumextendsItem{private_pictures:Picture[];publicconstructor(id: number,title: string){super(id, title);this._pictures=[];}getpicture(){returnthis._pictures}setpicture(pic:Picture[]){this._pictures= pic}publicaddPicture(picture:Picture){this._pictures.push(picture);}}letalbum:Album=newAlbum(100,'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);// Primer estado del álbumconsole.log('album inicial-> ', album);//cambiar id de álbum ó fotos/* new2Pic.id = 300; Se hacen inútiles debido
new3Pic.id = 400; a la propiedad de readonly *///cambiar titulo de álbumalbum.title='Mi nuevo álbum de fotos !';//agregar más fotos a mi álbumalbum.addPicture(newPic);album.addPicture(new2Pic);album.addPicture(new3Pic);console.log('album modificado -> ', album);// const item = new Item(1, 'Test Title'); // Realmente no tiene sentido usar ésto,// console.log('item', item) // pues Item es muuy general.console.log('PhotoOrientation',PhotoOrientation);
Que bueno es venir de Java a TypeScript, eso si con los conceptos de POO bien claros :D
TypeScript soporta la herencia, con esto implementa la habilidad de extender código de clases existentes a otras.
Utilizamos la palabra extends para heredar, si heredamos sólo se heredan los atributos public o protected.
classPerson{protected id:number;protected name:string;constructor(id:number, name:string){}}classStudentextendsPerson{private active:booleanconstructor(id:number, name:string, active:boolean){super(id,name)this.active= active
}}
En las clases de TypeScript se tienen disponibles las clases abstractas, estas son la base de donde otras clases podrían derivarse. A diferencia de una interface, una clase abstracta puede implementar funciones para sus instancias.
abstractclassPerson{}
Me esta gustando mucho TS, me recuerda a cuando empecé con C# en la Universidad pero terminé odiandolo por la forma en que me lo enseñaban, TS me esta ayudando a darle un segundo oportunidad.
No entiendo porque elimina la linea 67, alguien me puede ayudar?. Gracias
Por que ya está heredado de la super clase Item
Debía eliminarla en la clase anterior, en la de los métodos get y set, pero se le pasó. Hasta ahora vio el error.
ésta clase me gustó más que todas hasta el momento
copie el codigo de esta clase y me da un error: ++Property '_orientation' has no initializer and is not definitely assigned in the constructor++ Saben que puede estar pasando?
export{};enumPhotoOrientation{Landscape,Portrait,Square,Panorama}// SUPERclaseabstract classItem{protected readonly _id: number;protected_title: string;constructor(id: number,title: string){this._id= id;this._title= title;}getid(){returnthis._id;}// set id(id: number) {// this._id = id;// }gettitle(){returnthis._title;}settitle(title: string){this._title= title;}}// get y setclassPictureextendsItem{publicstatic photoOrientation =PhotoOrientation;// Propiedadesprivate_orientation:PhotoOrientation;// ++ESTA LINEA MARCA ERROR++publicconstructor(id: number,title: string,orientation:PhotoOrientation){super(id, title);this.orientation= orientation;}getorientation(){returnthis._orientation;}setorientation(o:PhotoOrientation){this._orientation= o;}// ComportamientopublictoString(){return`[id: ${this.id},
title: ${this.title},
orientation: ${this.orientation}]`;}}classAlbumextendsItem{privatepictures:Picture[];publicconstructor(id: number,title: string){super(id, title);// constructor de SUPER clasethis.pictures=[];}publicaddPicture(picture:Picture){this.pictures.push(picture);}}constalbum:Album=newAlbum(1,'Personal Pictures');constpicture:Picture=newPicture(1,'Platzi session',PhotoOrientation.Square);album.addPicture(picture);console.log('album', album);// Accediendo a los miembros publicosconsole.log('picture.id', picture.id);// get id()// picture.id = 100; // private, set id(100);picture.title='Another title';// privatealbum.title='Personal Activities';//privateconsole.log('album', album);// const item = new Item(1, 'Test title');// console.log('item', item);// Probar el miembro estaticoconsole.log('PhotoOrientation',Picture.photoOrientation.Landscape);
Si los metodos get/set no van a hacer nada mas que asignar el valor, conviene mejor declararlos public? o que otra ventaja tiene ademas de hacer algo intermedio antes de asignar el valor?
Esa es la función como tal. Devolver el valor de tu variable. Es importante no permitir la modificación desde afuera, y que sólo a través de set y get puedas manipularla.
no me deja acceder a la propiedad static de la clase picture alguien sabe porque?