Classes and Objects in TypeScript
Classes in TypeScript are blueprints for creating objects. They encapsulate data and behavior.
Defining a Class
A class is defined using the class
keyword. It can have properties, methods, and a constructor.
class Dog {
name: string;
breed: string;
constructor(name: string, breed: string) {
this.name = name;
this.breed = breed;
}
bark(): void {
console.log("Woof!");
}
}
const myDog = new Dog("Buddy", "Golden Retriever");
myDog.bark(); // Output: Woof!
Access Modifiers
TypeScript provides access modifiers like public
, private
, and protected
to control access to class members.
class Animal {
public name: string;
private age: number;
protected sound: string;
constructor(name: string, age: number, sound: string) {
this.name = name;
this.age = age;
this.sound = sound;
}
makeSound(): void {
console.log(this.sound);
}
}
const myAnimal = new Animal("Buddy", 5, "Woof");
console.log(myAnimal.name); // Accessible
// console.log(myAnimal.age); // Error: Private member
myAnimal.makeSound(); // Output: Woof
Static Members
Static members belong to the class itself rather than instances of the class.
class MathOperations {
static PI: number = 3.14;
static add(a: number, b: number): number {
return a + b;
}
}
console.log(MathOperations.PI); // Output: 3.14
console.log(MathOperations.add(5, 10)); // Output: 15
Inheritance
TypeScript supports inheritance using the extends
keyword.
class Animal {
speak(): void {
console.log("Animal sound");
}
}
class Cat extends Animal {
speak(): void {
console.log("Meow");
}
}
const myCat = new Cat();
myCat.speak(); // Output: Meow
Abstract Classes
Abstract classes cannot be instantiated directly and are meant to be subclassed.
abstract class Shape {
abstract area(): number;
}
class Circle extends Shape {
radius: number;
constructor(radius: number) {
super();
this.radius = radius;
}
area(): number {
return Math.PI * this.radius * this.radius;
}
}
const myCircle = new Circle(5);
console.log(myCircle.area()); // Output: 78.54
Interfaces
Interfaces define the structure of an object and can be implemented by classes.
interface Animal {
name: string;
speak(): void;
}
class Dog implements Animal {
name: string;
constructor(name: string) {
this.name = name;
}
speak(): void {
console.log("Woof!");
}
}
const myDog = new Dog("Buddy");
myDog.speak(); // Output: Woof!
Best Practices
- Use Access Modifiers: Control access to class members using
public
,private
, andprotected
. - Leverage Static Members: Use static members for properties and methods that belong to the class itself.
- Prefer Composition Over Inheritance: Favor composition over inheritance to avoid tight coupling.
- Use Abstract Classes for Shared Behavior: Abstract classes are useful for defining shared behavior across subclasses.
- Implement Interfaces for Flexibility: Interfaces allow you to define contracts that classes can implement.