1+ // 1º Ejercicio
2+ /**
3+ * Hay varios tipo de clases y que se pueden utilizar en clases
4+ * Herencia (Clases Extendidas), Abstractas, Interfaces, etc...
5+ */
6+
7+ // Vamos a empezar por las clases más básicas hasta la más complicada:
8+ // class
9+ class Persona {
10+ // Un constructor se encarga de inicializar las propiedades de la clase cuando se crea el objeto.
11+ constructor ( private _nombre : string ,
12+ private _edad : number ,
13+ private _profesion : string )
14+ { } ;
15+ /**
16+ * En este caso estamos utilizando public pero hay más, lo normal no es utilizarlo ahora veremos porqué.
17+ * public => Es la que vamos a utilizar en el ejemplo y significa que podemos usarlas desde cualquier lugar
18+ * no suele ser lo normal.
19+ * private => Se puede acceder solo a sus propiedades desde su misma clase. Para solventar esto hacemos los
20+ * famosos métodos, si un atributo es privado se utiliza el '_' delante.
21+ * protected => Se puede acceder a sus propiedades desde su clase y desde otra que herede esa clase.
22+ */
23+
24+ // Los get se utilizan para pillar el valor de la propiedad
25+ get nombre ( ) : string {
26+ return this . _nombre ;
27+ }
28+
29+ //Los set se utilizan para establecer sus valores
30+ set nombre ( nombre : string ) {
31+ this . _nombre = nombre ;
32+ }
33+
34+ get edad ( ) : number {
35+ return this . _edad ;
36+ }
37+
38+ set edad ( edad : number ) {
39+ this . _edad = edad ;
40+ }
41+
42+ get profesion ( ) : string {
43+ return this . _profesion ;
44+ }
45+
46+ set profesion ( profesion : string ) {
47+ this . _profesion = profesion ;
48+ }
49+
50+ //Tambien podemos incluir métodos
51+ cumplirAnhos ( ) : number {
52+ this . edad = this . edad + 1 ;
53+ return this . edad ;
54+ }
55+
56+ cambiarProfesion ( profesion : string ) : string {
57+ this . profesion = profesion ;
58+ return this . profesion ;
59+ }
60+
61+ // Esta funión nos va a servir para mostrar la información de nuestra persona
62+ toString ( ) : string {
63+ return `Mi nombre es: ${ this . nombre } tengo ${ this . edad } Años, mi profesion es ser un/a ${ this . profesion } ` ;
64+ }
65+ }
66+
67+ //Vamos a crear a una persona
68+ let persona = new Persona ( 'Igledev' , 19 , 'Programador' ) ; // Le ponemos datos por defecto.
69+ console . log ( persona )
70+ /**
71+ * Si hacemos nos va a aparecer un objeto con nuestras propiedades pero podremos acceder a ellas porque
72+ * estan en 'private', si fuese 'public' no tendríamos problema. Para ello vamos a utilizar los conocidos
73+ * setters & getters
74+ */
75+
76+ //Una vez hechos los setter & getters podremos acceder a las propiedades
77+ // console.log(persona.nombre + ' ' + persona.edad + ' ' + persona.profesion); // Nos saldrá IgleDev 19 Profesión.
78+ //En vez de utilizar todo esto, lo hacemos llamando a una función
79+ console . log ( persona . toString ( ) ) ;
80+
81+ //Utilizamos los métodos que hemos puesto en la clase
82+ persona . cumplirAnhos ( ) ;
83+ persona . cambiarProfesion ( 'Desarrollador Web' ) ;
84+ console . log ( persona . toString ( ) ) ;
85+ // Nos saldrá que nuestra edad ahora es de 20 y que somos desarrolladores web
86+
87+ // Herencia (clases extendidas)
88+ /**
89+ * Que tenga la palabra reservada 'extends' hace referencia a que vamos a tener que utilar los
90+ * parametros establecedidos en la clase Padre (en nuestro caso la clase Persona)
91+ */
92+ class Hijo extends Persona {
93+ constructor ( nombre : string ,
94+ edad : number ,
95+ profesion : string ,
96+ private _escuela : string )
97+ { super ( nombre , edad , profesion ) } // El super se utiliza para avisar de que las propiedades que estén entre los () son de la clase Padre
98+
99+ //Hacemos lo setter & getters necesarios
100+ get escuela ( ) : string {
101+ return this . _escuela ;
102+ }
103+
104+ set escuela ( escuela : string ) {
105+ this . _escuela = escuela ;
106+ }
107+
108+ toString ( ) : string {
109+ return super . toString ( ) + ' y mi escuela es: ' + this . escuela ; //Si utilizamos super más un método va a heredar tambien el contenido del método padre
110+ }
111+ }
112+
113+ let hijo = new Hijo ( 'Arrian' , 14 , 'Estudiante' , 'Montecastelo' ) ;
114+ console . log ( hijo . toString ( ) ) ;
115+
116+ //Abstracta
117+ /**
118+ * Una clase abstracta se utiliza cuando sabemso que nuncan la vamos a utilizar pero
119+ * si sus propiedades y que estén en clases derivadas.
120+ *
121+ */
122+
123+ abstract class ProductoDatos {
124+ constructor ( private _nombre : string ,
125+ private _desc : string ,
126+ private _creado_en : Date ,
127+ private _creado_por : number )
128+ { } ;
129+
130+ getFullYear ( ) {
131+ return this . _creado_en . getFullYear ( ) ;
132+ }
133+
134+ getFullDesc ( ) {
135+ return this . _nombre + ' ' + this . _desc ;
136+ }
137+
138+ //Tambien puede contener métodos abstractos que obviamente solo se pueden utilizar en ella
139+ abstract guardar ( ) : void ; // No se utilizan {}.
140+ }
141+
142+ //Ahora es cuando vamos a entender mejor esto:
143+ class Producto extends ProductoDatos {
144+ constructor (
145+ nombre : string ,
146+ desc : string ,
147+ creado_en : Date ,
148+ creado_por : number ,
149+ public stock : number , )
150+ { super ( nombre , desc , creado_en , creado_por ) } ;
151+
152+ override guardar ( ) : void {
153+ console . log ( 'Se ha guardado' ) ;
154+ }
155+
156+ }
157+
158+ // let datos = new ProductoDatos(). Si hacemos esto nos va saltar un error, debido a que una clase abstracta NO se puede instanciar
159+
160+ let producto1 = new Producto ( 'iPhone' , 'Movil' , new Date ( ) , 1 , 100 ) ;
161+ producto1 . guardar ( ) ; // Podremos acceder a sus métodos!
162+
163+
164+ //Interfaces
165+ /**
166+ * Se utilizan cuando NO vamos a compartir lógica pero si necesitamos la implementación de métodos y propiedades.
167+ */
168+
169+ interface Animal {
170+ nombre : string ,
171+ caminar ( ) : string ;
172+ onomatopeya ( ) : string ;
173+ } // En una Interfaz se pueden declarar tanto propiedades como métodos.
174+
175+ class Gato implements Animal {
176+ nombre : string = 'Zelda' ;
177+
178+ caminar ( ) : string {
179+ return 'va caminando...' ;
180+ }
181+
182+ onomatopeya ( ) : string {
183+ return 'meow' ;
184+ }
185+ }
186+
187+ let gato1 = new Gato ( ) ;
188+ console . log ( `El nombre del gato es ${ gato1 . nombre } y ${ gato1 . caminar ( ) } mientras dice ${ gato1 . onomatopeya ( ) } ` ) ;
189+
190+ // Ejercicio Extra
191+ class Nodo < T > {
192+ dato : T | null ;
193+ siguiente : Nodo < T > | null ;
194+
195+ constructor ( dato : T ) {
196+ this . dato = dato ;
197+ this . siguiente = null ;
198+ }
199+ }
200+
201+ class Pila < T > {
202+ tope : Nodo < T > | null ;
203+
204+ constructor ( ) {
205+ this . tope = null ;
206+ }
207+
208+ isEmpty ( ) : boolean {
209+ return this . tope === null ;
210+ }
211+
212+ push ( dato : T ) : void {
213+ const nuevoNodo = new Nodo ( dato ) ;
214+ nuevoNodo . siguiente = this . tope ;
215+ this . tope = nuevoNodo ;
216+ }
217+
218+ pop ( ) : T | null {
219+ if ( this . isEmpty ( ) ) {
220+ return null ;
221+ }
222+
223+ const datoEliminado = this . tope ! . dato ;
224+ this . tope = this . tope ! . siguiente ;
225+
226+ return datoEliminado ;
227+ }
228+
229+ size ( ) : number {
230+ let contador = 0 ;
231+ let actual = this . tope ;
232+
233+ while ( actual !== null ) {
234+ contador ++ ;
235+ actual = actual . siguiente ;
236+ }
237+
238+ return contador ;
239+ }
240+
241+ print ( ) : void {
242+ let actual = this . tope ;
243+
244+ while ( actual !== null ) {
245+ console . log ( actual . dato ) ;
246+ actual = actual . siguiente ;
247+ }
248+ }
249+ }
250+
251+ class Cola < T > {
252+ frente : Nodo < T > | null ;
253+ fin : Nodo < T > | null ;
254+
255+ constructor ( ) {
256+ this . frente = null ;
257+ this . fin = null ;
258+ }
259+
260+ isEmpty ( ) : boolean {
261+ return this . frente === null ;
262+ }
263+
264+ enqueue ( dato : T ) : void {
265+ const nuevoNodo = new Nodo ( dato ) ;
266+
267+ if ( this . isEmpty ( ) ) {
268+ this . frente = nuevoNodo ;
269+ this . fin = nuevoNodo ;
270+ } else {
271+ this . fin ! . siguiente = nuevoNodo ;
272+ this . fin = nuevoNodo ;
273+ }
274+ }
275+
276+ dequeue ( ) : T | null {
277+ if ( this . isEmpty ( ) ) {
278+ return null ;
279+ }
280+
281+ const datoEliminado = this . frente ! . dato ;
282+
283+ if ( this . frente === this . fin ) {
284+ // Último elemento en la cola
285+ this . frente = null ;
286+ this . fin = null ;
287+ } else {
288+ this . frente = this . frente ! . siguiente ;
289+ }
290+
291+ return datoEliminado ;
292+ }
293+
294+ size ( ) : number {
295+ let contador = 0 ;
296+ let actual = this . frente ;
297+
298+ while ( actual !== null ) {
299+ contador ++ ;
300+ actual = actual . siguiente ;
301+ }
302+
303+ return contador ;
304+ }
305+
306+ print ( ) : void {
307+ let actual = this . frente ;
308+
309+ while ( actual !== null ) {
310+ console . log ( actual . dato ) ;
311+ actual = actual . siguiente ;
312+ }
313+ }
314+ }
315+
316+ // Ejemplo de uso:
317+
318+ let pila = new Pila < number > ( ) ;
319+ pila . push ( 1 ) ;
320+ pila . push ( 2 ) ;
321+ pila . push ( 3 ) ;
322+
323+ console . log ( 'Pila:' ) ;
324+ pila . print ( ) ;
325+ console . log ( 'Tamaño de la pila:' , pila . size ( ) ) ;
326+
327+ console . log ( 'Elemento eliminado de la pila:' , pila . pop ( ) ) ;
328+ console . log ( 'Pila después de eliminar un elemento:' ) ;
329+ pila . print ( ) ;
330+
331+ let cola = new Cola < string > ( ) ;
332+ cola . enqueue ( 'A' ) ;
333+ cola . enqueue ( 'B' ) ;
334+ cola . enqueue ( 'C' ) ;
335+
336+ console . log ( '\nCola:' ) ;
337+ cola . print ( ) ;
338+ console . log ( 'Tamaño de la cola:' , cola . size ( ) ) ;
339+
340+ console . log ( 'Elemento eliminado de la cola:' , cola . dequeue ( ) ) ;
341+ console . log ( 'Cola después de eliminar un elemento:' ) ;
342+ cola . print ( ) ;
0 commit comments