MOO WebTech
Part 2 — OOPtheory-practicebeginner

L10 — OOP pt.1: Classes & Objects

Your first step into Object-Oriented Programming. We learn what classes and objects are, how to store data with fields and properties, add methods, and work with multiple independent objects.

80 min10.04.2026L10

🎯Learning Objectives

  • Understand why OOP exists and what problems it solves
  • Define a class with fields, auto-properties, and methods
  • Create objects using new and object initializer syntax
  • Explain the difference between a class (blueprint) and an object (instance)
  • Work with multiple independent objects of the same class

📖Theory

1. What Is OOP and Why Does It Exist?

Until now, all your code has been procedural — a list of instructions running top to bottom. That works fine for small programs.

But imagine you're building a school system. You need to track each student's name, age, and grades. With procedural code you'd end up with separate arrays that you have to keep in sync manually.

C#
// Tracking 3 students without OOP
string[] names = { "Alice", "Bob", "Carol" };
int[]    ages  = { 17, 18, 17 };
double[] gpas  = { 3.8, 3.2, 3.9 };

// Want to add a 4th student?
// You must update ALL THREE arrays. Miss one → bug.

Object-Oriented Programming (OOP) solves this by letting you bundle related data and behaviour into a single unit called an object. Instead of three parallel arrays, you get one list of Student objects — each carrying its own name, age, and GPA.

One-sentence summary: OOP is a way of organising code around things (objects) instead of actions (functions). Each object knows its own data and what it can do.

2. What Is a Class?

A class is a blueprint. It describes what data a thing has and what it can do — but it is not the thing itself.

Think of a cookie cutter. The cutter is the class. The cookies you press out are the objects. One cutter, many cookies — all the same shape, each with its own sprinkles.

C#
class Car
{
    public string Brand;
    public string Color;
    public int Year;
}

This Car class says: "every car will have a Brand, a Color, and a Year." No actual car exists yet — we've only described the shape.

3. What Is an Object?

An object is a concrete instance of a class. You create one using the new keyword. Each object gets its own copy of the data defined in the class.

C#
Car myCar = new Car();
myCar.Brand = "Toyota";
myCar.Color = "Red";
myCar.Year  = 2024;

Console.WriteLine($"{myCar.Brand} ({myCar.Year}), {myCar.Color}");
// Output: Toyota (2024), Red

After new Car(), a fresh Car object lives in memory. You set its fields using the dot (.) operator.

4. Fields — Storing Data Inside a Class

A field is a variable that lives inside a class. Every object gets its own copy. In the Car example above, Brand, Color, and Year are fields.

We marked them public so code outside the class can read and write them. But this is actually a bad habit — anyone can set Year to -5 and the class can't stop it.

C#
Car car = new Car();
car.Year  = -5;  // No error! But makes no sense.
car.Brand = "";  // Empty brand — also nonsense.

// The class has no way to reject bad values.
// Properties solve this — see next section.

Rule of thumb: use fields only for private internal storage. For anything the outside world needs to access, use properties instead. We'll cover validation in detail in L11.

5. Auto-Properties — The Right Way to Expose Data

A property looks like a field from the outside, but behind the scenes it's a pair of methods: one to get the value and one to set it. This gives the class control over its own data.

The simplest form is an auto-property. C# generates the hidden backing field for you. You just write { get; set; }.

C#
class Student
{
    public string Name { get; set; }
    public int Age { get; set; }
    public double GPA { get; set; }
}

From the outside, student.Name = "Alice" looks identical to using a field. The difference is that later you can add validation logic without changing any code that uses the property. We'll do exactly that in L11.

6. Methods Inside a Class

A class isn't just data — it also has behaviour. Methods inside a class can read and modify the object's own properties. This is what makes objects powerful: data and logic live together.

C#
class Student
{
    public string Name { get; set; }
    public int Age { get; set; }
    public double GPA { get; set; }

