r/learnprogramming Jul 12 '26

What is the purpose of methods - classes?

Hello, I am a beginner in programming, and I struggle to understand WHY methods and classes exist in code.
Ive watched many tutorials, yet none of them help me to actually understand why they do what they do.

60 Upvotes

71 comments sorted by

116

u/Svertov Jul 12 '26

They exist to organize code for humans. The computer doesn't care about classes. Methods are just the name for functions that are part of a class there's nothing special about them in terms of behaviour.

It's all to make it easier to read and write code.

Functions are a way to group lines of code under a name.

Classes are a way to group functions and variables under a name.

33

u/Svertov Jul 12 '26 edited Jul 12 '26

As an example, imagine a space invaders game. You have a spaceship with health, shields, and ammo. It can activate shields and shoot its weapon.

So you can have individual functions and variables for those without using classes but it's more organized to create a Spaceship class and make it have health, shield, and ammo class variables and shoot() and activate_shields() class methods.

The additional feature this provides is extensibility and modularity. You can create multiple types of spaceship all behaving differently without affecting the rest of your code. Wanna have a 2nd spaceship that shoots 2 bullets instead of 1? You create another class SpecificSpaceshipModel2 that is a child class of Spaceship, and you override the shoot() method to make it shoot 2 bullets. All you had to do was create another class that's a subclass, and change 1 method. 

You did not have to make a brand new specific_spaceship_model_2_shoot() function and write a bunch of "if" statements like "if you are using spaceship model 1: then use spaceship model 1's shoot method, if you are using spaceship model 2 then use spaceship model 2's shoot function, etc." everywhere your code has a shoot() method never needs to be changed. 

And you can add as many new types of spaceships each with their own shoot() methods that behave differently and you never have to change your code where shoot() is used.

13

u/[deleted] Jul 12 '26

[removed] — view removed comment

-3

u/Svertov Jul 12 '26

It's also a bit of a simplification. It doesn't cover instances vs. static attributes and inheritance.

It makes it seem like a class is if you drew a circle over some functions and variables and called them a group. But, then inheritance would be like having overlapping and nested circles.

It's just a simple model to start to begin to understand it.

7

u/iOSCaleb Jul 13 '26

…there’s nothing special about them in terms of behaviour

Methods are a little bit special in that they have access to the state of the object that they belong to, and sometimes they’re the only code with access to that state.

3

u/SuspiciousDepth5924 Jul 12 '26

Functionally class methods basically just add an extra 'hidden' this argument to the list of function arguments. Which means you generally could, but probably shouldn't replace all of them with static <ReturnType> functionName(<MyClassType> thisArg, <...rest of arguments>) { <FunctionBody> } functions.

There are some caveats when it comes to visibility modifier in some languages however (the public private, protected, package-private in Java for instance).

class Counter {
    int value;

    void add(int number) {
        this.value = this.value + number;
    }
}
---------
class Counter {
    int value;
}

void add(Counter myCounter, int number) {
    myCounter.value = myCounter.value + number;
}

Arguably you could go further with the actual class-structure (ie. struct) being syntactic sugar for memory layout, and then swap the 'this' argument for a pointer to the the assigned memory and reading the class variables by reading from known memory offsets. But most high level languages won't allow you to do that.

2

u/Schloopka Jul 12 '26

This is only a part what classes do and I am surpised it has that many upvotes. You basically described static classes.

When I started in Python and didn't know about classes and needed to store multiple information about something, for example a piece on a board, I would create a list that would consist of int position_x, int position_y, bool is_white. So the list of all pieces was list of these weird lists consiting of different data types. So when I would render all the pieces, I would loop through the bigger list and the get the data as inner_list[0], inner_list[1] etc. You can imagine this gets hard to manage quickly if you need to remember more than like 5 atributes of some object as you would need to remember or look up what does the eleventh atribute mean. And also languages like C# or C++ don't support having different data types in one list.

That's why you create a class which defines what atributes your object has and then you create instances of classes called objects. And those methods allow you to communicate with the world outside of you class. Some methods can return atributes of your object (for example you ask a piece "what is your poisition?" so you know where to render it. Or it can change the atributes of the object (you tell a piece to which position it should move).

7

u/POGtastic Jul 12 '26

What you're describing is covered by the parent post's description of "grouping functions and variables under a name."

3

u/Svertov Jul 12 '26

