Post

Object-Oriented Programming: A New Way to Think in Code

Object-Oriented Programming: A New Way to Think in Code

After spending the first part of the semester writing Python in a fairly linear, step-by-step style, moving into C# and object-oriented programming felt like being handed a completely different toolbox, even though the underlying logic variables, conditions, loops was already familiar. The new piece was the idea of organizing code around objects: bundles of data and behavior modeled after real things, rather than just a sequence of instructions running from top to bottom.

The first concept to really land was the distinction between a class and an object. A class, I eventually understood, is closer to a blueprint — a description of what something should have and what it should be able to do while an object is an actual instance built from that blueprint, with its own specific values. Writing a small Student class made this distinction concrete for the first time.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
using System;

class Student
{
    public string name;
    public int age;

    public void display()
    {
        Console.WriteLine("Name: " + name);
        Console.WriteLine("Age: " + age);
    }
}

class Program
{
    static void Main()
    {
        Student s1 = new Student();
        s1.name = "Anas";
        s1.age = 20;

        s1.display();
    }
}

On paper this looks almost identical in complexity to something I could have written in Python with a dictionary and a function. What changed my thinking was realizing that the Student class is reusable in a way a one-off dictionary is not. I could create a second student, a third, a hundred, each with their own name and age, all built from the exact same blueprint, all able to call the same display method without me rewriting a single line of logic for each one. That reusability is the entire point of organizing code this way, and it only became obvious once I actually tried creating more than one object from the same class.

C# itself also demanded a different kind of discipline compared to Python. Every variable needed an explicit type, every class needed to be properly closed and structured, and the compiler was far less forgiving about small mistakes than Python’s interpreter had been. At first this felt like unnecessary strictness, but working through several compiler errors made me appreciate it differently the compiler was catching mistakes before the program ever ran, rather than letting a small inconsistency slip through silently and cause a confusing bug later. That trade-off between flexibility and safety is something I had read about in theory before this course, but only really understood after experiencing both styles back to back in the same semester.

Methods inside a class were another idea that took a moment to fully click. Writing display() as part of the Student class, rather than as a separate standalone function that takes a student as a parameter, reframed how I thought about behavior in code. The ability to “display itself” belongs to the student, conceptually, rather than being something external done to it. That small shift in framing behavior belonging to the data it operates on, instead of living separately from it is, as far as I understand at this stage, the core idea that the rest of object-oriented programming, including concepts like inheritance and encapsulation that we only briefly touched on, builds upon.

Comparing this experience back to Programming Fundamentals, I noticed that the logical thinking skills built earlier in the semester transferred over almost completely. Conditionals, loops, and functions worked the same way conceptually inside a C# class as they had in a Python script; what was genuinely new was the organizational layer wrapped around them. Learning that layer felt less like starting over and more like adding a new dimension to skills I already had, which made the transition smoother than I expected when I first saw the unfamiliar class and public keywords on the screen.

By the end of this part of the semester, writing a small class with a few attributes and a method felt natural rather than intimidating. More importantly, I started noticing object-oriented patterns in tools and frameworks I had casually used before without understanding why they were structured the way they were. That kind of retroactive understanding finally seeing the reasoning behind something I had taken for granted is, for me, one of the clearest signs that a concept has actually been learned rather than just memorized for an assignment.

I also found myself revisiting earlier Python assignments with this new object-oriented lens, almost out of curiosity rather than necessity. Looking back at the discount calculator program from Programming Fundamentals, I started imagining how it might look as a class instead of a single function a Customer object holding name and age, with a method that calculated its own discount based on its own attributes. I never actually rebuilt that program in C#, but the mental exercise of reimagining old, already-working code through a new structural lens was its own kind of useful practice, reinforcing the idea that object-oriented thinking is a way of organizing logic that exists independently of any one language.

The strictness of C# also taught me something about reading documentation more carefully than I had needed to with Python. Looking up how to properly define an access modifier, or what the difference between a public and private member actually meant in practice, forced me to slow down and read official explanations rather than guessing based on what felt intuitive. That habit of consulting documentation deliberately, instead of relying purely on trial and error, is a small but genuinely useful shift, and one I suspect will matter even more once I start working with larger, less forgiving codebases in future semesters.

Looking back at this part of the semester as a whole, object-oriented programming did not replace anything I had already learned in Programming Fundamentals it gave that earlier knowledge a new shape to live inside. The logic itself, the conditions and loops and step-by-step thinking, stayed exactly the same. What changed was the container around that logic, and learning to see code in terms of objects rather than just sequences of instructions feels, even at this early stage, like one of the more permanent shifts in how I think about writing software, one I expect to notice again every time I open a new, unfamiliar codebase from now on.

This post is licensed under CC BY 4.0 by the author.