    public void PrintInfo()
    {
        Console.WriteLine($"{Name}, age {Age}, GPA: {GPA}");
    }

    public bool IsHonorRoll()
    {
        return GPA >= 3.5;
    }
}

Now you can call student.PrintInfo() and the object prints its own data. You don't pass the name or GPA as arguments — the object already knows them.

Instance method — a method that belongs to an object and can access that object's data. Calling alice.PrintInfo() prints Alice's info, not Bob's — each object has its own copy of the data.

7. Object Initializer Syntax

Setting properties one line at a time gets tedious. C# has a shortcut called object initializer syntax — you set properties right inside the curly braces after new.

C#
// Line-by-line (verbose)
Student s1 = new Student();
s1.Name = "Alice";
s1.Age  = 17;
s1.GPA  = 3.8;

// Object initializer (clean)
Student s2 = new Student
{
    Name = "Bob",
    Age  = 18,
    GPA  = 3.2
};

Both approaches produce the same result. The initializer is just more compact and easier to read, especially when creating many objects.

8. Working with Multiple Objects

Each object is independent. Changing one does not affect another, even though they come from the same class. Think of two cookies from the same cutter — painting one red doesn't change the other.

C#
Student alice = new Student { Name = "Alice", Age = 17, GPA = 3.8 };
Student bob   = new Student { Name = "Bob",   Age = 18, GPA = 3.2 };

alice.PrintInfo();  // Alice, age 17, GPA: 3.8
bob.PrintInfo();    // Bob, age 18, GPA: 3.2

bob.GPA = 3.5;
bob.PrintInfo();    // Bob, age 18, GPA: 3.5
alice.PrintInfo();  // Alice unchanged — still 3.8

You can also store objects in an array and loop through them. This is exactly the power OOP gives you over parallel arrays.

C#
Student[] roster = new Student[]
{
    new Student { Name = "Alice", Age = 17, GPA = 3.8 },
    new Student { Name = "Bob",   Age = 18, GPA = 3.2 },
    new Student { Name = "Carol", Age = 17, GPA = 3.9 }
};

foreach (Student s in roster)
    s.PrintInfo();

Note: Compare this to the procedural version from section 1. Three parallel arrays became one array of Student objects. Adding a new student? Just add one object — no risk of arrays getting out of sync.

💻Code Examples

Complete working examples. Create a Console App project and try each one.

Example A — Dog class with methods

C#
// --- Class definition (below top-level code) ---
class Dog
{
    public string Name  { get; set; }
    public string Breed { get; set; }
    public int    Age   { get; set; }

    public void Bark()
    {
        Console.WriteLine($"{Name} says: Woof!");
    }

    public string GetInfo()
    {
        return $"{Name}{Breed}, {Age} years old";
    }
}

// --- Top-level code ---
Dog d1 = new Dog { Name = "Rex",   Breed = "Labrador", Age = 3 };
Dog d2 = new Dog { Name = "Buddy", Breed = "Beagle",   Age = 5 };

d1.Bark();                        // Rex says: Woof!
Console.WriteLine(d2.GetInfo()); // Buddy — Beagle, 5 years old

Example B — Rectangle with calculated values

C#
class Rectangle
{
    public double Width  { get; set; }
    public double Height { get; set; }

    public double Area()      => Width * Height;
    public double Perimeter() => 2 * (Width + Height);

    public void Print()
    {
        Console.WriteLine($"{Width} x {Height} | Area = {Area()} | Perimeter = {Perimeter()}");
    }
}

Rectangle r = new Rectangle { Width = 5, Height = 3 };
r.Print();  // 5 x 3 | Area = 15 | Perimeter = 16

✏️Practice Tasks

Task 1Book Class
EASY — IN CLASS

Create a Book class with auto-properties: Title (string), Author (string), Pages (int).

Add a method GetSummary() that returns a string like "'1984' by George Orwell — 328 pages".