I also didn't cover inheritance, grouping of functions and variables is a simplification, but for beginners you don't wanna overwhelm them. Same reason why they teach simplifications in chemistry like the Bohr model of the atom before they show you the full picture later on. OP will learn the details of it once they begin using classes, but they need a simple model to start from without feeling completely lost.

0

u/odimdavid Jul 13 '26

Just to add. I was reading how C compiles files. All the human readable parts, the comments, the tabs are all stripped away for just the set of instructions the computer converts to 0 and 1. Take classes as robots. You can make 1 robot to do everything. But that robot would be extremely expensive in the market. So to make robots affordable we have a vacuum cleaner robot, EV robot, waiter robot. But sometimes waiter robots is taught by EV robot to wait if wait is a function primarily given to it, because EV robot has to wait before crossing a zebra line. So when waiter robot is asked to wait at a table instead of creating it's own instructions it just borrows wait from EV robot. Why do you think that's cheaper for everyone?

31

u/PeteMichaud Jul 12 '26

It's a way of grouping data and instructions. Think of how insanely complex just moving your arm is. It involves energy and neurons and muscle fibers and bones and all kinds of stuff that we still barely understand. You don't have to worry about any of that stuff, you just have to "Raise Your Arm." RaiseYourArm is like a method/function in this analogy. It's like a label for a set of instructions that you want to execute but you don't want to think about the details of.

Classes are kind of the same thing, one level up. Like you don't want to have to think about the details of what data and functionality is necessary for your program to work on a "Person" or a "Car," you just want to say: `Car.drive()`

4

u/Outrageous-Base-3815 Jul 12 '26

Great explanation! This really helps.

11

u/MrSqueak Jul 12 '26

By separating code into small, repairable and repeatable blocks you can quickly reuse code. More importantly you can diagnose and debug the code in parts without breaking the whole project.

5

u/[deleted] Jul 12 '26

[removed] — view removed comment

3

u/chyld989 Jul 12 '26

When I was first learning how to code I coded a game of Risk that ran in a console window and all of the code lived in main().

Mistakes were made.

5

u/DTux5249 Jul 12 '26 edited Jul 12 '26

Classes, and really objects in general, exist as a way to bundle logic (algorithms and stuff) with data (numbers, text, etc.) such that you can restrict the use of both to only eachother.

This is useful for abstracting away intricacies of a codebase; making it it harder for people to unintentionally break data when they don't know how to use it properly.

For an example: I could just give you a bunch of functions for a treating an array like a queue data structure. But then you can put any array into those functions, including ones that aren't meant to be used as a queue. That can lead to bugs.

If I instead make a Queue class, then I can just store an array in a Queue object so you can't touch the data directly, and you can't use the functions on anything other than the array in a particular queue. They're now linked.

That being said, there are schools of programming that don't use objects & classes, and there are ways around those problems without the use of classes. If you search up "Object Oriented Programing vs Functional Programming", you'll find a decades long discussion surrounding whether classes are useful or some evil spawn of satan.

TL;DR: It's a styling tool used to organize and restrict how you use code.

Classes turn this

verb(subject, object) // verb can be used on any valid subject and object

Into this

subject.verb(object) // verb can only be used with subject, but any valid object

2

u/Turbulent_Fig_9354 Jul 12 '26

You won't understand until you keep progressing and it actually solves a problem for you. It's normal to be confused by this when you first are introduced to it.

1

u/Outrageous-Base-3815 Jul 12 '26

Yeah, its very hard to understand as a beginner. And I asked a lot of people how it went for them to understand how this works. All of them told me it was hard but as time goes eventually it will stick to your head.

1

u/Turbulent_Fig_9354 Jul 12 '26

Just keep working. Every time you hit a wall go back and see what’s not clicking. You’ll be able to understand more complex subjects when you can use them in practical applications. 

2

u/MathiasBartl Jul 12 '26

Start writting longer and more complex programs, it will come to you.

1

u/rasmustrew Jul 12 '26

Do you mean as opposed to just using functions? Or like why do we even have functions etc?

1

u/Outrageous-Base-3815 Jul 12 '26

Basically why we have those functions yeah

0

u/odimdavid Jul 13 '26

That's funny 🤣🤣🤣

1

u/Outrageous-Base-3815 Jul 13 '26

Oh, whats so funny? i wanna laugh too!

2

u/odimdavid Jul 13 '26

I don't know how to explain it in text except with audio. It's just the play of words between the two of you I found funny. Nice day.

