1 OOP CheatSheet
1.1 Concepts
1.1.1 Common Properties in a Class
Instance Properties (unique to each object):
- Data attributes: Store object state
- Private attributes: Internal state (often prefixed with
_or__) - Computed/derived attributes: Calculated from other properties
Class Properties (shared across all instances):
- Class variables: Shared data among all instances
- Constants: Immutable values
- Static properties: Class-level data
1.1.2 Common Methods in a Class
Core Methods:
- Constructor (
__init__): Initializes new instances - Destructor (
__del__): Cleanup when object is destroyed - String representation (
__str__,__repr__): Human-readable representation
Access Methods:
- Getters: Retrieve property values
- Setters: Modify property values
- Properties: Pythonic way to access attributes
Behavioral Methods:
- Instance methods: Operate on instance data
- Class methods: Operate on class-level data
- Static methods: Utility functions without instance/class access
Special Methods (dunder/magic methods):
- Comparison (
__eq__,__lt__, etc.) - Arithmetic (
__add__,__sub__, etc.) - Container (
__len__,__getitem__, etc.)
1.2 Python
class BankAccount:
# Class variables
bank_name = "SimpleBank"
total_accounts = 0
minimum_balance = 100
def __init__(self, account_holder, initial_balance=0):
# Instance properties
self.account_holder = account_holder
self._balance = initial_balance # Protected attribute
self.__pin = None # Private attribute
self.transaction_history = []
self.account_number = self._generate_account_number()
# Update class variable
BankAccount.total_accounts += 1
# Destructor
def __del__(self):
BankAccount.total_accounts -= 1
# String representations
def __str__(self):
return f"Account({self.account_holder}, Balance: ${self._balance})"
def __repr__(self):
return f"BankAccount('{self.account_holder}', {self._balance})"
# Getter method
def get_balance(self):
return self._balance
# Setter method
def set_pin(self, pin):
if len(str(pin)) == 4:
self.__pin = pin
else:
raise ValueError("PIN must be 4 digits")
# Property decorator (Pythonic getter/setter)
@property
def balance(self):
return self._balance
@balance.setter
def balance(self, amount):
if amount >= 0:
self._balance = amount
else:
raise ValueError("Balance cannot be negative")
# Instance methods
def deposit(self, amount):
if amount > 0:
self._balance += amount
self._record_transaction("deposit", amount)
return True
return False
def withdraw(self, amount):
if 0 < amount <= self._balance - BankAccount.minimum_balance:
self._balance -= amount
self._record_transaction("withdrawal", amount)
return True
return False
# Protected method
def _record_transaction(self, transaction_type, amount):
from datetime import datetime
self.transaction_history.append({
'type': transaction_type,
'amount': amount,
'timestamp': datetime.now(),
'balance_after': self._balance
})
# Private method
def _generate_account_number(self):
import random
return f"ACC{random.randint(100000, 999999)}"
# Class method
@classmethod
def get_total_accounts(cls):
return cls.total_accounts
@classmethod
def from_csv_row(cls, csv_row):
# Alternative constructor
name, balance = csv_row.split(',')
return cls(name, float(balance))
# Static method
@staticmethod
def calculate_interest(principal, rate, years):
# Utility function - doesn't need instance or class
return principal * rate * years
# Comparison magic methods
def __eq__(self, other):
if isinstance(other, BankAccount):
return self._balance == other._balance
return False
def __lt__(self, other):
if isinstance(other, BankAccount):
return self._balance < other._balance
return NotImplemented
# Arithmetic magic methods
def __add__(self, amount):
# Allow account + number syntax
new_account = BankAccount(self.account_holder, self._balance + amount)
return new_account
# Container magic methods
def __len__(self):
# Return number of transactions
return len(self.transaction_history)
def __getitem__(self, index):
# Allow indexing to get transaction
return self.transaction_history[index]
# Context manager methods
def __enter__(self):
print(f"Starting transaction for {self.account_holder}")
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print(f"Transaction completed. Current balance: ${self._balance}")
return False
# Usage examples
if __name__ == "__main__":
# Create instances
acc1 = BankAccount("Alice", 1000)
acc2 = BankAccount.from_csv_row("Bob,2000")
# Use properties
print(acc1.balance) # Getter via property
acc1.balance = 1500 # Setter via property
# Use methods
acc1.deposit(500)
acc1.withdraw(200)
# Class method
print(f"Total accounts: {BankAccount.get_total_accounts()}")
# Static method
interest = BankAccount.calculate_interest(1000, 0.05, 2)
# Magic methods
print(acc1) # Uses __str__
print(acc1 == acc2) # Uses __eq__
acc3 = acc1 + 500 # Uses __add__
print(len(acc1)) # Uses __len__
# Context manager
with acc1 as account:
account.deposit(100)1.3 Dart
Here’s a comprehensive Dart OOP CheatSheet using the BankAccount example:
// DART OOP CHEATSHEET - BankAccount Example
import 'dart:math';
/// A comprehensive BankAccount class demonstrating Dart OOP concepts
class BankAccount implements Comparable<BankAccount> {
// ===== CLASS VARIABLES (static) =====
static const String bankName = "SimpleBank"; // Compile-time constant
static final int minimumBalance = 100; // Runtime constant
static int _totalAccounts = 0; // Private static variable
// ===== INSTANCE VARIABLES =====
// Public variables
String accountHolder;
List<Map<String, dynamic>> transactionHistory = [];
// Private variables (underscore prefix)
double _balance;
String? _pin; // Nullable type
// Late variables (initialized later)
late final String accountNumber; // Can only be set once
late DateTime createdAt; // Must be initialized before use
// ===== CONSTRUCTORS =====
// Main constructor
BankAccount(this.accountHolder, [this._balance = 0]) {
accountNumber = _generateAccountNumber();
createdAt = DateTime.now();
_totalAccounts++;
}
// Named constructor
BankAccount.vip(this.accountHolder) : _balance = 10000 {
accountNumber = 'VIP${Random().nextInt(9999)}';
createdAt = DateTime.now();
_totalAccounts++;
}
// Factory constructor
factory BankAccount.fromJson(Map<String, dynamic> json) {
return BankAccount(
json['accountHolder'] as String,
json['balance'] as double,
);
}
// Redirecting constructor
BankAccount.empty(String holder) : this(holder, 0);
// ===== GETTERS AND SETTERS =====
// Getter
double get balance => _balance;
// Setter with validation
set balance(double amount) {
if (amount >= 0) {
_balance = amount;
} else {
throw ArgumentError('Balance cannot be negative');
}
}
// Computed property (getter only)
bool get isVip => _balance > 50000;
// Expression-bodied getter
String get accountInfo => '$accountHolder: \$$_balance';
// ===== INSTANCE METHODS =====
// Regular instance method
bool deposit(double amount) {
if (amount > 0) {
_balance += amount;
_recordTransaction('deposit', amount);
return true;
}
return false;
}
// Method with optional positional parameter
bool withdraw(double amount, [String? description]) {
if (amount > 0 && amount <= _balance - minimumBalance) {
_balance -= amount;
_recordTransaction('withdrawal', amount, description: description);
return true;
}
return false;
}
// Method with named parameters
void transfer({
required BankAccount recipient,
required double amount,
String? reference,
}) {
if (withdraw(amount)) {
recipient.deposit(amount);
_recordTransaction('transfer', amount,
description: 'To: ${recipient.accountHolder}');
}
}
// Private method
void _recordTransaction(String type, double amount, {String? description}) {
transactionHistory.add({
'type': type,
'amount': amount,
'description': description,
'timestamp': DateTime.now(),
'balanceAfter': _balance,
});
}
// Private method returning value
String _generateAccountNumber() {
return 'ACC${Random().nextInt(999999).toString().padLeft(6, '0')}';
}
// ===== STATIC METHODS =====
// Static getter
static int get totalAccounts => _totalAccounts;
// Static method
static double calculateInterest(double principal, double rate, int years) {
return principal * rate * years;
}
// Static factory method
static BankAccount createBusinessAccount(String businessName) {
var account = BankAccount(businessName, 5000);
account._recordTransaction('initial_deposit', 5000);
return account;
}
// ===== OPERATOR OVERLOADING =====
// Arithmetic operators
BankAccount operator +(double amount) {
return BankAccount(accountHolder, _balance + amount);
}
BankAccount operator -(double amount) {
return BankAccount(accountHolder, _balance - amount);
}
// Comparison operators
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
return other is BankAccount &&
other.accountNumber == accountNumber;
}
bool operator <(BankAccount other) => _balance < other._balance;
bool operator >(BankAccount other) => _balance > other._balance;
bool operator <=(BankAccount other) => _balance <= other._balance;
bool operator >=(BankAccount other) => _balance >= other._balance;
// Index operators
Map<String, dynamic>? operator [](int index) {
if (index >= 0 && index < transactionHistory.length) {
return transactionHistory[index];
}
return null;
}
void operator []=(int index, Map<String, dynamic> transaction) {
if (index >= 0 && index < transactionHistory.length) {
transactionHistory[index] = transaction;
}
}
// ===== SPECIAL METHODS =====
@override
String toString() => 'BankAccount($accountHolder, Balance: \$$_balance)';
@override
int get hashCode => accountNumber.hashCode;
// From Comparable interface
@override
int compareTo(BankAccount other) {
return _balance.compareTo(other._balance);
}
// Call method (makes instance callable)
double call() => _balance;
// ===== ASYNC METHODS =====
// Async method
Future<bool> processTransaction(double amount) async {
// Simulate network delay
await Future.delayed(Duration(seconds: 1));
return deposit(amount);
}
// Async generator
Stream<double> get balanceStream async* {
while (true) {
await Future.delayed(Duration(seconds: 1));
yield _balance;
}
}
// ===== JSON SERIALIZATION =====
Map<String, dynamic> toJson() => {
'accountHolder': accountHolder,
'balance': _balance,
'accountNumber': accountNumber,
'createdAt': createdAt.toIso8601String(),
};
}
// ===== INHERITANCE =====
class SavingsAccount extends BankAccount {
final double interestRate;
// Super constructor call
SavingsAccount(String holder, double balance, this.interestRate)
: super(holder, balance);
// Override method
@override
bool withdraw(double amount, [String? description]) {
// Add withdrawal limit logic
if (amount > 5000) {
print('Withdrawal limit exceeded');
return false;
}
return super.withdraw(amount, description);
}
// New method
void applyInterest() {
double interest = balance * interestRate;
deposit(interest);
}
}
// ===== ABSTRACT CLASS =====
abstract class Account {
String get accountType;
void closeAccount();
// Concrete method in abstract class
void logActivity(String activity) {
print('[$accountType] $activity');
}
}
// ===== INTERFACE (implicit via class) =====
class Auditable {
DateTime? lastAuditDate;
void audit() {}
}
// ===== MIXIN =====
mixin NotificationMixin {
void sendNotification(String message) {
print('Notification: $message');
}
void notifyTransaction(String type, double amount) {
sendNotification('$type of \$$amount processed');
}
}
// ===== ENUM =====
enum AccountType {
checking('CHK'),
savings('SAV'),
business('BUS');
final String code;
const AccountType(this.code);
}
// ===== EXTENSION =====
extension BankAccountExtensions on BankAccount {
// Add new getter
String get formattedBalance => '\$${_balance.toStringAsFixed(2)}';
// Add new method
bool get hasMinimumBalance => _balance >= BankAccount.minimumBalance;
}
// ===== GENERIC CLASS =====
class TransactionProcessor<T extends BankAccount> {
final List<T> accounts = [];
void processAll(double Function(T) operation) {
for (var account in accounts) {
operation(account);
}
}
}
// ===== USAGE EXAMPLES =====
void main() {
// Create instances
var acc1 = BankAccount('Alice', 1000);
var acc2 = BankAccount.vip('Bob');
var acc3 = BankAccount.empty('Charlie');
// Use properties
print(acc1.balance); // Getter
acc1.balance = 1500; // Setter
print(acc1.isVip); // Computed property
// Use methods
acc1.deposit(500);
acc1.withdraw(200, 'ATM withdrawal');
acc1.transfer(recipient: acc2, amount: 100);
// Static methods
print('Total accounts: ${BankAccount.totalAccounts}');
var interest = BankAccount.calculateInterest(1000, 0.05, 2);
// Operators
var acc4 = acc1 + 500; // Addition operator
print(acc1 == acc2); // Equality operator
print(acc1 < acc2); // Comparison operator
print(acc1[0]); // Index operator
// Special methods
print(acc1); // toString()
print(acc1()); // Call method
// Async usage
acc1.processTransaction(100).then((success) {
print('Transaction success: $success');
});
// JSON serialization
var json = acc1.toJson();
var restored = BankAccount.fromJson(json);
// Extension usage
print(acc1.formattedBalance);
print(acc1.hasMinimumBalance);
// Inheritance
var savings = SavingsAccount('Eve', 5000, 0.03);
savings.applyInterest();
// With cascade operator
var acc5 = BankAccount('Frank')
..deposit(1000)
..withdraw(200)
..balance = 2000;
}1.3.1 Quick Reference Summary
Class Declaration Patterns:
class Name { } // Regular class
abstract class Name { } // Abstract class
class Name extends Parent { } // Inheritance
class Name implements Interface { } // Interface implementation
class Name with Mixin { } // Mixin usage
class Name<T> { } // Generic classConstructor Patterns:
ClassName(this.field); // Simplified constructor
ClassName() : field = value; // Initializer list
ClassName.named(); // Named constructor
factory ClassName() { } // Factory constructorMethod Patterns:
void method() { } // Instance method
static void method() { } // Static method
Future<void> method() async { } // Async method
Type get property => value; // Getter
set property(Type value) { } // SetterAccess Modifiers:
field // Public (default)
_field // Private (library-private)This cheatsheet covers all major OOP concepts in Dart with practical examples you can adapt for your own classes!
1.4 TypeScript
Here’s a comprehensive TypeScript OOP CheatSheet using the BankAccount example:
// TYPESCRIPT OOP CHEATSHEET - BankAccount Example
// ===== INTERFACES =====
interface Auditable {
lastAuditDate?: Date;
audit(): void;
}
interface Transaction {
type: string;
amount: number;
description?: string;
timestamp: Date;
balanceAfter: number;
}
interface AccountConfig {
accountHolder: string;
initialBalance?: number;
accountType?: AccountType;
}
// ===== TYPE ALIASES =====
type AccountNumber = `ACC${string}`;
type Currency = number;
type TransactionType = 'deposit' | 'withdrawal' | 'transfer';
// ===== ENUMS =====
enum AccountType {
Checking = 'CHK',
Savings = 'SAV',
Business = 'BUS'
}
// ===== ABSTRACT CLASS =====
abstract class Account {
abstract readonly accountType: string;
abstract closeAccount(): void;
// Concrete method in abstract class
logActivity(activity: string): void {
console.log(`[${this.accountType}] ${activity}`);
}
}
// ===== MAIN CLASS =====
class BankAccount extends Account implements Auditable {
// ===== STATIC PROPERTIES =====
static readonly bankName: string = "SimpleBank"; // Readonly static
static readonly minimumBalance: number = 100; // Compile-time constant
private static _totalAccounts: number = 0; // Private static
// ===== INSTANCE PROPERTIES =====
// Public properties
accountHolder: string;
transactionHistory: Transaction[] = [];
lastAuditDate?: Date; // From Auditable interface
// Private properties
private _balance: Currency;
private _pin?: string; // Optional property
// Protected property (accessible in subclasses)
protected overdraftLimit: number = 0;
// Readonly properties
readonly accountNumber: AccountNumber;
readonly createdAt: Date;
// ===== CONSTRUCTOR =====
constructor(accountHolder: string, initialBalance: Currency = 0) {
super(); // Call parent constructor
this.accountHolder = accountHolder;
this._balance = initialBalance;
this.accountNumber = this._generateAccountNumber();
this.createdAt = new Date();
BankAccount._totalAccounts++;
}
// ===== GETTERS AND SETTERS =====
// Getter
get balance(): Currency {
return this._balance;
}
// Setter with validation
set balance(amount: Currency) {
if (amount >= 0) {
this._balance = amount;
} else {
throw new Error('Balance cannot be negative');
}
}
// Computed property (getter only)
get isVip(): boolean {
return this._balance > 50000;
}
// Abstract property implementation
get accountType(): string {
return 'Standard';
}
// ===== INSTANCE METHODS =====
// Public method
deposit(amount: Currency): boolean {
if (amount > 0) {
this._balance += amount;
this._recordTransaction('deposit', amount);
return true;
}
return false;
}
// Method with optional parameter
withdraw(amount: Currency, description?: string): boolean {
if (amount > 0 && amount <= this._balance - BankAccount.minimumBalance) {
this._balance -= amount;
this._recordTransaction('withdrawal', amount, description);
return true;
}
return false;
}
// Method with object parameter (named parameters pattern)
transfer(options: {
recipient: BankAccount;
amount: Currency;
reference?: string;
}): void {
const { recipient, amount, reference } = options;
if (this.withdraw(amount)) {
recipient.deposit(amount);
this._recordTransaction('transfer', amount,
`To: ${recipient.accountHolder}`);
}
}
// Private method
private _recordTransaction(
type: TransactionType,
amount: Currency,
description?: string
): void {
this.transactionHistory.push({
type,
amount,
description,
timestamp: new Date(),
balanceAfter: this._balance,
});
}
// Protected method (accessible in subclasses)
protected _generateAccountNumber(): AccountNumber {
const num = Math.floor(Math.random() * 999999)
.toString()
.padStart(6, '0');
return `ACC${num}`;
}
// ===== STATIC METHODS =====
// Static getter
static get totalAccounts(): number {
return this._totalAccounts;
}
// Static method
static calculateInterest(
principal: Currency,
rate: number,
years: number
): Currency {
return principal * rate * years;
}
// Static factory method
static createBusinessAccount(businessName: string): BankAccount {
const account = new BankAccount(businessName, 5000);
account._recordTransaction('deposit', 5000, 'Initial deposit');
return account;
}
// ===== ASYNC METHODS =====
// Async method
async processTransaction(amount: Currency): Promise<boolean> {
// Simulate network delay
await new Promise(resolve => setTimeout(resolve, 1000));
return this.deposit(amount);
}
// Async generator
async *getBalanceHistory(): AsyncGenerator<Currency> {
for (const transaction of this.transactionHistory) {
await new Promise(resolve => setTimeout(resolve, 100));
yield transaction.balanceAfter;
}
}
// ===== SPECIAL METHODS =====
// toString equivalent
toString(): string {
return `BankAccount(${this.accountHolder}, Balance: $${this._balance})`;
}
// valueOf for numeric conversion
valueOf(): number {
return this._balance;
}
// JSON serialization
toJSON(): object {
return {
accountHolder: this.accountHolder,
balance: this._balance,
accountNumber: this.accountNumber,
createdAt: this.createdAt.toISOString(),
};
}
// Interface implementation
audit(): void {
this.lastAuditDate = new Date();
console.log(`Account ${this.accountNumber} audited`);
}
// Abstract method implementation
closeAccount(): void {
this._balance = 0;
BankAccount._totalAccounts--;
}
}
// ===== INHERITANCE =====
class SavingsAccount extends BankAccount {
private interestRate: number;
constructor(holder: string, balance: Currency, interestRate: number) {
super(holder, balance); // Call parent constructor
this.interestRate = interestRate;
}
// Override parent method
override withdraw(amount: Currency, description?: string): boolean {
// Add withdrawal limit logic
if (amount > 5000) {
console.log('Withdrawal limit exceeded');
return false;
}
return super.withdraw(amount, description);
}
// Override getter
override get accountType(): string {
return 'Savings';
}
// New method
applyInterest(): void {
const interest = this.balance * this.interestRate;
this.deposit(interest);
}
}
// ===== GENERIC CLASS =====
class TransactionProcessor<T extends BankAccount> {
private accounts: T[] = [];
addAccount(account: T): void {
this.accounts.push(account);
}
processAll(operation: (account: T) => Currency): Currency[] {
return this.accounts.map(operation);
}
findAccount(predicate: (account: T) => boolean): T | undefined {
return this.accounts.find(predicate);
}
}
// ===== DECORATOR PATTERN (Method Decorator) =====
function log(target: any, propertyName: string, descriptor: PropertyDescriptor) {
const method = descriptor.value;
descriptor.value = function(...args: any[]) {
console.log(`Calling ${propertyName} with args:`, args);
const result = method.apply(this, args);
console.log(`Result:`, result);
return result;
};
}
// ===== MIXIN PATTERN =====
type Constructor<T = {}> = new (...args: any[]) => T;
function NotificationMixin<TBase extends Constructor>(Base: TBase) {
return class extends Base {
sendNotification(message: string): void {
console.log(`Notification: ${message}`);
}
notifyTransaction(type: string, amount: Currency): void {
this.sendNotification(`${type} of $${amount} processed`);
}
};
}
// Apply mixin
class NotifiableBankAccount extends NotificationMixin(BankAccount) {
@log
override deposit(amount: Currency): boolean {
const result = super.deposit(amount);
if (result) {
this.notifyTransaction('Deposit', amount);
}
return result;
}
}
// ===== NAMESPACE =====
namespace Banking {
export interface Fee {
type: string;
amount: Currency;
}
export class FeeCalculator {
static calculateTransactionFee(amount: Currency): Currency {
return amount * 0.01;
}
}
}
// ===== TYPE GUARDS =====
function isBankAccount(account: any): account is BankAccount {
return account instanceof BankAccount;
}
function isSavingsAccount(account: BankAccount): account is SavingsAccount {
return 'applyInterest' in account;
}
// ===== UTILITY TYPES =====
// Partial type for updates
type AccountUpdate = Partial<{
accountHolder: string;
balance: Currency;
}>;
// Readonly version
type ReadonlyAccount = Readonly<BankAccount>;
// Pick specific properties
type AccountSummary = Pick<BankAccount, 'accountHolder' | 'accountNumber'>;
// ===== USAGE EXAMPLES =====
function main() {
// Create instances
const acc1 = new BankAccount('Alice', 1000);
const acc2 = new SavingsAccount('Bob', 5000, 0.03);
const acc3 = new NotifiableBankAccount('Charlie', 2000);
// Use properties
console.log(acc1.balance); // Getter
acc1.balance = 1500; // Setter
console.log(acc1.isVip); // Computed property
// Use methods
acc1.deposit(500);
acc1.withdraw(200, 'ATM withdrawal');
acc1.transfer({
recipient: acc2,
amount: 100,
reference: 'REF123'
});
// Static methods
console.log(`Total accounts: ${BankAccount.totalAccounts}`);
const interest = BankAccount.calculateInterest(1000, 0.05, 2);
// Type guards
if (isSavingsAccount(acc2)) {
acc2.applyInterest();
}
// Async usage
acc1.processTransaction(100).then(success => {
console.log('Transaction success:', success);
});
// Async generator
(async () => {
for await (const balance of acc1.getBalanceHistory()) {
console.log('Historical balance:', balance);
}
})();
// JSON serialization
const json = JSON.stringify(acc1);
const parsed = JSON.parse(json);
// Generic usage
const processor = new TransactionProcessor<BankAccount>();
processor.addAccount(acc1);
processor.addAccount(acc2);
const balances = processor.processAll(acc => acc.balance);
// Namespace usage
const fee = Banking.FeeCalculator.calculateTransactionFee(100);
// Type narrowing with discriminated unions
type AccountEvent =
| { type: 'created'; account: BankAccount }
| { type: 'closed'; accountNumber: string }
| { type: 'transaction'; account: BankAccount; amount: number };
function handleEvent(event: AccountEvent) {
switch (event.type) {
case 'created':
console.log('New account:', event.account.accountHolder);
break;
case 'closed':
console.log('Account closed:', event.accountNumber);
break;
case 'transaction':
console.log('Transaction:', event.amount);
break;
}
}
}
// ===== MODULE EXPORTS =====
export {
BankAccount,
SavingsAccount,
TransactionProcessor,
AccountType,
type Transaction,
type AccountConfig
};
// Default export
export default BankAccount;1.4.1 Quick Reference Summary
Class Declaration Patterns:
class Name { } // Regular class
abstract class Name { } // Abstract class
class Name extends Parent { } // Inheritance
class Name implements Interface { } // Interface implementation
class Name<T> { } // Generic classProperty Patterns:
property: Type; // Public property
private property: Type; // Private property
protected property: Type; // Protected property
readonly property: Type; // Readonly property
property?: Type; // Optional property
static property: Type; // Static property
#property: Type; // Private field (ES2022)Method Patterns:
method(): void { } // Instance method
static method(): void { } // Static method
async method(): Promise<T> { } // Async method
*method(): Generator<T> { } // Generator method
get property(): Type { } // Getter
set property(value: Type) { } // Setter
private method(): void { } // Private method
protected method(): void { } // Protected method
override method(): void { } // Override parent methodConstructor Patterns:
constructor(param: Type) { } // Basic constructor
constructor(public param: Type) { } // Parameter property
constructor(param?: Type) { } // Optional parameter
constructor(...args: Type[]) { } // Rest parametersInterface Patterns:
interface Name { } // Interface declaration
interface Name extends Parent { } // Interface inheritance
type Name = { }; // Type alias
type Union = Type1 | Type2; // Union type
type Intersection = Type1 & Type2; // Intersection type