Object-Oriented Programming
Object-Oriented Programming
Introduction
In this lesson, you'll learn about object-oriented programming in Python. Coming from C#, you already have a foundation for understanding this concept. We'll build on that knowledge while highlighting the key differences.
In C#, you're familiar with object-oriented programming.
Python has its own approach to object-oriented programming, which we'll explore step by step.
The Python Way
Let's see how Python handles this concept. Here's a typical example:
class Person:
def __init__(self, name: str, age: int):
self.name = name
self._age = age # convention: _ = "private"
@property
def age(self) -> int:
return self._age
@age.setter
def age(self, value: int):
self._age = value if value > 0 else 0Comparing to C#
Here's how you might have written similar code in C#:
class Person {
public string Name { get; set; }
private int _age;
public Person(string name, int age) {
Name = name;
_age = age;
}
public int Age {
get => _age;
set => _age = value > 0 ? value : 0;
}
}You may be used to different syntax or behavior.
Python __init__ replaces the C# constructor
You may be used to different syntax or behavior.
self is the explicit first parameter of every instance method (like 'this' but required)
You may be used to different syntax or behavior.
@property decorator replaces C# property getter
You may be used to different syntax or behavior.
@propname.setter decorator replaces C# property setter
You may be used to different syntax or behavior.
No access modifiers — use _ prefix convention for 'private' fields
Step-by-Step Breakdown
1. Class and Constructor
Python uses __init__ as the constructor. The first parameter 'self' is like C#'s implicit 'this', but must be written explicitly in every method.
class Car {
string Model;
int Year;
public Car(string model, int year) {
Model = model;
Year = year;
}
}class Car:
def __init__(self, model: str, year: int):
self.model = model
self.year = year
car = Car("Tesla", 2024) # no 'new' keyword!2. Properties with @property
Python @property turns a method into a read-only property. Add a @name.setter to make it writable. This maps directly to C# get/set.
public int Age {
get => _age;
set => _age = value >= 0 ? value : 0;
}@property
def age(self) -> int:
return self._age
@age.setter
def age(self, value: int):
self._age = value if value >= 0 else 0
# Usage is same as accessing a field:
person.age = 30 # calls setter
print(person.age) # calls getter3. Inheritance
Python inheritance looks similar to C#. The super() call replaces base.MethodName() or base().
class Animal {
public virtual void Speak() =>
Console.WriteLine("...");
}
class Dog : Animal {
public override void Speak() =>
Console.WriteLine("Woof!");
}class Animal:
def speak(self):
print("...")
class Dog(Animal):
def speak(self):
print("Woof!")
def __init__(self, name):
super().__init__() # call parent __init__
self.name = name4. Dataclasses — Replacing Simple POCOs
Python @dataclass automatically generates __init__, __repr__, and __eq__ — similar to C# record or a simple POCO with auto-properties.
record Point(int X, int Y);
// auto: constructor, ToString, Equals, GetHashCodefrom dataclasses import dataclass
@dataclass
class Point:
x: int
y: int
p = Point(1, 2)
print(p) # Point(x=1, y=2)
p1 = Point(1, 2)
p2 = Point(1, 2)
print(p1 == p2) # True (value equality)Common Mistakes
When coming from C#, developers often make these mistakes:
- Python __init__ replaces the C# constructor
- self is the explicit first parameter of every instance method (like 'this' but required)
- @property decorator replaces C# property getter
Key Takeaways
- __init__ is the constructor; self is the explicit 'this'
- @property and @name.setter replace C# property syntax
- No access modifiers — _ prefix is the 'private' convention
- @dataclass generates boilerplate, similar to C# records