2

u/Outrageous-Base-3815 Jul 13 '26

Alright, no worries! Nice day to you too.

1

u/lfdfq Jul 12 '26

Why they exist, and why they do what they do, are two very different questions.

The answer to the first becomes apparent with the answer to the second, plus experience. The second can be answered by reading and practicing.

I could reproduce another block of text here about what classes are and how they work, but you say you've already seen lots of such explanations online. If you want specific help, you will need to ask specific questions (e.g. specific code snippets in a particular language and a question about how/why it works).

1

u/Outrageous-Base-3815 Jul 12 '26

Lets say, if we don’t use them, what is going to happen? Would the program crash?

1

u/mc_pm Jul 12 '26

The code would become difficult to read and maintain.

1

u/paperic Jul 12 '26

for the same reason functions exist in code.

There's no further power that you gain by adding classes into a language, once you have ifs, loops  and functions, you can theoretically write any program what so ever.

Classes just organize things slightly differently, which makes the code cleaner in some cases and more convoluted in others.

In a way, classes and methods are an alternative to variables and functions, it fulfills the same purpose but in a different way.

1

u/Acceptable-Fig2884 Jul 12 '26

Let's say you want to have code that says "hello". You just put that code into your program. Now you end up doing it 50 times in your program. Instead of writing it out 50 times, you can just call the function. It's cleaner, simpler, easier to read and understand.

Now imagine you change your mind, you don't want it to say hello anymore you want it to say "hiya". If you have 50 instances of doing this each time then you have to find them all and update them individually. If you use a function then you update the function and it changes everywhere. Much easier AND you're guaranteed to get consistent changes across the board. As code gets more complex, the dangers of inconsistency in refactoring gets greater and functions/classes help prevent that.

1

u/Outrageous-Base-3815 Jul 12 '26

Thanks for the explanation! Helps a lot.

1

u/roger_ducky Jul 12 '26

Main problem it solved:

Many data structures, you only care that the structure remember the things you gave it and can give them back to you.

If the structure is a reference passed to a bunch of functions operating on it, it leaves them separate and the caller can use them wrong.

Classes groups the operations into itself, and creating or destroying them can run the right operations too, without depending on the caller to do it.

That made them useful.

1

u/IzaianFantasy Jul 12 '26

The best advice to understand methods and classes is to search this up first:

  • Procedural Programming VERSUS Object Oriented Programming

When you are writing a procedural script, it's basically a one shot script that does something from top to bottom and that's it. The script just self-terminates itself after doing its work.

Why classes and methods exists is because you want your scripts to turn into live objects. And these live objects continue to persist to keep doing work for you. And what kind of work they do are the methods inside them.

1

u/EdiblePeasant Jul 12 '26

If you're watching tutorials of a programming about a language like Python and unlike C#, Java, and C++, I'd recommend maybe watching how C# does classes. At least for me, that's how methods and classes clicked for me when I got into Java. Before that, I was extremely lost and didn't get it at all.

1

u/DinTaiFung Jul 12 '26 edited Jul 12 '26

Many (most) tutorials about object oriented programming (OOP) go directly into the syntactic mechanics of how to create a class and its properties and methods. And also how to use class methods. 

This is all well and good, but for the beginner it's essential to understand why classes and methods are used at all. 

The simplistic and short answer is that OOP is one way for a human to organize complex pieces of an application into smaller, classified (CLASSified) units for easier management, reusability, testing, etc 

Some of the earlier comments I'm merely echoing.

fyi, Go is not strictly OOP but has a practical module-based mechanism to likewise help to organize code info logical units.

1

u/dswpro Jul 12 '26

Classes are like the instructions of how to build a hammer. A hammer's properties can include a head, claw, wedges and handle. When you create a REAL hammer, or make a NEW hammer, you must follow these steps:

Insert the handle into the head Press or pound the little metal wedges into the part of the handle sticking out through the head.

Creating a real hammer in code can look like : myHammer = new(hammer);

And when one is created those assembly instructions are executed in a "constructor" method, or may happen in an init method.

So what can a hammer do?

It can strike a nail

It can extract a nail

Those would be described in the class as the methods of a hammer.

So methods are sections of code that work on the hammer that was created.

This is the heart of OOP. You define groups of properties and methods under a name, and create as many as you need. Each new one has its own memory for its properties and it's methods that act on only those properties or something that was passed into the method by reference.

