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