Classes
## Learning Objectives
- Create and use classes
- Understand inheritance
- Master access modifiers
- Work with abstract classes
- Use static members and constructors
## Class Basics
### Declaration
```typescript
class Person {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
greet(): string {
return `Hello, I'm ${this.name}`;
}
}
let person = new Person("Alice", 30);
person.greet(); // "Hello, I'm Alice"
```
### Instance Members
```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
```
## Access Modifiers
### public
Accessible everywhere (default):
```typescript
class Person {
public name: string;
constructor(name: string) {
this.name = name;
}
}
let person = new Person("Bob");
console.log(person.name); // "Bob"
```
### private
Accessible only within the class:
```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' is private
account.getBalance(); // 100
```
### protected
Accessible within class and subclasses:
```typescript
class Animal {
protected name: string;
constructor(name: string) {
this.name = name;
}
}
class Dog extends Animal {
bark(): void {
console.log(`${this.name} says woof!`);
}
}
let dog = new Dog("Buddy");
dog.bark(); // "Buddy says woof!"
// dog.name; // Error: 'name' is protected
```
### readonly
Cannot be modified after initialization:
```typescript
class Config {
readonly apiUrl: string;
readonly port: number = 8080;
constructor(apiUrl: string) {
this.apiUrl = apiUrl;
// this.port = 3000; // Error: Cannot assign to 'port'
}
}
let config = new Config("https://api.example.com");
// config.apiUrl = "https://other.com"; // Error
```
## Parameter Properties
Shorthand in 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: private
// person.email; // Error: protected
```
## Inheritance
### extends
```typescript
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
speak(): void {
console.log(`${this.name} makes a sound`);
}
}
class Dog extends Animal {
breed: string;
constructor(name: string, breed: string) {
super(name); // Call parent constructor
this.breed = breed;
}
speak(): void {
console.log(`${this.name} barks`);
}
}
let dog = new Dog("Buddy", "Labrador");
dog.speak(); // "Buddy barks"
```
### Method Overriding
```typescript
class Cat extends Animal {
speak(): void {
console.log(`${this.name} meows`);
}
}
let cat = new Cat("Whiskers");
cat.speak(); // "Whiskers meows"
```
## super Keyword
Access parent class members:
```typescript
class Animal {
constructor(public name: string) {}
speak(): void {
console.log(`${this.name} makes a sound`);
}
}
class Dog extends Animal {
constructor(name: string, public breed: string) {
super(name);
}
speak(): void {
super.speak(); // Call parent method
console.log(`${this.name} barks loudly`);
}
}
```
## Abstract Classes
### Cannot Be Instantiated
```typescript
abstract class Shape {
abstract area(): number; // Must be implemented
display(): void {
console.log(`Area: ${this.area()}`);
}
}
// let shape = new Shape(); // Error: Cannot instantiate
```
### Concrete Subclass
```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());
```
## Static Members
Shared across all instances:
```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 and Setters
Controlled property access:
```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"; // Uses setter
console.log(user.name); // "Alice" - uses getter
```
## Class as Type
Instance type:
```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: must be instance
```
## Interface Implementation
```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(`Drawing ${this.color} circle`);
}
}
```
## Constructor Overloads
Multiple constructor signatures:
```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");
```
## Property Initialization
### With strictPropertyInitialization
```typescript
class User {
name: string = "";
email: string = "";
}
// Or use definite assignment
class User2 {
name!: string;
}
```
## instanceof
Check class at runtime:
```typescript
class Dog {
bark(): void {
console.log("Woof!");
}
}
class Cat {
meow(): void {
console.log("Meow!");
}
}
function speak(animal: Dog | Cat): void {
if (animal instanceof Dog) {
animal.bark();
} else {
animal.meow();
}
}
```
## Summary
- Classes define objects with properties and methods
- `public`: accessible everywhere
- `private`: class only
- `protected`: class and subclasses
- `readonly`: set once, never changed
- `extends` for inheritance
- `super()` to call parent constructor
- `abstract` classes cannot be instantiated
- `static` members shared across instances
- Getters/setters control property access
Comments
Comments powered by Giscus
To enable comments, add your Giscus embed code here.
Learn more about Giscus →