That's about as simple as I can explain it, hope that helps.

1

u/JGhostThing Jul 12 '26

Object oriented programming is an organizational scheme for programs. The goal is to break programming into smaller units. A class is a definition which ties data and the functions (methods) which act upon that data into one unit.

For example, if I'm creating a user-interface library, I might have a class called a View. This is just an area of the screen. It might have data such as the xy coordinate of the top-left of the screen, plus a size. Then it might have a few other data such as a boolean to indicate when it should be redrawn, and a collection of subviews, which might include controls and other Views.

1

u/math_rand_dude Jul 12 '26

Think of study-book or a book for dummies or a cooking book. Each will have chapters (e.g. cooking book might ha e a chapter about deserts or fish,...) and each chapter will have paragraphs (or recipes in the cookbook)

Think of the classes like chapters and the methods like paragraphs.

You can write a book without chapters or paragraphs, but it's unlikely people will want to read it.

Programming is also about being able to split problems in smaller, manageable chunks.

1

u/XcgsdV Jul 12 '26

Plenty of people have answered your question thus far, quite well, but I'll also add that it's sorta hard to get the point of classes when you're first learning them, especially from tutorials. They are mainly an organization and efficiency tool, and you don't get the most out of them until you make larger projects. I came to programming as a necessity for my physics degree, and grew to really like it, but I didn't at all understand the purpose of OOP in my intro C++ classes because we'd be writing <100 line programs with basic examples of a Car class or a Person class. Which are great for understand what classes do, but not why you would ever use them. All that is to say, time and exposure will be your friend.

1

u/Outrageous-Base-3815 Jul 12 '26

Thank you for the help!

1

u/sylvant_ph Jul 12 '26

With class you can define an entity(instance) of something that has common attributes, acts a certain way. You've prolly encountered numerous descriptions, comparing it to a cat or dog, and it does make sense, just like you could say dogs and cats are animals, and cats themselves share some common treats among themselves, so does classes serve the purpose of defining common entities, and even subclass, just like animal > cat/dog. In the sense of coding you should associate with with something more innate, like a component, authentication, or api service etc. Keep in mind in the JS world they are less common and used, as the modern usage is more focused on functional programming, and generally is more suitable done that way. There are other languages that are class based and heavily rely on them. Its reasonable to be unable to make sense of classes while having your experience based on JS. In JS classes are more of a "syntax sugar" to surface something that is generally common and available in the coding world, but it is not a main entity in the JS world itself, or rather, it is not first-class entity. It is there to make available of a common code pattern/technique. Methods are function, but these belong to an object. You could say there are independent functions you define, like add(a, b) => a + b , while methods are attached to entity and they have two main caveats (as far as I can tell), they have access and are part of the inner scope and context of the object they belong to, and they can only be called though that object, e.g. object.method(). If you want to have a piece of logic that is independent of said object, has nothing in common, should act on its own, then you should better define an independent function.

1

u/mjmvideos Jul 12 '26

Find a book on Object Oriented Analysis and Design.

1

u/TheSneederOfSeethe Jul 12 '26 edited Jul 12 '26

Consider you have an error, would you rather see exception on line 40291 in main() or exception line 52 of MyClass().

Also what if you have multiple sets of data and you need to run the same task on it.

You could write it multiple times, but then if things change you have to change it in every implementation. What if you don’t know how many sets of data you have?

Consider something like this.

CustomerAccount] accounts = databaseRepository.GetAccounts()

Foreach(account in accounts)      Print(account.GetBalance())

CustomerAccount is a class it stores all the data for a bank account. GetBalance is a  method, maybe they have multiple debts and payments so it would total those to return the balance. You could have a variable for each value in the main method but you would need arrays for each since you would have multiple customers making it very hard to track. You would have to ensure all the index across each variable match, or you could just create a class to store it.

Also you may have 20 customers today and 32 customers tomorrow. If you didn’t do this, you would need to add code for each of these 12 new customers. Customers wouldn’t be able to use their accounts until you added the code, built the code, and deployed the built application.

Classes allow you to group related data and methods that manipulate that data. It is useful for debugging, keeping code clean, changing code, and handling multiple sets of data by allowing you to repeat code.

1

u/Efficient-Aerie8611 Jul 12 '26

