Clases
## Objetivos de Aprendizaje
- Crear y usar clases
- Comprender la herencia
- Dominar los modificadores de acceso
- Trabajar con clases abstractas
- Usar miembros estaticos y constructores
## Basicos de Clases
### Declaracion
```typescript
class Person {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
greet(): string {
return `Hola, soy ${this.name}`;
}
}
let person = new Person("Alice", 30);
person.greet(); // "Hola, soy Alice"
```
### Miembros de Instancia
```typescript
class Rectangle {
width: number;
height: number;
constructor(width: number, height: number) {
this.width = width;
this.height = height;
}
area(): number {
return this.width * this.height;
}
}
let rect = new Rectangle(10, 5);
rect.area(); // 50
```
## Modificadores de Acceso
### public
Accesible en todas partes (por defecto):
```typescript
class Person {
public name: string;
constructor(name: string) {
this.name = name;
}
}
let person = new Person("Bob");
console.log(person.name); // "Bob"
```
### private
Accesible solo dentro de la clase:
```typescript
class BankAccount {
private balance: number;
constructor(initialBalance: number) {
this.balance = initialBalance;
}
deposit(amount: number): void {
this.balance += amount;
}
getBalance(): number {
return this.balance;
}
}
let account = new BankAccount(100);
// account.balance; // Error: 'balance' es privado
account.getBalance(); // 100
```
### protected
Accesible dentro de la clase y subclases:
```typescript
class Animal {
protected name: string;
constructor(name: string) {
this.name = name;
}
}
class Dog extends Animal {
bark(): void {
console.log(`${this.name} dice guau!`);
}
}
let dog = new Dog("Buddy");
dog.bark(); // "Buddy dice guau!"
// dog.name; // Error: 'name' es protegido
```
### readonly
No puede ser modificado despues de la inicializacion:
```typescript
class Config {
readonly apiUrl: string;
readonly port: number = 8080;
constructor(apiUrl: string) {
this.apiUrl = apiUrl;
// this.port = 3000; // Error: No se puede asignar a 'port'
}
}
let config = new Config("https://api.example.com");
// config.apiUrl = "https://other.com"; // Error
```
## Propiedades de Parametro
Abreviado en el constructor:
```typescript
class Person {
constructor(
public name: string,
private age: number,
protected email: string
) {}
}
let person = new Person("Alice", 30, "alice@example.com");
console.log(person.name); // "Alice"
// person.age; // Error: privado
// person.email; // Error: protegido
```
## Herencia
### extends
```typescript
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
speak(): void {
console.log(`${this.name} hace un sonido`);
}
}
class Dog extends Animal {
breed: string;
constructor(name: string, breed: string) {
super(name); // Llama al constructor padre
this.breed = breed;
}
speak(): void {
console.log(`${this.name} ladra`);
}
}
let dog = new Dog("Buddy", "Labrador");
dog.speak(); // "Buddy ladra"
```
### Sobreescritura de Metodos
```typescript
class Cat extends Animal {
speak(): void {
console.log(`${this.name} maulla`);
}
}
let cat = new Cat("Whiskers");
cat.speak(); // "Whiskers maulla"
```
## Palabra Clave super
Acceder a miembros de la clase padre:
```typescript
class Animal {
constructor(public name: string) {}
speak(): void {
console.log(`${this.name} hace un sonido`);
}
}
class Dog extends Animal {
constructor(name: string, public breed: string) {
super(name);
}
speak(): void {
super.speak(); // Llama al metodo padre
console.log(`${this.name} ladra fuerte`);
}
}
```
## Clases Abstractas
### No Pueden Ser Instanciadas
```typescript
abstract class Shape {
abstract area(): number; // Debe ser implementado
display(): void {
console.log(`Area: ${this.area()}`);
}
}
// let shape = new Shape(); // Error: No se puede instanciar
```
### Subclase Concreta
```typescript
class Circle extends Shape {
constructor(public radius: number) {
super();
}
area(): number {
return Math.PI * this.radius ** 2;
}
}
class Rectangle extends Shape {
constructor(public width: number, public height: number) {
super();
}
area(): number {
return this.width * this.height;
}
}
let shapes: Shape[] = [new Circle(5), new Rectangle(4, 6)];
shapes.forEach(s => s.display());
```
## Miembros Estaticos
Compartidos entre todas las instancias:
```typescript
class MathUtil {
static PI: number = 3.14159;
static circleArea(radius: number): number {
return this.PI * radius ** 2;
}
static add(a: number, b: number): number {
return a + b;
}
}
console.log(MathUtil.PI); // 3.14159
MathUtil.circleArea(5); // 78.54
MathUtil.add(2, 3); // 5
```
## Getters y Setters
Acceso controlado a propiedades:
```typescript
class User {
private _name: string = "";
get name(): string {
return this._name;
}
set name(value: string) {
if (value.length > 0) {
this._name = value;
}
}
}
let user = new User();
user.name = "Alice"; // Usa setter
console.log(user.name); // "Alice" - usa getter
```
## Clase como Tipo
Tipo de instancia:
```typescript
class Point {
x: number;
y: number;
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
}
let p: Point = new Point(10, 20);
// let p2: Point = { x: 10, y: 20 }; // Error: debe ser instancia
```
## Implementacion de Interface
```typescript
interface Drawable {
draw(): void;
}
interface Colorable {
color: string;
}
class Circle implements Drawable, Colorable {
constructor(public radius: number, public color: string) {}
draw(): void {
console.log(`Dibujando circulo ${this.color}`);
}
}
```
## Sobrecargas de Constructor
Multiples firmas de constructor:
```typescript
class Person {
name: string;
age: number;
email?: string;
constructor(name: string, age: number);
constructor(name: string, age: number, email: string);
constructor(name: string, age: number, email?: string) {
this.name = name;
this.age = age;
this.email = email;
}
}
let p1 = new Person("Alice", 30);
let p2 = new Person("Bob", 25, "bob@example.com");
```
## Inicializacion de Propiedades
### Con strictPropertyInitialization
```typescript
class User {
name: string = "";
email: string = "";
}
// O usar asignacion definitiva
class User2 {
name!: string;
}
```
## instanceof
Verificar clase en tiempo de ejecucion:
```typescript
class Dog {
bark(): void {
console.log("Guau!");
}
}
class Cat {
meow(): void {
console.log("Miau!");
}
}
function speak(animal: Dog | Cat): void {
if (animal instanceof Dog) {
animal.bark();
} else {
animal.meow();
}
}
```
## Resumen
- Las clases definen objetos con propiedades y metodos
- `public`: accesible en todas partes
- `private`: solo la clase
- `protected`: clase y subclases
- `readonly`: establecido una vez, nunca cambiado
- `extends` para herencia
- `super()` para llamar al constructor padre
- Las clases `abstract` no pueden ser instanciadas
- Los miembros `static` son compartidos entre instancias
- Getters/setters controlan el acceso a propiedades
Comments
Comments powered by Giscus
To enable comments, add your Giscus embed code here.
Learn more about Giscus →