Classes and Objects
Before diving into advanced OOP concepts, let’s start with the fundamentals: understanding what classes are and how to write them.
What is a Class?
Section titled “What is a Class?”A class is a blueprint or template for creating objects. It defines:
- Attributes (data/variables)
- Methods (functions that operate on the data)
An object (or instance) is a specific realization of a class - a concrete example created from the blueprint.
Real-World Analogy
Section titled “Real-World Analogy”Think of a class like a cookie cutter:
- The class is the cookie cutter (the template)
- The objects are the cookies (specific instances created from the template)
All cookies made from the same cutter have the same shape, but each cookie is a separate object.
Basic Class Structure
Section titled “Basic Class Structure”Here’s the simplest class definition:
class Dog: pass # Empty class
# Create an instance (object)my_dog = Dog()print(type(my_dog)) # <class '__main__.Dog'><class '__main__.Dog'>public class Dog { // Empty class}
// Create an instance (object)public class Main { public static void main(String[] args) { Dog myDog = new Dog(); System.out.println(myDog.getClass().getName()); // Dog }}Dogclass Dog { // Empty class}
// Create an instance (object)const myDog = new Dog();console.log(myDog.constructor.name); // DogDog#include <iostream>#include <typeinfo>
class Dog { // Empty class};
int main() { // Create an instance (object) Dog myDog; std::cout << typeid(myDog).name() << std::endl; // 3Dog (mangled name)
return 0;}3Dogusing System;
public class Dog { // Empty class}
public class Program { public static void Main() { // Create an instance (object) Dog myDog = new Dog(); Console.WriteLine(myDog.GetType().Name); // Dog }}Dogpackage main
import ( "fmt" "reflect")
type Dog struct{}
func main() { myDog := &Dog{} fmt.Println(reflect.TypeOf(myDog).Elem().Name())}Dogstruct Dog;
fn main() { let my_dog = Dog; println!("{}", std::any::type_name::<Dog>()); // simple_class::Dog}simple_class::DogThe Constructor
Section titled “The Constructor”The constructor is a special method called when you create a new instance of a class.
class Dog: def __init__(self, name: str, breed: str): """Constructor - called when creating a new Dog instance""" self.name = name self.breed = breed
# Create instancesdog1 = Dog("Buddy", "Golden Retriever")dog2 = Dog("Max", "German Shepherd")
print(dog1.name) # "Buddy"print(dog2.breed) # "German Shepherd"BuddyGerman Shepherdpublic class Dog { private String name; private String breed;
// Constructor - called when creating a new Dog instance public Dog(String name, String breed) { this.name = name; this.breed = breed; }
// Getters public String getName() { return name; }
public String getBreed() { return breed; }}
// Create instancespublic class Main { public static void main(String[] args) { Dog dog1 = new Dog("Buddy", "Golden Retriever"); Dog dog2 = new Dog("Max", "German Shepherd");
System.out.println(dog1.getName()); // "Buddy" System.out.println(dog2.getBreed()); // "German Shepherd" }}BuddyGerman Shepherdclass Dog { name: string; breed: string;
// Constructor - called when creating a new Dog instance constructor(name: string, breed: string) { this.name = name; this.breed = breed; }}
// Create instancesconst dog1 = new Dog("Buddy", "Golden Retriever");const dog2 = new Dog("Max", "German Shepherd");
console.log(dog1.name); // "Buddy"console.log(dog2.breed); // "German Shepherd"BuddyGerman Shepherd#include <iostream>#include <string>
class Dog {private: std::string name; std::string breed;
public: // Constructor - called when creating a new Dog instance Dog(const std::string& name, const std::string& breed) : name(name), breed(breed) {}
// Getters std::string getName() const { return name; }
std::string getBreed() const { return breed; }};
int main() { // Create instances Dog dog1("Buddy", "Golden Retriever"); Dog dog2("Max", "German Shepherd");
std::cout << dog1.getName() << std::endl; // "Buddy" std::cout << dog2.getBreed() << std::endl; // "German Shepherd"
return 0;}BuddyGerman Shepherdusing System;
public class Dog { private string name; private string breed;
// Constructor - called when creating a new Dog instance public Dog(string name, string breed) { this.name = name; this.breed = breed; }
// Getters public string GetName() { return name; }
public string GetBreed() { return breed; }}
public class Program { public static void Main() { // Create instances Dog dog1 = new Dog("Buddy", "Golden Retriever"); Dog dog2 = new Dog("Max", "German Shepherd");
Console.WriteLine(dog1.GetName()); // "Buddy" Console.WriteLine(dog2.GetBreed()); // "German Shepherd" }}BuddyGerman Shepherdpackage main
import "fmt"
type Dog struct { name string breed string}
func NewDog(name, breed string) *Dog { return &Dog{name: name, breed: breed}}
func (d *Dog) GetName() string { return d.name }func (d *Dog) GetBreed() string { return d.breed }
func main() { dog1 := NewDog("Buddy", "Golden Retriever") dog2 := NewDog("Max", "German Shepherd")
fmt.Println(dog1.GetName()) fmt.Println(dog2.GetBreed())}BuddyGerman Shepherdstruct Dog { name: String, breed: String,}
impl Dog { fn new(name: impl Into<String>, breed: impl Into<String>) -> Self { Self { name: name.into(), breed: breed.into(), } }
fn name(&self) -> &str { &self.name }
fn breed(&self) -> &str { &self.breed }}
fn main() { let dog1 = Dog::new("Buddy", "Golden Retriever"); let dog2 = Dog::new("Max", "German Shepherd");
println!("{}", dog1.name()); println!("{}", dog2.breed());}BuddyGerman ShepherdUnderstanding self and this
Section titled “Understanding self and this”class Person: def __init__(self, name: str, age: int): # self refers to the current instance self.name = name # Instance attribute self.age = age # Instance attribute
def introduce(self): # self allows access to instance attributes return f"Hi, I'm {self.name} and I'm {self.age} years old"
person = Person("Alice", 30)print(person.introduce()) # "Hi, I'm Alice and I'm 30 years old"Hi, I'm Alice and I'm 30 years oldpublic class Person { private String name; private int age;
// Constructor - this refers to the current instance public Person(String name, int age) { this.name = name; // Instance attribute this.age = age; // Instance attribute }
public String introduce() { // this allows access to instance attributes return "Hi, I'm " + this.name + " and I'm " + this.age + " years old"; }}
// Usagepublic class Main { public static void main(String[] args) { Person person = new Person("Alice", 30); System.out.println(person.introduce()); // "Hi, I'm Alice and I'm 30 years old" }}Hi, I'm Alice and I'm 30 years oldclass Person { name: string; age: number;
// Constructor - this refers to the current instance constructor(name: string, age: number) { this.name = name; // Instance attribute this.age = age; // Instance attribute }
introduce(): string { // this allows access to instance attributes return `Hi, I'm ${this.name} and I'm ${this.age} years old`; }}
const person = new Person("Alice", 30);console.log(person.introduce()); // "Hi, I'm Alice and I'm 30 years old"Hi, I'm Alice and I'm 30 years old#include <iostream>#include <string>
class Person {private: std::string name; int age;
public: // Constructor - refers to the current instance Person(const std::string& name, int age) : name(name), age(age) {}
std::string introduce() const { // Access instance attributes return "Hi, I'm " + name + " and I'm " + std::to_string(age) + " years old"; }};
int main() { Person person("Alice", 30); std::cout << person.introduce() << std::endl; // "Hi, I'm Alice and I'm 30 years old"
return 0;}Hi, I'm Alice and I'm 30 years oldusing System;
public class Person { private string name; private int age;
// Constructor - this refers to the current instance public Person(string name, int age) { this.name = name; // Instance attribute this.age = age; // Instance attribute }
public string Introduce() { // this allows access to instance attributes return $"Hi, I'm {this.name} and I'm {this.age} years old"; }}
public class Program { public static void Main() { Person person = new Person("Alice", 30); Console.WriteLine(person.Introduce()); // "Hi, I'm Alice and I'm 30 years old" }}Hi, I'm Alice and I'm 30 years oldpackage main
import "fmt"
type Person struct { name string age int}
func NewPerson(name string, age int) *Person { return &Person{name: name, age: age}}
func (p *Person) Introduce() string { return fmt.Sprintf("Hi, I'm %s and I'm %d years old", p.name, p.age)}
func main() { person := NewPerson("Alice", 30) fmt.Println(person.Introduce())}Hi, I'm Alice and I'm 30 years oldstruct Person { name: String, age: u32,}
impl Person { fn new(name: impl Into<String>, age: u32) -> Self { Self { name: name.into(), age, } }
fn introduce(&self) -> String { format!("Hi, I'm {} and I'm {} years old", self.name, self.age) }}
fn main() { let person = Person::new("Alice", 30); println!("{}", person.introduce());}Hi, I'm Alice and I'm 30 years oldInstance Attributes
Section titled “Instance Attributes”Instance attributes are variables that belong to a specific instance. Each object has its own copy of these attributes.
class BankAccount: def __init__(self, account_number: str, balance: float): # Instance attributes - unique to each account self.account_number = account_number self.balance = balance
# Each account has its own balanceaccount1 = BankAccount("ACC-001", 1000.0)account2 = BankAccount("ACC-002", 500.0)
print(account1.balance) # 1000.0print(account2.balance) # 500.01000.0500.0public class BankAccount { private String accountNumber; private double balance;
// Constructor public BankAccount(String accountNumber, double balance) { this.accountNumber = accountNumber; this.balance = balance; }
// Getters public double getBalance() { return balance; }
public String getAccountNumber() { return accountNumber; }}
// Usagepublic class Main { public static void main(String[] args) { BankAccount account1 = new BankAccount("ACC-001", 1000.0); BankAccount account2 = new BankAccount("ACC-002", 500.0);
System.out.println(account1.getBalance()); // 1000.0 System.out.println(account2.getBalance()); // 500.0 }}1000.0500.0class BankAccount { accountNumber: string; balance: number;
// Constructor constructor(accountNumber: string, balance: number) { // Instance attributes - unique to each account this.accountNumber = accountNumber; this.balance = balance; }}
// Each account has its own balanceconst account1 = new BankAccount("ACC-001", 1000.0);const account2 = new BankAccount("ACC-002", 500.0);
console.log(account1.balance); // 1000.0console.log(account2.balance); // 500.01000500#include <iostream>#include <string>
class BankAccount {private: std::string accountNumber; double balance;
public: // Constructor BankAccount(const std::string& accountNumber, double balance) : accountNumber(accountNumber), balance(balance) {}
// Getters double getBalance() const { return balance; }
std::string getAccountNumber() const { return accountNumber; }};
int main() { // Each account has its own balance BankAccount account1("ACC-001", 1000.0); BankAccount account2("ACC-002", 500.0);
std::cout << account1.getBalance() << std::endl; // 1000.0 std::cout << account2.getBalance() << std::endl; // 500.0
return 0;}1000500using System;
public class BankAccount { private string accountNumber; private double balance;
// Constructor public BankAccount(string accountNumber, double balance) { // Instance attributes - unique to each account this.accountNumber = accountNumber; this.balance = balance; }
// Getters public double GetBalance() { return balance; }
public string GetAccountNumber() { return accountNumber; }}
public class Program { public static void Main() { // Each account has its own balance BankAccount account1 = new BankAccount("ACC-001", 1000.0); BankAccount account2 = new BankAccount("ACC-002", 500.0);
Console.WriteLine(account1.GetBalance()); // 1000.0 Console.WriteLine(account2.GetBalance()); // 500.0 }}1000500package main
import "fmt"
type BankAccount struct { accountNumber string balance float64}
func NewBankAccount(accountNumber string, balance float64) *BankAccount { return &BankAccount{accountNumber: accountNumber, balance: balance}}
func (b *BankAccount) GetBalance() float64 { return b.balance }func (b *BankAccount) GetAccountNumber() string { return b.accountNumber }
func main() { account1 := NewBankAccount("ACC-001", 1000.0) account2 := NewBankAccount("ACC-002", 500.0)
fmt.Println(account1.GetBalance()) fmt.Println(account2.GetBalance())}1000500struct BankAccount { account_number: String, balance: f64,}
impl BankAccount { fn new(account_number: impl Into<String>, balance: f64) -> Self { Self { account_number: account_number.into(), balance, } }
fn balance(&self) -> f64 { self.balance }
fn account_number(&self) -> &str { &self.account_number }}
fn main() { let account1 = BankAccount::new("ACC-001", 1000.0); let account2 = BankAccount::new("ACC-002", 500.0);
println!("{}", account1.balance()); println!("{}", account2.balance());}1000500Instance Methods
Section titled “Instance Methods”Instance methods are functions defined inside a class that operate on instance data.
class BankAccount: def __init__(self, account_number: str, balance: float): self.account_number = account_number self.balance = balance
def deposit(self, amount: float): """Instance method - operates on this account""" if amount > 0: self.balance += amount return f"Deposited ${amount:.2f}. New balance: ${self.balance:.2f}" return "Invalid deposit amount"
def withdraw(self, amount: float): """Instance method - operates on this account""" if 0 < amount <= self.balance: self.balance -= amount return f"Withdrew ${amount:.2f}. New balance: ${self.balance:.2f}" return "Insufficient funds or invalid amount"
def get_balance(self): """Instance method - returns this account's balance""" return self.balance
# Usageaccount = BankAccount("ACC-001", 1000.0)print(account.deposit(500.0)) # Deposited $500.00. New balance: $1500.00print(account.withdraw(200.0)) # Withdrew $200.00. New balance: $1300.00print(account.get_balance()) # 1300.0Deposited $500.00. New balance: $1500.00Withdrew $200.00. New balance: $1300.001300.0public class BankAccount { private String accountNumber; private double balance;
public BankAccount(String accountNumber, double balance) { this.accountNumber = accountNumber; this.balance = balance; }
// Instance method - operates on this account public String deposit(double amount) { if (amount > 0) { this.balance += amount; return String.format("Deposited $%.2f. New balance: $%.2f", amount, this.balance); } return "Invalid deposit amount"; }
// Instance method - operates on this account public String withdraw(double amount) { if (amount > 0 && amount <= this.balance) { this.balance -= amount; return String.format("Withdrew $%.2f. New balance: $%.2f", amount, this.balance); } return "Insufficient funds or invalid amount"; }
// Instance method - returns this account's balance public double getBalance() { return this.balance; }}
// Usagepublic class Main { public static void main(String[] args) { BankAccount account = new BankAccount("ACC-001", 1000.0); System.out.println(account.deposit(500.0)); // Deposited $500.00. New balance: $1500.00 System.out.println(account.withdraw(200.0)); // Withdrew $200.00. New balance: $1300.00 System.out.println(account.getBalance()); // 1300.0 }}Deposited $500.00. New balance: $1500.00Withdrew $200.00. New balance: $1300.001300.0class BankAccount { private accountNumber: string; private balance: number;
constructor(accountNumber: string, balance: number) { this.accountNumber = accountNumber; this.balance = balance; }
// Instance method - operates on this account deposit(amount: number): string { if (amount > 0) { this.balance += amount; return `Deposited $${amount.toFixed(2)}. New balance: $${this.balance.toFixed(2)}`; } return "Invalid deposit amount"; }
// Instance method - operates on this account withdraw(amount: number): string { if (amount > 0 && amount <= this.balance) { this.balance -= amount; return `Withdrew $${amount.toFixed(2)}. New balance: $${this.balance.toFixed(2)}`; } return "Insufficient funds or invalid amount"; }
// Instance method - returns this account's balance getBalance(): number { return this.balance; }}
// Usageconst account = new BankAccount("ACC-001", 1000.0);console.log(account.deposit(500.0)); // Deposited $500.00. New balance: $1500.00console.log(account.withdraw(200.0)); // Withdrew $200.00. New balance: $1300.00console.log(account.getBalance()); // 1300.0Deposited $500.00. New balance: $1500.00Withdrew $200.00. New balance: $1300.001300#include <iostream>#include <string>#include <sstream>#include <iomanip>
class BankAccount {private: std::string accountNumber; double balance;
public: BankAccount(const std::string& accountNumber, double balance) : accountNumber(accountNumber), balance(balance) {}
// Instance method - operates on this account std::string deposit(double amount) { if (amount > 0) { balance += amount; std::stringstream ss; ss << "Deposited $" << std::fixed << std::setprecision(2) << amount << ". New balance: $" << balance; return ss.str(); } return "Invalid deposit amount"; }
// Instance method - operates on this account std::string withdraw(double amount) { if (amount > 0 && amount <= balance) { balance -= amount; std::stringstream ss; ss << "Withdrew $" << std::fixed << std::setprecision(2) << amount << ". New balance: $" << balance; return ss.str(); } return "Insufficient funds or invalid amount"; }
// Instance method - returns this account's balance double getBalance() const { return balance; }};
int main() { BankAccount account("ACC-001", 1000.0); std::cout << account.deposit(500.0) << std::endl; // Deposited $500.00. New balance: $1500.00 std::cout << account.withdraw(200.0) << std::endl; // Withdrew $200.00. New balance: $1300.00 std::cout << account.getBalance() << std::endl; // 1300.0
return 0;}Deposited $500.00. New balance: $1500.00Withdrew $200.00. New balance: $1300.001300using System;
public class BankAccount { private string accountNumber; private double balance;
public BankAccount(string accountNumber, double balance) { this.accountNumber = accountNumber; this.balance = balance; }
// Instance method - operates on this account public string Deposit(double amount) { if (amount > 0) { balance += amount; return $"Deposited ${amount:F2}. New balance: ${balance:F2}"; } return "Invalid deposit amount"; }
// Instance method - operates on this account public string Withdraw(double amount) { if (amount > 0 && amount <= balance) { balance -= amount; return $"Withdrew ${amount:F2}. New balance: ${balance:F2}"; } return "Insufficient funds or invalid amount"; }
// Instance method - returns this account's balance public double GetBalance() { return balance; }}
public class Program { public static void Main() { BankAccount account = new BankAccount("ACC-001", 1000.0); Console.WriteLine(account.Deposit(500.0)); // Deposited $500.00. New balance: $1500.00 Console.WriteLine(account.Withdraw(200.0)); // Withdrew $200.00. New balance: $1300.00 Console.WriteLine(account.GetBalance()); // 1300.0 }}Deposited $500.00. New balance: $1500.00Withdrew $200.00. New balance: $1300.001300package main
import "fmt"
type BankAccount struct { accountNumber string balance float64}
func NewBankAccount(accountNumber string, balance float64) *BankAccount { return &BankAccount{accountNumber: accountNumber, balance: balance}}
func (b *BankAccount) Deposit(amount float64) string { if amount > 0 { b.balance += amount return fmt.Sprintf("Deposited $%.2f. New balance: $%.2f", amount, b.balance) } return "Invalid deposit amount"}
func (b *BankAccount) Withdraw(amount float64) string { if amount > 0 && amount <= b.balance { b.balance -= amount return fmt.Sprintf("Withdrew $%.2f. New balance: $%.2f", amount, b.balance) } return "Insufficient funds or invalid amount"}
func (b *BankAccount) GetBalance() float64 { return b.balance}
func main() { account := NewBankAccount("ACC-001", 1000.0)
fmt.Println(account.Deposit(500.0)) fmt.Println(account.Withdraw(200.0)) fmt.Println(account.GetBalance())}Deposited $500.00. New balance: $1500.00Withdrew $200.00. New balance: $1300.001300struct BankAccount { account_number: String, balance: f64,}
impl BankAccount { fn new(account_number: impl Into<String>, balance: f64) -> Self { Self { account_number: account_number.into(), balance, } }
fn deposit(&mut self, amount: f64) -> String { if amount > 0.0 { self.balance += amount; return format!( "Deposited ${:.2}. New balance: ${:.2}", amount, self.balance ); } "Invalid deposit amount".to_string() }
fn withdraw(&mut self, amount: f64) -> String { if amount > 0.0 && amount <= self.balance { self.balance -= amount; return format!( "Withdrew ${:.2}. New balance: ${:.2}", amount, self.balance ); } "Insufficient funds or invalid amount".to_string() }
fn balance(&self) -> f64 { self.balance }}
fn main() { let mut account = BankAccount::new("ACC-001", 1000.0);
println!("{}", account.deposit(500.0)); println!("{}", account.withdraw(200.0)); println!("{}", account.balance());}Deposited $500.00. New balance: $1500.00Withdrew $200.00. New balance: $1300.001300Complete Example: User Class
Section titled “Complete Example: User Class”Let’s put it all together with a complete example:
class User: """A simple User class demonstrating basic OOP concepts"""
def __init__(self, username: str, email: str, age: int): """Constructor - initialize user attributes""" self.username = username self.email = email self.age = age self.is_active = True # Default value
def get_info(self): """Instance method - return user information""" status = "active" if self.is_active else "inactive" return f"User: {self.username} ({self.email}), Age: {self.age}, Status: {status}"
def deactivate(self): """Instance method - deactivate user account""" self.is_active = False return f"{self.username} has been deactivated"
def activate(self): """Instance method - activate user account""" self.is_active = True return f"{self.username} has been activated"
def update_email(self, new_email: str): """Instance method - update user email""" if "@" in new_email: self.email = new_email return f"Email updated to {new_email}" return "Invalid email address"
# Create user instances
# Each user is independentprint(user1.get_info())print(user2.get_info())
# Modify one user - doesn't affect the otheruser1.deactivate()print(user1.get_info())print(user2.get_info())public class User { private String username; private String email; private int age; private boolean isActive;
// Constructor - initialize user attributes public User(String username, String email, int age) { this.username = username; this.email = email; this.age = age; this.isActive = true; // Default value }
// Instance method - return user information public String getInfo() { String status = isActive ? "active" : "inactive"; return String.format("User: %s (%s), Age: %d, Status: %s", username, email, age, status); }
// Instance method - deactivate user account public String deactivate() { this.isActive = false; return username + " has been deactivated"; }
// Instance method - activate user account public String activate() { this.isActive = true; return username + " has been activated"; }
// Instance method - update user email public String updateEmail(String newEmail) { if (newEmail.contains("@")) { this.email = newEmail; return "Email updated to " + newEmail; } return "Invalid email address"; }}
// Usagepublic class Main { public static void main(String[] args) {
// Each user is independent System.out.println(user1.getInfo()); System.out.println(user2.getInfo());
// Modify one user - doesn't affect the other user1.deactivate(); System.out.println(user1.getInfo()); System.out.println(user2.getInfo()); }}class User { username: string; email: string; age: number; isActive: boolean;
// Constructor - initialize user attributes constructor(username: string, email: string, age: number) { this.username = username; this.email = email; this.age = age; this.isActive = true; // Default value }
// Instance method - return user information getInfo(): string { const status = this.isActive ? "active" : "inactive"; return `User: ${this.username} (${this.email}), Age: ${this.age}, Status: ${status}`; }
// Instance method - deactivate user account deactivate(): string { this.isActive = false; return `${this.username} has been deactivated`; }
// Instance method - activate user account activate(): string { this.isActive = true; return `${this.username} has been activated`; }
// Instance method - update user email updateEmail(newEmail: string): string { if (newEmail.includes("@")) { this.email = newEmail; return `Email updated to ${newEmail}`; } return "Invalid email address"; }}
// Create user instances
// Each user is independentconsole.log(user1.getInfo());console.log(user2.getInfo());
// Modify one user - doesn't affect the otheruser1.deactivate();console.log(user1.getInfo());console.log(user2.getInfo());#include <iostream>#include <string>
class User {private: std::string username; std::string email; int age; bool isActive;
public: // Constructor - initialize user attributes User(const std::string& username, const std::string& email, int age) : username(username), email(email), age(age), isActive(true) {}
// Instance method - return user information std::string getInfo() const { std::string status = isActive ? "active" : "inactive"; return "User: " + username + " (" + email + "), Age: " + std::to_string(age) + ", Status: " + status; }
// Instance method - deactivate user account std::string deactivate() { isActive = false; return username + " has been deactivated"; }
// Instance method - activate user account std::string activate() { isActive = true; return username + " has been activated"; }
// Instance method - update user email std::string updateEmail(const std::string& newEmail) { if (newEmail.find("@") != std::string::npos) { email = newEmail; return "Email updated to " + newEmail; } return "Invalid email address"; }};
int main() { // Create user instances
// Each user is independent std::cout << user1.getInfo() << std::endl; std::cout << user2.getInfo() << std::endl;
// Modify one user - doesn't affect the other user1.deactivate(); std::cout << user1.getInfo() << std::endl; std::cout << user2.getInfo() << std::endl;
return 0;}using System;
public class User { private string username; private string email; private int age; private bool isActive;
// Constructor - initialize user attributes public User(string username, string email, int age) { this.username = username; this.email = email; this.age = age; this.isActive = true; // Default value }
// Instance method - return user information public string GetInfo() { string status = isActive ? "active" : "inactive"; return $"User: {username} ({email}), Age: {age}, Status: {status}"; }
// Instance method - deactivate user account public string Deactivate() { isActive = false; return $"{username} has been deactivated"; }
// Instance method - activate user account public string Activate() { isActive = true; return $"{username} has been activated"; }
// Instance method - update user email public string UpdateEmail(string newEmail) { if (newEmail.Contains("@")) { email = newEmail; return $"Email updated to {newEmail}"; } return "Invalid email address"; }}
public class Program { public static void Main() { // Create user instances
// Each user is independent Console.WriteLine(user1.GetInfo()); Console.WriteLine(user2.GetInfo());
// Modify one user - doesn't affect the other user1.Deactivate(); Console.WriteLine(user1.GetInfo()); Console.WriteLine(user2.GetInfo()); }}package main
import ( "fmt" "strings")
type User struct { username string email string age int isActive bool}
func NewUser(username, email string, age int) *User { return &User{ username: username, email: email, age: age, isActive: true, }}
func (u *User) GetInfo() string { status := "inactive" if u.isActive { status = "active" } return fmt.Sprintf("User: %s (%s), Age: %d, Status: %s", u.username, u.email, u.age, status)}
func (u *User) Deactivate() string { u.isActive = false return fmt.Sprintf("%s has been deactivated", u.username)}
func (u *User) Activate() string { u.isActive = true return fmt.Sprintf("%s has been activated", u.username)}
func (u *User) UpdateEmail(newEmail string) string { if strings.Contains(newEmail, "@") { u.email = newEmail return fmt.Sprintf("Email updated to %s", newEmail) } return "Invalid email address"}
func main() {
fmt.Println(user1.GetInfo()) fmt.Println(user2.GetInfo())
user1.Deactivate() fmt.Println(user1.GetInfo()) fmt.Println(user2.GetInfo())}struct User { username: String, email: String, age: u32, is_active: bool,}
impl User { fn new(username: impl Into<String>, email: impl Into<String>, age: u32) -> Self { Self { username: username.into(), email: email.into(), age, is_active: true, } }
fn get_info(&self) -> String { let status = if self.is_active { "active" } else { "inactive" }; format!( "User: {} ({}), Age: {}, Status: {}", self.username, self.email, self.age, status ) }
fn deactivate(&mut self) -> String { self.is_active = false; format!("{} has been deactivated", self.username) }
fn activate(&mut self) -> String { self.is_active = true; format!("{} has been activated", self.username) }
fn update_email(&mut self, new_email: impl Into<String>) -> String { let new_email = new_email.into(); if new_email.contains('@') { self.email = new_email.clone(); format!("Email updated to {}", new_email) } else { "Invalid email address".to_string() } }}
fn main() {
println!("{}", user1.get_info()); println!("{}", user2.get_info());
user1.deactivate(); println!("{}", user1.get_info()); println!("{}", user2.get_info());}Visual Representation
Section titled “Visual Representation”Key Takeaways
Section titled “Key Takeaways”Next Steps
Section titled “Next Steps”Now that you understand the basics of classes, you’re ready to explore:
- Enums - Named constants and type-safe enumerations
- Interfaces - Contracts that classes can implement
- Encapsulation - Protecting data with access modifiers
- Abstraction - Hiding complexity and exposing essential features
- Inheritance - Creating class hierarchies
- Polymorphism - Using objects interchangeably
Remember: Classes are a way to model real-world entities in code, bundling together related data (attributes) and behavior (methods) into a single, reusable unit.
Make this lesson stick
Answer from memory, then check yourself. No typing or sign-in needed.
What is the difference between a class and an object?