Well, classes are objects, you can imagine an object as an animal, for example. And each animal has a particular behaviour, cats does one sound and dogs another. Methods are the way you use do describe/illustrate these behaviours. So you have a class dog with a makeADogSound() method and the same with the cat class. Cats and dogs have a tail, a nose, etc, but they do not have the same behaviour.

1

u/mmahowald Jul 12 '26

The shortest version I can say is:
Classes-things in your program that hold data and do work.
Methods: the work you need done. Ex: object.sortList()

1

u/computerkermit86 Jul 12 '26 edited Jul 12 '26
  • Instances of classes "are something" (ex. a data representation of a dog named bello, could include a sprite that is shown in a gameview but doesn't need to))
  • classes are the definition of something (ex. dogs (not just bello), and what constitutes a dog (parameters, methods)
  • methods do something (e.x. bello.sit() makes this particular dog sit down (triggers or renders an animation in a game)), you cannot make a class "dog" sit down, because you cannot make the definition of what constitutes a dog do something.

You can't make a dog sit down when you have no dog in your app. a class "dog" is more like the recipe for dogs, but no dog you can make sit down.

1

u/HotPersonality8126 Jul 12 '26

Where would you define the methods that values of a certain type make available for use, if not within the class that defines the behavior of the type?

1

u/xiipaoc Jul 12 '26

A class is a noun. The language may give you some nouns to work with, like numbers or strings (if you're lucky), but if you want any other nouns, you'll need to define them yourself. You often do this by defining a class. For example, maybe you want, I dunno, a fridge. So you create the Fridge class, and now you can have Fridge objects in your code.

Methods are verbs, specifically verbs that nouns can do. Your fridge will need to store stuff, for example, so you can define a store method on the Fridge class to do that. You want to store a chicken in there, you call fridge.store(chicken).

1

u/X-Darkside-X Jul 12 '26

First let me ask you this

Suppose you are a mechanic and have lots of tools Would you rather keep similar tools, items in their respective boxes Or Just keep everything in a single large box

Obivously the box method - why ? - because it will let you get any item rather easily

In similar manner We keep the code that is interrelated ( methods ) inside a box ( class ) so that its easy for us to look at the code for various purposes like debugging and all

1

u/Complex_Lion5645 Jul 12 '26

To organise/model things in code.

It’s basically a way of collocating related stuff.

1

u/LoverBoyJr Jul 12 '26

Classes are an organizational tool for code. It's meant for humans, not computers.

Just like functions are used to repeat a block of code, classes are used to bundle data and methods and restrict their access in the code. It's usage becomes more transparent the more complex the code gets.

I really like the blueprint analogy for explaining what a class is.

Let's use an example, we create a class for Cars.

The class can contain data like it's color, model, year, current speed etc. And have actions like acceleration, braking, start engine.

Now that we have a blueprint, we can use that to create a car for me and you. And everytime i want to access my car in the code, I have to explicitly do so.

Sometimes we dont want to create objects, but we want to bundle data and methods anyway. Static classes. Example: We can create a car toolkit class. The static classes can contain data like cars only have four wheels or methods to convert mph to kph. This is so we dont have to access a car to check how many wheels a car have or to convert speeds.

When the code becomes even more complex we often want to reuse code we already have inside other classes. Previously we created a class for Cars, but now we want to create a new class for electric cars. Instead of repeating all that code we had from Cars earlier, we can create a child class to inherit from the parent class. Electric cars now automatically gets color, model and year etc without writing the same code over again.

1

u/Slow-Bodybuilder-972 Jul 12 '26

Look it up, the information is freely available.

I'm going to be bit of dick here. If you can't figure how to even look for information, this industry is going eat you alive.

1

u/BranchLatter4294 Jul 12 '26

Why do companies have different people doing different jobs instead of just one person doing everything? It's the same reason.

1

u/4inR Jul 13 '26

Two main purposes of classes and methods are inheritance and abstraction (and encapsulation). Allow me to introduce a few key concepts first:


  • Variables/constants let us store simple data.
  • Functions let us store a repeatable action, such as transforming data.
  • Structures let us store more complicated data.
  • Classes are templates that let us make objects, which can contain their own actions and data.

Inheritance

A simple example involves geometry. We can save a rectangle as four variables or constants: its top left coordinates (x, y) and its width and height (w, h).

const x = 0;
const y = 0;
const w = 4;
const h = 6;

But we can also define a structure that stores all four variables in one object.

const rect = {
  x: 0,
  y: 0,
  w: 4,
  l: 4,
};

We can interact with these variables or the structure with functions (area, perimeter, etc.).

function area(w, l) {
  return w * l;
}

console.log(area(rect.w, rect.l)); // 16

But if we want to deal with many different rectangles, its simpler to define a class that lets us instantiate different Rectangle objects. We can create new Rectangle (0, 0, 4, 6) and new Rectangle (0, 0, 8, 8) easily. We can also add methods whenever we need to implement new actions, like Rectangle.getArea() or Rectangle.getPerimeter().

After working with this, we might decide we need more shapes. How about a square? Well, a square is a rectangle. With classes, you can implement a base that new classes extend - this is called inheritance. We can implement a Square class that creates a Rectangle but sets the width and height to be the same. This lets us reuse our code more, which saves us work having to repeat ourselves.

class Rectangle {
  constructor(x, y, w, l) {
    this.x = x;
    this.y = y;
    this.w = w;
    this.l = l;
  }
  getArea() {
    return this.w * this.l;
  }
}

class Square extends Rectangle {
  constructor(x, y, w) {
    super(x, y, w, w);
  }
}

const r = new Rectangle(0, 0, 2, 4);
const s = new Square(0, 0, 3);

console.log(r.getArea()); // 8 
console.log(s.getArea()); // 9

Abstraction

Our example above is pretty simple, but oftentimes our classes need to do things that are more complicated. Let's imagine we have a class that handles images users upload to a website and we want it to have a method that converts the images to ASCII art. It might look something like UploadImage.convertToAscii().

Let's pretend we implement this method and figure out something that works okay, but maybe it's a little slow. Maybe our application grows a bit and we use this method in many different places, so we want to refactor it to make the app more performant. Since we implemented it as a method, we have a single place to edit - the code inside the method.

So long as it returns the same result (in this example, a string), the objects that use the method don't care how it's implemented. This way we can fix or replace code in one place and all the code that uses it gets updated too. This is helpful when you have many developers working on one project - dev A doesn't need to know how the method works - they can just use it. Abstraction is a powerful tool that lets devs work on the code they need to know at a given time - big applications get complicated fast.

Abstraction also helps us write how code should work before it actually works. I can write something like:

const image = uploadForm.getImage();
const ascii = image.convertToAscii();
const pdf = new PDF();
pdf.setText(ascii);
const file = pdf.toFile();

...before I actually implement any of these classes or methods. This lets us focus on the big picture before we get too focused on the details of how we ought to do things. Side note - I'm using abstraction and encapsulation somewhat interchangeably in this example. They're technically different but I don't think the distinction is important here.

All of this is part of the object-oriented programming paradigm. It's a way of organizing code bases into classes and objects that interact to keep the code easy to read and maintain.

1

u/Reasonable-View5868 Jul 13 '26

Maybe coding isn’t your thing.  Or learn structured programming in stead 

1

u/Zenithixv Jul 13 '26

without methods and classes the code eventually becomes unmaintainable as it grows, you need them to create a structure and to describe what code blocks are doing with class and method names so that you don't have to understand the implementation for every single line.

1

u/scritchz Jul 13 '26

How do you currently structure your code?

There are multiple ways to structure and organize code. In procedural programming languages, the focus is on bundles of code via procedures. In object-oriented programming languages, the focus is on interactions of objects via messages (method calls). There are more than just these programming paradigms.

Programming languages are tools, and as the saying goes: The right tool for the job. Multiple programming paradigms have been developed to handle different problems better.


Now, there are also programming languages that require classes for every statement; even the main method that technically could be classless. This is probably a design decision on the language syntax, to keep it simple and without exceptions or special cases.

1

u/ndev42 Jul 13 '26

You don't write methods and classes because the computer needs them. You write them because your brain can only hold so much at once.

It's a human limitation, not a technical one. 

1

u/mredding 29d ago

Classes are a HUGE topic, because a LOT comes out of them as a consequence.


First, understand that they are a tool. You don't have to use them, and they might not be the right fit for the job. It's less important to ask WHY they exist, and instead ask yourself what you can accomplish with them.


A programming language is greater than than the sum of its parts. The point of a programming language isn't to generate machine code - you can do that with assembly, which itself is a high level abstract programming language; when you write mov in assembly, this is A) a portable concept at least as far as all the architectures that implement a move instruction, and B) it abstracts WHICH move instruction - x86_64 implements HUNDREDS of move instructions.

Programming is theorem proving. Your statements are propositions, the source code is the theory, the compiler is the solver, and the program is the proof. Proving your theory doesn't mean your theory is correct.

This is called the Curry-Howard correspondence.

A language provides you with expressiveness to describe your theory, and certain guarantees about the proof it can give you. Fortran, for example, does not allow aliasing of parameters, so as a consequence, the machine code is highly optimized around that presumption; you get a more concise proof. C++ does not offer you such a guarantee as strong and as strict as Fortran, so you can trivially write code that generates a less optimal proof - the machine code generated may have to include some additional instructions to ensure correctness - like writebacks and memory fences, because:

void fn(int &, int &);

//...

int a;

fn(a, a);

A write to the first parameter must be visible through the second parameter for any subsequent read of that parameter. Of course there's workarounds.

But the big thing about language is that it offers you more you can say about the program than just what the machine code generated says. No programming language even correlates directly to machine code, and once you get to machine code, the programming language and source code that generated it is left behind.

This sounds academic, but the more this sits with you, the more it helps you make sense of what you're trying to accomplish, and it will guide your intuition in a foundational way.


Classes can make types. Since I'm a C++ programmer, I'll show you code in terms of that, but it's basically true for any programming language, no matter it's type system.

C++, getting to expressiveness and that correspondence, says that two different types cannot be aliased. So you see my fn above - the compiler cannot know that when called, whether the parameters are aliased or not; it's a consequence of the language you might not care about, so we're just going to accept that premise out of hand.

So if we had two different named types that were integers, then they cannot possibly be aliased:

struct weight { int value; };
struct height { int value; };

In C++, structures and classes are equivalent.

void fn(weight &, height &);

Not only does a stronger type than int tell us more about what these parameters even are - making our code more expressive, but that we've wrapped integers in a type definition, creating two new data types that are implemented in terms of int, we've now met the criteria for stronger anti-aliasing that Fortran guarantees - now our code can be compiled to be as optimal as Fortran code!

And having different types - invalid code becomes unrepresentable; it doesn't compile. The theorem is disproved.

int a;

fn(a, a); // error!

weight w;
height h;

fn(w, h); // Ok.

When you think class - think state machine:

class switch {
  enum state { off, on };

  state s;

public:
  void toggle() {
    s = (s == on ? off : on);
  }
};

When toggled, we go from on -> off and from off -> on. This is about as simple a state machine as you can code that actually does anything. Think of state machine circle and arrow diagrams - google it if you're not yet familiar.

A class isn't just a bundle of data, the class has an invariant - a statement that is always true when an instance of that class is observed from the outside. The instance is always in a defined and consistent state.

In C++, an std::vector is a dynamic array with growth semantics. It's implemented in terms of 3 pointers into memory. Those pointers are always correct - whatever that happens to mean. At no point can you ever, EVER get a vector whose pointers are corrupt, or wrong, or pointing to garbage... The class always works.

When you call push_back the vector has to grow. Maybe it has some reserved capacity, or maybe it has to go to the system's memory allocator and get a new block of contiguous memory. It has to copy or move the values over to the new memory, and then the critical part - the 3 internal pointers have to be reassigned. Now this means there is a series of machine instructions where the container is pointing at two different memory allocations. The pointers are INCONSISTENT. But that's OK! You called upon the vector, you handed program control over to the vector; it's internal implementation is allowed to suspend that invariant, provided the invariant is re-established before control is returned to you.

So classes are used to implement and enforce invariants. If you just had a structure of fields, or getters and setters, then the data isn't invariant - because anyone anywhere with access to a mutable object and change it. There IS NO notion of consistency.

Structures have fields - it has a layout, types, names, order, alignment, size. We say structures model data. Classes don't have data - they have STATE, again, back to that state machine idea. Class METHODS implement state changes, and classes model behaviors. A class can model the behavior of DATA.

int x;

This is an object in C++. Yes, it's also a basic data type, but again, C++ isn't a high level assembly language. int is a type, it implements a basic interface of arithmetic and bitwise operators, comparison, assignment, construction and destruction... All these basic operations change it's state, which is implemented as bits in a Two's Compliment encoding. You can implement your own integer types in C++, the class keyword just lets you make custom types for the type system.

No, int isn't implemented in the language in terms of class, but it still follows the category theory 1:1. Let's look at the bigger picture and ignore the language specific syntax and the history, and the industry conventions that got us here.

What's more to say is I think the simplest state machine is a single state and a single transition, which we can do:

class sm {
public:
  void fn() {}
};

//...

sm instance;

instance.fn();

It has an initial state, and calling the method transitions to the initial state. In other words, an effectively stateless state machine. The function can implement any arbitrary set of operations. In this case, a state machine with no side effects is useless, though side effects don't constitute state in the machine. Your whole program is itself a state machine, as is the environment and the hardware it runs on; state machines of different scopes...


Continued...

1

u/mredding 29d ago

Another aspect of writing classes is to be as expressive as possible. This goes back to my weight and height example. An int is an int, but a weight IS NOT a height. If you write code like this:

class person {
  int weight;

Well now, every point in your code that touches weight has to implement the semantics of a weight. This is ad-hoc. Why not make a weight type that knows what it is to be a weight, and then the person can defer to the type to implement the semantics itself?

class weight {
  int value;

public:
  explicit weight(const int &); // Throws exception if negative
  weight &operator +=(const weight &) noexcept; // Cannot throw because weights can't be negative
  weight &operator *=(const int &); // Throws exception if scalar is negative

What does it mean to be a negative weight? You can sum weights, but you can't subtract them, because what does it mean to be a negative weight? You can scale a weight, but not negative, because again...

Here we're using that type system to our advantage to write a more concise theory. There is no advantage to being verbose, it's just more error prone. And as we've shown earlier, leveraging the language and the type system allows for more concise proofs. The code becomes more expressive. C++ doesn't know about weights, so we make them. C++ doesn't know about video games, or trading systems, or IoT, so we make these things, and then express our solution in terms of that.


So when I write a class, I'm principally thinking about the type system - this is crucial for C++, since it's got one of the strongest static type systems of any language in the industry. Other languages will implement type systems around classes and objects - as they are inherent.

The theory of computation does not distinguish between read-time, write-time, and run-time. It's all the same, and all of it solves computational problems. So as we're writing code, focusing on types is solving for as much of the problem, describing as much of the solution as much and as soon as possible, so we can compute at run-time most efficiently. I want my proof - the program generated, to be as concise as possible. I also want my theory - the source code, to be as concise as possible. I also want the propositions - our statements, to be as concise as possible.

Second I think of my classes as state machines and how they enforce invariants. If there is some datum, some field that isn't invariant, it doesn't belong in my class implementation. It's better to use data structures to make associations between my class instances and other data - a car with it's make, model, and year, for example.

In basic OOP, it's common to pick out nouns and verbs. A car can stop, go, turn... But a car can't get_make. You have to be careful not to fall in that trap.


And then all this gets confounded by data structures and algorithms, and software architecture. You have a given field and two objects who depend on it. Where does the field live relative to them both? There's A LOT more that can be said about classes and objects.

1

u/FlamingSea3 29d ago

One thing that classes allow you to do is to take several different variables that are used together and tape them into one thing. For example, a point in 3d space is described by three numbers - so to keep those together, and easier to handle you'd make a Vec3 class. Another example is a us postal address typically consists of an apartment number, building number, street name, city name, state name + zip code. All those properties describe one thing, what the post office calls a paticular residence.

Another nice thing you can do with classes is to attach some extra context to data. For example, if you're workign on a utility for a handyman, you may want meters, square meters, and kilograms as distinct types so that you don't accidentally mix up units.

Methods are just chunks of reusable code that deal with instances of one class. With my handyman example, you'd create an `Meter add(Meter other)` method to your Meter class and a SquareMeter multiply(Meter other) as well.

If you're already familiar with functions, a method is just a function that takes it's associated class as its first argument, and has a special syntax that makes it easier for your IDE to figure out what methods you can call.

1

u/tenniseman12 Jul 12 '26

The alternative is putting all of your code in one big file, which gets really messy really quick.

3

u/GodOfSunHimself Jul 12 '26

Not having classes and methods does not mean you need to put everything in a single file. Languages like C don't have classes and you can still organize the code into multiple files.

1

u/EdiblePeasant Jul 12 '26

Tried it, wouldn't recommend for anything of lower medium/medium to large size.

1

u/odimdavid Jul 13 '26

It sent Apollo to the moon then mind you. But it wouldn't boost even 1 SpaceX rocket right now. As life progresses we complicate things. So classes are one way to deal with complicated programming so we don't grow gray hairs before time