In the main program, create 2 Book objects using object initializer syntax, call GetSummary() on each, and print the results.

💡 Hint
The method signature is public string GetSummary() — it returns a string, it doesn't print it directly. Use Console.WriteLine(book.GetSummary()) in the main program.
Task 2Bank Account Tracker
MEDIUM — HOMEWORK

Create a BankAccount class with properties: Owner (string) and Balance (decimal).

Add methods:

  • Deposit(decimal amount) — adds to balance, prints new balance
  • Withdraw(decimal amount) — subtracts from balance only if there are enough funds; otherwise prints "Insufficient funds"
  • PrintStatement() — prints owner name and current balance

In the main program, create an account, make 2 deposits, 1 successful withdrawal, and 1 failed withdrawal. Print the statement after each operation.

💡 Hint
In Withdraw, check if (amount > Balance) before subtracting. Use decimal for money — double has floating-point rounding errors that matter when dealing with currency.
Task 3Student Roster
HARD — HOMEWORK

Create a Student class with properties: Name (string), Grade1, Grade2, Grade3 (all int, 0–100).

Add methods:

  • GetAverage() — returns the average of three grades as a double
  • GetLetterGrade() — returns "A" (≥90), "B" (≥75), "C" (≥60), or "F"
  • Print() — prints name, average, and letter grade on one line

In the main program, create an array of 4 students with different grades. Loop through them and call Print(). Then find and print the student with the highest average.

💡 Hint
To find the best student, start with Student best = roster[0]; and loop through the rest: if (s.GetAverage() > best.GetAverage()) best = s;. This is the same max-finding pattern from L07 — but applied to objects instead of plain numbers.

⚠️Common Mistakes

Forgetting new — using a class like a variable

Writing Student alice; declares a variable but does not create an object. Trying to set alice.Name = "Alice" will crash with a NullReferenceException. You must write Student alice = new Student();.

Confusing the class with the object

Writing Student.Name = "Alice" is wrong — Student is the class (the blueprint), not an object. You need an instance first: Student s = new Student(); s.Name = "Alice";.

Putting the class inside top-level code

With top-level statements, your class must be defined after all top-level code, or in a separate file. If you write class Dog { } in the middle of your main code, you'll get a compiler error.

Missing public on properties

Writing string Name { get; set; } without public makes the property private by default — you won't be able to access it from outside the class. Always add public in front.

🎓Instructor Notes

⚡ How to run this lesson (~80 min)

  • [10 min] Start with the analogy before touching the keyboard. Draw a "Student" card on the board with fields (Name, Age, GPA). Ask the room: "If I give you 30 blank copies of this card, what would you do?" They'll say "fill them in" — that's instantiation. Analogy first, syntax second.
  • [15 min] Live code: class → object → fields. Build the Car class from section 2 live. Create two cars. Change one — show that the other doesn't change. When the room goes quiet, ask: "How many Car objects exist in memory right now?"
  • [15 min] Live code: properties + methods. Refactor Car fields into auto-properties. Add a PrintInfo() method. Ask: "Why is it better that the Car prints itself, instead of us printing it from outside?" This plants the seed for encapsulation (covered in L11).
  • [10 min] Object initializer syntax + arrays of objects. Show the shorthand. Then create an array of 3 cars and loop with foreach. Ask: "How would you do this with parallel arrays? How many arrays would you need?"
  • [25 min] Task 1 in class. Walk around while students work. The most common stumble is putting the class definition in the wrong place (inside top-level code). Have the fix ready on the projector.
  • [5 min] Wrap up + assign homework. Preview L11: "Next week we add constructors and learn how to protect object data with encapsulation." Assign Tasks 2 and 3 as homework.

💬 Discussion questions

  • "Can you think of a real-world thing that would be hard to represent with just variables and arrays?"
  • "If two objects come from the same class, are they the same object? Why or why not?"
  • "Why might you want a method to return a value instead of printing directly?"