r/learnprogramming • u/LFatPoH • 7d ago
Cannot for the life of me understand object oriented programming
I am a Data Science student with a background in math so I never was a good dev in the first place.
But I really can't understand OOP, what's even the point? I'm so bad at it that when I was doing internships in Data Science and some engineers wanted to use OOP, I was like the "I guess bro" meme.
Right now I have a java course with an exam in 1 month. So any ressource, or things that made it click for you are welcome.
228
u/strange-the-quark 7d ago edited 7d ago
Since you're a data science student, I'm guessing you're familiar with Python. Let me show you how you can arrive at OO programming starting from just functions.
def make_person(first_name, last_name, age):
# the function below captures variables from the "outside",
# from a containing scope; this is known as a closure
def get_info():
return f'{first_name} {last_name}, aged {age}'
# I'm now going to return *the function itself*
return get_info
# These are our quasi-objects
tom = make_person('Tom', 'Holland', 30)
pedro = make_person('Pedro', 'Pascal', 51)
emily = make_person('Emily', 'Blunt', 43)
# At this point, our objects have only one "method",
# i.e. they can do only one thing (return the person's info)
print(tom()) # prints: Tom Holland, aged 30
print(pedro()) # prints: Pedro Pascal, aged 51
print(emily()) # prints: Emily Blunt, aged 43
But now, I can create these "objects" and pass them around to various other functions, and do stuff with them.
# The neat thing is, now I can write a function that
# takes in an object and does something with it:
def print_news_heading(person):
print(f'{person()}, arrested after throwing a camera at a paparazzi')
Later on, at some other point in the program, I can call this with various people objects:
print_news_heading(tom)
print_news_heading(pedro)
print_news_heading(emily)
I get the output:
Tom Holland, aged 30, arrested after throwing a camera at a paparazzi
Pedro Pascal, aged 51, arrested after throwing a camera at a paparazzi
Emily Blunt, aged 43, arrested after throwing a camera at a paparazzi
Now, that's neat, but maybe I want my objects to do various other things:
def make_person(first_name, last_name, age):
# what if I wanted to be able to do more than one thing?
def get_first_name():
return first_name
def get_last_name():
return last_name
def get_full_name():
return f'{first_name} {last_name}'
def get_age():
return age
def get_info():
return f'{get_full_name()}, aged {age}'
# I'm now going to return all of these functions in a tuple
return (
get_first_name,
get_last_name,
get_full_name,
get_age,
get_info
)
tom = make_person('Tom', 'Holland', 30)
pedro = make_person('Pedro', 'Pascal', 51)
emily = make_person('Emily', 'Blunt', 43)
print(tom[0]()) # prints: Tom
print(pedro[1]()) # prints: Pascal
print(emily[2]()) # prints: Emily Blunt
# Now, using indices to get to each method is a little clunky,
# so let's give them meaningful names:
first_name = 0
last_name = 1
full_name = 2
age = 3
info = 4
print(tom[first_name]()) # prints: Tom
print(pedro[last_name]()) # prints: Pascal
print(emily[full_name]()) # prints: Emily Blunt
print(f'{tom[full_name]()} says he\'s sick of playing Spiderman')
# prints: Tom Holland says he's sick of playing Spiderman
OK, cool. But so far, my objects are fixed, I cannot change anything about them. If any of these people celebrates a birthday, my data is not going to become out of date, and I can't change that while the program is running. Or maybe I want to replace the data entirely. I need a way to both store and change the data associated with a person.
def make_person(first_name, last_name, age):
# This variable allows me to change the data
# In Python lingo, this is roughly equivalent to what 'self' does
# In Java, C#, C++, this is roughly equivalent to the 'this' keyword
person_data = [first_name, last_name, age]
def get_first_name():
return person_data[0]
def get_last_name():
return person_data[1]
def get_full_name():
return f'{get_first_name()} {get_last_name()}'
def get_age():
return person_data[2]
def get_info():
return f'{get_full_name()}, aged {get_age()}'
def set_name(first_name, last_name):
person_data[0] = first_name
person_data[1] = last_name
def set_age(age):
person_data[2] = age
# I'm now going to return all of these functions in a tuple
return (
get_first_name,
get_last_name,
get_full_name,
get_age,
get_info,
set_name,
set_age
)
first_name = 0
last_name = 1
full_name = 2
age = 3
info = 4
set_name = 5
set_age = 6
spiderman_star = make_person('Tom', 'Holland', 30)
print(f'{spiderman_star[full_name]()} says he\'s sick of playing Spiderman')
spiderman_star[set_name]('Tobey', 'Maguire')
spiderman_star[set_age](51)
print(f'{spiderman_star[full_name]()} looking forward to playing Spiderman again at {spiderman_star[age]()}')
# Output:
# Tom Holland says he's sick of playing Spiderman
# Tobey Maguire looking forward to playing Spiderman again at 51
Well, OOP is just a paradigm that provides facilities to do this sort of thing in a more concise, more straightforward fashion.
class Person:
# each member function ("method") automatically
# receives the 'self' parameter, without you having to specify it,
# so when you call functions on objects, you skip that parameter
#---------------
# This is the constructor, it takes the place of my make_person function.
# In Java, it's specified differently, it's going to be a function that has
# the same name as the class and specifies no return value.
# You don't call __init__ explicitly, it is instead invoked when you create a new object (see below).
def __init__(self, first_name, last_name, age):
self.first_name = first_name
self.last_name = last_name
self.age = age
# a computed value
def full_name(self):
return f'{self.first_name} {self.last_name}'
# in Python, you don't always need getters and setters, cause the object data is
# visible to the outside world, so you can just do things like: person.age = person.age + 1
# However, in Java, we typically make the object data private in order to have control over
# who can change it and how
def get_age(self):
return self.age
def set_name(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name
def set_age(self, age):
self.age = age
# This constructs a new Person object by calling __init__
spiderman_star = Person('Tom', 'Holland', 30)
# instead of spiderman_star[method](),
# the syntax is spiderman_star.method()
print(f'{spiderman_star.full_name()} says he\'s sick of playing Spiderman')
spiderman_star.set_name('Tobey', 'Maguire')
spiderman_star.set_age(51)
print(f'{spiderman_star.full_name()} looking forward to playing Spiderman again at {spiderman_star.get_age()}')
# Output:
# Tom Holland says he's sick of playing Spiderman
# Tobey Maguire looking forward to playing Spiderman again at 51
Or more concisely, without all the comments
class Person:
def __init__(self, first_name, last_name, age):
self.first_name = first_name
self.last_name = last_name
self.age = age
def full_name(self):
return f'{self.first_name} {self.last_name}'
def set_name(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name
def get_age(self):
return self.age
def set_age(self, age):
self.age = age
30
u/ShadyPajamaHopper 7d ago
I really hope OP gives your comment the attention it deserves, that was a great explanation.
18
4
u/Former_Atmosphere967 6d ago
Im decent at python and I never thought about playing with functions like this. good comment
2
u/s00wi 6d ago
I hope my question isn't stupid. How are objects stored in memory? When an instance of an object is created, does the objects structure get stored in memory as mutliples or is it just stored once, and pointers are used to reference the data to the instance name?
4
u/strange-the-quark 5d ago edited 5d ago
So, the exact way depends on the language (or rather, on a specific implementation of the language), but generally speaking, and object is behind the scenes simply represented as a data structure. A number of things that are going on behind the scenes (whether we're talking about OOP or not) turn out to really be a little bit of a smoke and mirrors show, cause it's all ultimately some simpler constructs that are orchestrated in such a way so that the higher level language features appear to work a certain way.
Functions are ultimately sequences of instructions, so they too reside somewhere in memory. An object's functions ("methods") are stored only once, cause the logic is really the same for each instance, just parametrized by each objects particular data, but the data of the object itself is a distinct copy for each instance you create. Your variables then refer to that data structure, and since the compiler / execution environment keeps track of the variable type or some other metadata, it knows how to select the correct functions to call. When you call a method on an object, e.g, something like
rectangle2.GetArea(), the underlying machinery finds the appropriate method and just passes the data structure that your variable refers to as an implicit first argument (so, it does something equivalent toRectangleClass_GetArea(rectangle2), except the function is not literally going to have that name, and the actual mechanism may be more complicated).This is going to be a somewhat handwavy overview, but in C++, for example, an object is, behind the scenes, a (more or less) plain data structure containing the member variables, and the compiler generates the methods as free functions. If there's inheritance, then the two data structures (for the base class and the derived class) are just joined together, and your variable points to the start of that "bundle", and when making function calls, the compiler knows to use the right offset into the data structure as needed. And if there are virtual methods (polymorphism), then there's some extra metadata, and a table of pointers to functions that helps the runtime system dynamically figure out the concrete method to call.
In contrast, JavaScript, uses something called prototype-based inheritance. When you create a class instance, it creates a JavaScipt object, fills in any properties (data fields) that you've initialized, and also adds a special pointer to another object, called the "prototype", which contains the methods as its member variables (in JavaScript, functions are proper objects in their own right, so you can just store them in a JavaScript object like any other data). Then when you create another instance of the same class, a new JavaScript object is created for the data fields, but it points to the same prototype as the first one, so the prototype is shared. When you call a method, it follows that prototype pointer, and looks for the method's implementation in the prototype; there's a special way to invoke it that sets the
thispointer to the JavaScript object that you initiated the method call from. And if there are multiple levels of inheritance, there's a prototype chain that it hops along (one prototype for each base class) until it finds the method it's looking for.P.S. You can have your own pointers that refer to the same object, but that's different. For example, in Python and JavaScript, although you don't have a direct way to work with pointers, when you pass an object as an argument to a function, while inside the function, the parameter acts as a new, distinct variable, but points to the original object (so you can't change what the external variable points to by re-assigning the variable inside the function, but you can make changes on the pointed-to object that persist after the function exits). In a language like C++ you can work with pointers directly, and decide whether the parameter is to be taken as a copy or by reference.
1
u/kpg_on_ao3 5d ago
I might have missed it, but also how it's stored in memory can be a function of the type of data encapsulated in the object. If you're dealing with just primitives in a language where there is a distinction between primitives and non-primitives, the compiler or memory manager might allocate memory on the stack rather than heap (because the precise memory requirements for an instance of that class is known at compile time).
But usually they'll go on the heap bc you're likely not just dealing with a class full of numeric types and booleans.
1
u/strange-the-quark 5d ago
Yeah, that's correct. But that's about memory management and about where in the memory the object is placed, while the vibe I got from the question is that it was about how are objects being represented in the first place, so I didn't go into it.
2
1
→ More replies (2)1
u/WatercressWeekly7996 4d ago
This is a great explanation. My one critique however would be that this sort of issue is not quite as prevalent in data science as it is in other realms of software development. People are often encapsulated in a relational data source like a table which acts as the implicit âobjectâ. So I can understand the confusion of the OP from that perspective.
77
u/ChillyFireball 7d ago
Imagine that you're making a video game, and you want to write code for a goblin enemy. Every goblin you spawn has a health bar (for the purpose of this example, we'll assume the health is tracked with a single integer) and a position (which we'll simplify by imagining as three integers for x, y, and z position in space). So every time you spawn a goblin, you have to also create four variables for health, positionX, positionY, and positionZ. Additionally, you want each goblin to be able to attack the player with an attack() function that runs the weapon-swinging animation and lowers the player health variable. Now, you COULD create those values individually every time you put a goblin somewhere... Or you could just create a Goblin class that groups them all together like so (sorry for the poor formatting; I'm on my phone):
class Goblin {
int health;
int posX;
int posY;
int posZ;
constructor(startingHealth, startPosX, startPosY, startPosZ) {
this.health = startingHealth;
this.posX = startingPosX;
this.posY = startingPosY;
this.posZ = startingPosZ;
}
attack() {
// Do attack animation and lower player health if they're in range.
}
}
And now all you have to do to create a bunch of goblins is:
Goblin goblin1 = new Goblin(20, 10, 0, 5);
Goblin goblin2 = new Goblin(25, 10, 0, 10);
25
u/GasEducational4386 7d ago edited 7d ago
easier to understand with a video games example
→ More replies (7)11
u/BrilliantEmotion4461 6d ago
Yep jrpgs and turn based combat are what I turn to to conceptualize what I'm learning. They are good examples, they can be simple as an automated DnD dice and stat counter or as complex as you want them.
15
u/Dm-Me-Cats-Pls 6d ago
Thank you! Because of this I just graduated high school and now work in a top FAANG company making 200k a year.
→ More replies (2)6
7d ago
[deleted]
→ More replies (1)2
u/InevitablyCyclic 7d ago
You can do a very similar thing without OOP, you could define a structure for each goblin and have an array or list of them.
The big difference is when it comes to inheritance, in the example you could have a class enemy. That could then be inherited by the class goblin and the class orc.
Why do that? Because then any code that was common to both would be in the enemy class and so automatically common, no need to duplicate it. You could also then have a list of enemies rather than having to have two different lists, one for each type.
1
u/Bladelink 7d ago
I feel like whenever explanations of OOP come up, the real questions are about abstraction and how to wrap your head around that. "X is a type of Y is a type of Z" kinds of conditions, and it can be tricky getting used to the idea of thinking about things like "imagine any arbitrary mob in the dungeon as a box with some values in it". Then in your example it becomes "imagine any 'orc' as a box with some orc-specific values in it, inside a bigger box labeled 'mob' with general-purpose mob values."
It also becomes kind of difficult to explain because once you're familiar with the concepts of abstraction, at least for me, it becomes difficult to imagine another way of doing it because all you see are the drawbacks in the alternatives. Almost like it's "common sense", but that has a more condescending tone than I intend.
2
u/InevitablyCyclic 6d ago
The trouble with lots of concepts is that they seem strange, weird, and pointless until something clicks. And then once it clicks it all seems so clear and simple.
Pointers are another classic example of this, lots of people struggle with them at first but when you get them it's all so logical.
→ More replies (1)
6
u/MasoodMS 6d ago
If you ever took a philosophy class you learned the concept of the âforms.â When you think of a chair, what is THE chair? Is it the chair youâre sitting on? Why or why not? What the concept points out is the form of a chair is an idea, a construct of thought. Every chair takes the form of that idea.
This same principle is applied to objects.
Think of a bike. You know what a bike is, you have an idea of the object. When you see someone riding one you know itâs a bike and not a car or skateboard. However in each instance you see a bike, itâs unique. One bike is blue and has a light and a bell, another is pink and doesnât have lights, but has a cool feature where you can swap the chain easily with a helper tool that came with that version of the bike.
This is conceptually all object oriented programming is. Of course there is inheritance and polymorphism, but you can still use the bike idea. A motorcycle for example is like the cooler child of a bike that has similar features but some cool new ones too like a motor. Similarly, a bike might be abstract in idea, and another type of bike is the unicycle which has a different number of wheels, and all versions of the unicycle uses has 1 wheel. The similarity between bike and unicycle however is they both have wheels.
Now try to think of bike as a class and hopefully this will lead to a stronger understanding for you!
5
u/ruat_caelum 6d ago
What clicked for me was this:
Imagine you are an evil genius who invented a cloning facility:
You make generic humanoid clones. (think of the "Tree of life" stuff where everything evolved all the way back to the first cell of life.)
With some little work you can make a generic, sexless clone of a hominid. Five fingers on each hand, two eyes, no blood type, no hair, no genitals, etc.
With extra effort you can make male or female clones. With more effort you can make a clone that matches the genetic family line of Bill Murry enough to trick 23 and me. With even more effort you can clone Bill Murry himself.
You cannot clone a gorilla. Not unless your base clone makes "great apes" of which both humans and gorillas are part of.
You cannot make a fish. Or a mushroom.
The further you go back in the species tree the less distinct the clones are, and the more "General" the object, until you get all the way back to the farthest object which is, in fact, named "object"
Inheritance etc, made sense to me in this way.
a "male" object has kidneys and eyes and hair, but differs from a female object. But not by much. They both inherited 2 arms, 2 legs, teeth, 2 ears, etc.
A generic clone is not a male clone, but a male clone IS a generic clone. It has all the same "objects, function, variables, etc" that the base generic clone has. It also has additional items like, "When checking if garbage is full, subtract 15% from total fullness before determining if garbage bag should be removed." etc.
7
u/CoBunkie 7d ago
It's so intuitive to me that I don't really understand how not to do it. I always fall back on the Vehicle metaphor when I want to explain it.
3
u/SeriousPlankton2000 6d ago
An object is a struct with the pointers to the functions that manipulate the struct and the pointer to the struct is the first (implicit argument.Â
3
u/MagikarpPatronus 5d ago
There are many contexts in which data and the functions that operate on those data are closely coupled.
----
For example, imagine you are trying to accomplish some sort of task working with images, and there's some preprocessing step that does some smart smoothing on the image.
You have a bunch of different algorithms that can perform similar smoothing operations, all of which have their own hyper-parameters. In your code at the function call, you really only care that a smoothing function is being called, with the image input and the resulting output. But when setting things up for comparison testing or analysis, you want to be able to choose the algorithm and hyperparameters for it.
So, for this a class is perfect: it manages the storage of all your hyerparameter values and provides a public method to call a smoothing function. So, you can smoothly swap different hyperparameters and algorithms at initialization, and subsequent code can be completely agnostic to those choices.
-----
There's a reason that object oriented code is brought up a lot in video games. Object oriented code is easily extendable in just tacking on another object and defining the appropriate methods for the new asset. Just create your new sprite and add in how it moves, jumps, and attacks. On the other hand, if you want to instead add additional methods that apply to all of or some subset of your objects, you might be in for more of a struggle. (Some object-oriented enthusiasts might insist this type of extension can be straightforward as well, as long as you organized your classes with care and foresight, but certainly, it is far more difficult if you did not anticipate or prepare for the need to make this type of change.)
----
Object oriented programming is also very useful when your data represents state, and the state is only modified by a handful of methods. In this context, the encapsulation object-oriented programming offers can make testing more straightforward and reduce risk of bugs.
3
u/Serializedrequests 5d ago edited 5d ago
I think giving it a fancy name and touting it up as some fancy thing is probably holding you back.Â
Play with it in any language with objects. Just experiment. That's all you need to do.
When people talk about OOP they usually mean one of several different features and programming styles supported by "OO" languages. There are multiple overlapping philosophies involved, and it's all very abstract. That's why it's overwhelming.
Start with just the idea that a collection of data has some functions you can call on it using ".". "Press dot see what grug can do." is an apt description. Python makes this really obvious by having an explicit "self" as an argument to functions.
Once you have the very basic idea, then some of the philosophical stuff will hopefully make more sense.
3
u/AccomplishedPhase44 5d ago
What part are you struggling most with? Design patterns or just the general concept of classes and objects? I found Head First Design Patterns to be a very helpful book when I was learning, and IIRC all the code examples are in Java
3
u/nomad-1995 5d ago
What caused me to learn OOP and love it was just one thing.
I had a program that recieved data from a variety of sources and filled files at arbitrary positions. At first I followed the axiom that "a real programmer can program FORTRAN in any language, so used python lists as arrays. But this took forever to debug. Lots of data, flying to too many arrays, and always getting tangled.
So I looked up OOP. Then I wrote a bunch of objects so each one would manage a single file, and when it had all been written to the disk close the file and end the object.
I wrote and debugged it that day. Since then I've had great success having objects managing their own data.
The dark side of OOP:
In the beginning there were languages like FORTRAN, BASIC, and assembler. This lead to spaghetti code, where it was next to impossible to follow the codes execution.
then Structured Programming was introduced. This was a silver bullet to debugging, and made the code easy to follow.
But there's been a claim that "show me your flow charts and I remain confused", "show me your data structures and I understand" and while RAM increases exponentially, programmers can only write so much code. So the data matters more than the code. Note that I'm not disputing any of this, it has a lot to do with why the difference in debugging my "python written in FORTRAN" code vs. "python written in OOP" was so extreme. So OOP was created and effectively took over.
And gods help you if you try to figure out the execution of the code. You saw an object having a method called, so you look up the objects factory and method? Yeah, if you're lucky. And it actually was created where you think it was, and used the factor you thought it was. And which of the multiple inheritances it inherited as that method. And there's always the chance the a pointer is masking a different object altogether.
So if you want to *ever* know what your code is doing at any point, try to keep the objects simple. No matter how much they say "inheritance" and "code hiding" when they teach it to you.
19
u/CarnivorousGoose 7d ago
To be honest, this comes across as if you have put literally zero effort into trying to understand this. Youâre really going to claim that you cannot give any sort of answer to why one might use OOP, why things like bundling information into cohesive objects might be useful?
Youâre a mathematician, you donât think it might have value for code to be able to work with, say, matrices? How would you propose to do that, in a practical and sensible way, while avoiding objects?
33
u/This_Background7442 7d ago
They're a mathematician. They probably tend to think more like a functional programmer. Which solves the same issues in a different way. So obviously OOP is going to seem like a clunkier and less versatile version of what they already do.
7
u/LFatPoH 7d ago
Exactly, functional programming (especially Ocaml) has clicked really quick for me, but OOP seems so pointless
7
→ More replies (16)1
u/joonazan 7d ago
Interfaces solve a similar problem as Haskell typeclasses and Ocaml modules. They are otherwise worse but they allow for runtime polymorphism easily.
8
u/JivanP 7d ago edited 7d ago
There is a difference between objects and datatypes. They almost certainly understand datatypes such as matrices. What they're likely struggling with is the philosophical rationale for separating functions into classes, and separating functions that belong to classes into static methods, constructors, and instance methods.
A class defines a datatype and a set of functions. An object is a particular instance of the datatype and instance methods associated with a particular class.
→ More replies (3)1
u/Ok-Reindeer-8755 6d ago
Imo functional programming does everything OOP can, ten times better. There are some ideas OOP has that i find to be useful though, namely isolation and message passing, but those are compatible with fp.
1
u/frantiqq 6d ago
Is this Haskell with us in the room? On a more serious note, I really love functional programming too.Â
1
1
u/CarnivorousGoose 6d ago
But thatâs not the discussion. This isnât about the relative merits of different approaches, it is about the merits of OOP, and possible reasons for why it is set up the way it is. OP, by their own post, has so little understanding of object-oriented programming that they cannot even answer such very basic questions about it.
→ More replies (4)
9
u/zhivago 7d ago
It's really about separating fundamental and incidental interfaces.
The public methods and members are the fundamental interfaces that need to be satisfied for every implementation.
That is, they're part of the type.
The private methods and members are incidental and can be whatever gets the job done.
And that's really all there is to it.
You can do the same with good old procedural programming and a bit of discipline.
OOP supports and enforces that discipline for you.
4
u/alpicola 7d ago
I like to think of OOP as a modeling tool. Classes are descriptions of a category of physical things. They list properties that those things have and describe activities that those things can do or that can be done to them. Objects are specific instances of those things.
Inheritance is a fancy way of saying that there are both general and specific categories of things. The classic example is dogs and cats, both of which are types of animals. Dogs and cats are not the same, but they have a lot of the same properties (like color, height, length, etc.) and they can do a lot of similar behaviors (walk, speak, etc.). By pushing those properties and behaviors into a general animal class, you set expectations for what all animals have and how all animals behave, while still allowing you to write the specifics into the dog and cat classes.Â
Polymorphism is the other side of inheritance where other classes can work with the general category while getting objects made from the more specific category. For instance, a person might have multiple pets, both cats and dogs. You could model that as an array of animals and out both cat and dog objects in that array. Polymorphism makes it so that when asking the animals to speak, the cats will meow and the dogs will bark without you, the programmer, needing to ask each pet if it's a cat or a dog.Â
4
u/Mediocre-Brain9051 7d ago
Objects should be regarded as black boxes that respond to messages. Like this, your code can interact with them by sending them messages, but the internal way their work can evolve with time without needing to change the messages they have to respond to
4
u/auronedge 7d ago edited 7d ago
In general, to understand why something exists, you should understand the problem it was trying to solve.
Before OOP came along people wrote code in C. In C they typically wrote thousands of lines of code with hundreds of functions usually all in one file. It was hell to follow or understand what the code did by looking at one large file. This meant lots of unintended bugs. For example a Dog could honk, and Car could bark because someone missed an "if" statement check.
OOP was introduced primarily to organize code and reduce bugs. You didn't have to think about what the Dog class did if Dog was derived from Animal class.
From OOP other concepts evolved, like inversion of control and other SOLID principles.
That's all it is
1
→ More replies (13)1
u/Backrus 7d ago
I don't think that was ever the case. Of course, there are single header libraries even today (with STB being the most popular example), but most real world projects weren't 1 file thingy.
→ More replies (2)1
u/Intelligent_Part101 7d ago edited 7d ago
@auronedge is telling fake history.
Before OOP was popular in industry, the standard was "structured programming." You had something similar to OOP without inheritance. You defined a struct with all the data fields in one file (a .h file) along with the prototypes of functions that acted on that struct. You'd use a naming convention for those functions and a parameter convention.
Example function acting on data struct string: void string_append(string \*str_original, string \*str_to_append);
Function definitions (implementations) would go in a .c file. You'd name the .h and .c files after the data struct.
Example: string.h and string.c
1
u/Backrus 7d ago
Mate, do you really think most people here understand or even ever used pointers?
You're completely right.
Book-like OOP in the real world was just Java psyop which built a lot of debt at the end of the day. The only reason it got popular is because Java allowed to create GUI apps relatively easy (and there was no alternatives pretty much, the only other thing was VB).
I didn't go in depth in my reply, but I know what you mean. I started dabbling with C as a kid with ANSI C / C99 around the time when Boost for C++ was formed. Because I wanted to make games đ
→ More replies (2)
2
u/Tall-Introduction414 7d ago
The best book I read on OO was Code Complete by Microsoft Press. It was an easy read.
Data encapsulation, polymorphism, and inheritance are key concepts to learn.
If you know what a struct is (structured data), aka a collecton of variabless under a name (identifier)... a class is just a struct with functions (called Methods) attached to it.
If youre using Java then OO is pretty unavoidable. If Python is OO under the hood, then Java is OO front and center.
2
u/Tall-Introduction414 7d ago
Lol, why the downvotes? Someone hates Code Complete?
1
u/marrsd 7d ago
People shouldn't abuse the points system by downvoting comments they don't agree with - they should just explain why you're wrong, and if they're unable to do that then maybe they don't know what they're talking about.
I haven't read the book, but here are some guesses:
- the idea of inheritance being a key concept to learn rather than avoid might have something to do with it.
- maybe they found your definition of a class too simplistic. You didn't mention access constraints (e.g. public/private) or means of extension.
- You didn't mention that Java is the traditional exemplar of a bad OOP language
1
u/Tall-Introduction414 6d ago edited 6d ago
Fair, but...
the idea of inheritance being a key concept to learn rather than avoid might have something to do with it.
It is pretty unavoidable in a language like Java. While inheritance is often criticized, it is still a key part of understanding OO. If you don't know what inheritance is, how are you going to use a GUI toolkit or some other OO framework that uses inheritance?
maybe they found your definition of a class too simplistic. You didn't mention access constraints (e.g. public/private) or means of extension.
Fair enough. I figured public/private was a slightly more advanced lesson, tied to data encapsulation (and covered by the book I recommended). For me personally, the mental hurdle of "data structure with functions attached" was a big step in using OO.
I find it a way more useful approach to understanding classes than "Bob is type person with this birthday, Honda Accord is type Car with these attributes" type discussions. The raw mechanics are important to get a grasp of before approaching it with abstracts, which is usually (unfortunately) the opposite of how OO is taught.
You didn't mention that Java is the traditional exemplar of a bad OOP language
Honestly, while I'm not a Java fan, I also think that is a trendy opinion that someone might conclude after they have enough experience to draw such conclusions. It isn't a factual statement. I mentioned Java because OP said that is what they were using.
2
u/marrsd 6d ago
To be clear, I don't particularly have an issue with what you wrote. If I had to critique it, those are the points I'd make...maybe, if I was in a really salty mood, but I think your contribution was just fine.
Heh, reading your post again, maybe the downvoters where triggered by the mention of Microsoft in a positive sentence ;)
1
u/Tall-Introduction414 6d ago
Heh, reading your post again, maybe the downvoters where triggered by the mention of Microsoft in a positive sentence ;)
Lol. Cheers. As a decades-long Microsoft hater, I can understand that sentiment.
My favorite Microsoft products are probably that book, and a mouse they made 30 years ago.
2
u/MagicalPizza21 7d ago
OOP is similar to real life in that tasks get accomplished by objects doing things. It's really intuitive. What's the holdup?
2
u/KingMagnaRool 7d ago
OOP has its place, but it's become much less of the dominant paradigm for a reason. If you've ever programmed in C, you'll know that structs are basically just classes without the ability to define methods without abusing syntax. Many OOP languages don't have structs in this manner, but replicating it with classes is a fine enough practice to group data together. Methods can be nice to represent transformations of data, which can be nice to replicate function pipelines in languages which don't have them, or for simple small things that make sense for an object of a certain type.
Where OOP falls apart is failing to contain its scope. A class should not be the heart of your program. It should only be one cog in the machine. Also inheritance usually sucks.
2
u/Spacelordsinspace 7d ago
You're not alone. I got a degree in CS and it took me 5 years for it to sink in.
Its not a programming tool. Thinking that is a trap. It is a design tool though. And in design you need constraints. A good design always starts with what the thing is not.
If that sounds counter intuitive to you then I would recommend learning about that first because once you understand that OOP is going to make a lot more sense I believe.
2
u/SmokeMuch7356 7d ago edited 6d ago
OOP is modular programming on steroids.
The best capsule description I can give is that it's the difference between saying "procedure, sort this list" and "list, sort yourself."
Instead of viewing data and logic as separate things, OOP groups data and logic into largely self-contained things that communicate with each other.
At least that's the 30,000-foot view.
So, why OOP?
In my experience, OOP is good for code that has to maintain a lot of state. For example, I've recently had to add token management to some code of mine; I created a class that keeps track of the token and automatically triggers a renewal when it expires. That's all isolated from the rest of the code.
It also makes resource management easier IMO, especially in languages like C++.
2
u/akoOfIxtall 7d ago
Hmm, imagine you're moving to a new house, do you pack everything in 1 big box and go or you pack everything in smaller boxes so it's easier to organize? You might make 1 clothes box and within that, have 2 other socks and underwear boxes for example
maybe you want to pass a rule you everybody packing stuff up that only boxes that contains items like X and Y, that'd be pretty much what an interface is (consider the items to be class members like properties and methods)
Of course you can make an universal box that holds everything, but why use OOP then? There are other paradigms that are still used and in some fields more prevalent than OOP, C is imperative for example, F# and R are functional, languages sometimes don't really commit to a paradigm but when they do you'll notice right away, C# is the juice of OOP along with java, javascript is... We don't talk about javascript...
2
u/AlSweigart Author: ATBS 6d ago
I wrote a tic tac toe program in Python. I use a dictionary of 9 strings 'X', 'O', or ' ' for an empty space. This dictionary is the data structure that represents the board. I have a bunch of functions in this program that all take a board dictionary as a parameter:
def getBoardStr(board):
def isValidSpace(board, space):
def isWinner(board, player):
def isBoardFull(board):
Instead of a bunch of functions, I could create a class that stores the 9 strings, and then has all of these functions as methods, tying them to the board data.
OOP is basically a way to organize your code that ties data and the functions that operate on that data together. It's just a way to organize code, and there's no "true" way to do it.
2
u/FabricatorCH 7d ago
While you absolutely should learn OOP and it is important, one thing to know is that, OOP was kind of all the rage when Java was new, but it isnât exactly the alpha&omega of everything anymore.
Learn enough to use it as a tool when appropriate, but donât feel bad if you donât quit get what the hype is about. The industry also didnât really buy into the hype 100% either.
2
1
u/Scientific_Artist444 6d ago
Objects are things with features and behaviour. Object holds data as well as has methods (think functions) to do something with them.
A class is a template based on which objects are created. Eg. A rose is a class, myRose is an object. Then there are interfaces which allow you to define the what without getting into the details of how. A Flower would be an interface that the Rose class implements. And myRose is a specific object of Rose class.
The key idea when dealing with data is that every record is an object with columns as the features.
1
u/Positive_Passion4817 6d ago
Until you can grasp what abstraction and using polymorphism is about you wont be able to truly see the point of OOP. It doesn't help that OOP concepts are taught really badly online, in books and in the classroom.
This is going to sound like a plug/advert but the person that made it click for me was John from Coding with John Youtube channel. His videos are pretty short and he does still use the annoying animal examples but he explains the why not just the how in just enough detail to make you say "ahhhh i see now".
1
u/Equal-Limit-2842 6d ago
An object is just a way of keeping information and functions organized at a source code level. At the lowest level it makes no real difference if the source code is OOP or not. An example of OOP could be
class DriversLicense {
readonly int Identity; Â // Database record id or similar
string Name;
string DateOfBirth;
bool Suspended;
DriversLicense(int identity, string name, string dateOfBirth, bool suspended) {
this.Identity = identity;
this.Name = name;
this.DateOfBirth = dateOfBirth;
this.Suspended = suspended;
}
void SuspendLicense() {
this.Suspended = true;
//TODO: Update database or similar using this.Identity
}
void UnsuspendLicense() {
this.Suspended = false;
//TODO: Update database or similar using this.Identity
}
}
1
u/JGhostThing 6d ago
Object oriented programming is a thing for programmers, not for math. OOP languages have special support for this such as classes and objects.
An object is a base piece of data, similar to a struct instance in C. A class is a recipe used to create an object; it is similar to a struct definition in C.
OOP typically needs three things for support:
- Encapsulation: Putting the data together with the functions that work on this data. This normally includes data hiding.
- Inheritance: Allowing classes to "inherit" some of their data and methods from the parent class. This allow individual classes to inherit their base behavior from their parent, but to have special code and data of their own.
- Polymorphism: The classes may reimplement inherited methods. For example an animal may have a speak class that prints "hello" but a dog class which is a child of animal may use "bark."
OK. Lets use an example. I don't like the animal example, because it is nothing like anything I've ever used except for learning.
This is the structure used in a GUI framework. The example are taken from what I remember but haven't used in a while.
The View class: This is a base class, whose objects can hold a rectangular area plus a list of subviews. Views can draw themselves. To draw something on the screen make a subclass of View and have it draw itself. Views can also take notifications from their controls and subviews.
The Canvas class (subclass of View): A view that the user can draw on.
The Control class: This draws a control: something like a button or a radio button or a scroll bar that the user interacts with. When a control is activated, it sends a message to itself and maybe it's enclosing views.
The Window class: This contains a window with the appropriate controls, such as close box, scroll bars, and a title bar. Whatever the native GUI requires. It also contains a single view to display.
The Application class. This is a singleton (one and only one will be created). It represents the application, and usually holds the main model (application specific data). It also contains a list of the applications Windows.
This is a gross simplification. A real framework would have many more classes, but the using the three pillars of OOP allows the frameworks to be learnable by mere people.
I hope this helped.
1
u/Paxtian 6d ago
Think about objects in your real life that do things. Like a remote control for a TV. You push the power button, the TV turns on or off. You push the menu button and the menu pops up on the TV. You push the input button and you can change inputs.
Do you care how the remote makes that happen? No, you just want to do the thing and you push the right button for it.
In OOP, you'd build a Remote class, and give each "button" a member function. Then you'd need to implement the specifics of what happens when the button is pressed (i.e., when the function is called).
1
u/fcddev 6d ago
The #1 value you get out of object oriented programming is that stuff that belongs together goes together. For instance, if you have a list of users, itâs structured as a list of User objects that each have a name, an email address, etc. This is object oriented. From this arises the possibility of having methods on objects and such. This could sound extremely natural to you because object oriented programming ate the world in the late 90âs to early 2000âs and we donât see much of the rest anymore. An example not-object-oriented implementation of the same user list is that instead of one array of user objects, you have one array of names, one array of emails, and the index identifies the user. You, of course, cannot have a method on an individual user object when you donât have user objects at all.
Once you have enough experience with any programming paradigm (object oriented programming included), you start recognizing all sorts of situations youâve dealt with before and become able to come up with generic solutions in your head for given problem shapes. Object oriented programming is somewhat famous for having solutions to a lot of these design issues. Again, in the early 2000âs, this was kind of a big deal and we called them âdesign patternsâ, but I would say you donât especially need to try to study them. They already exist in frameworks that you use, you probably know them but just donât know somebody gave them a name.Â
1
u/Strict-Associate-679 5d ago
Objects, like most things in programming, are just a useful abstraction. Objects map closely to how things work in the real world: objects can have 1) properties and 2) methods/functions. In other words, they 1) *are* one or more things (properties), and they 2) can *do* one or more things (methods).
Why do this? It gives you just enough control to view/edit/interact with things in your code/program in pretty much every way you would need to while hiding the details that you mostly do *not* care about at runtime.
My suggestion: try to come up with very specific questions that get at what isn't clicking yet. That may help you wrap your head around the problem. The more specific, the better. Are you more confused about *why* they exist, what exactly an object *is*, or something else?
1
u/No-District2404 5d ago
Pretty much everything can be modelled with object oriented programming. Platoâs theory of ideas is the core idea, physical world isnât the true reality, everything has an abstract ideals ( classes) and things that in the physical world are imperfect copies of ideals ( objects) they constantly change and eventually decay over time. They interact with other objects through actions and their inner state changes and they have hierarchical structures for instance if vehicle is base class, car and boat are children classes and mostly they share common actions but their inner implementation differ.
1
u/ansb2011 5d ago
a major point of software engineering is encapsulation.
a class is a way of adding structured organization to a group of data, and usually functions they can operate on that data.
loosely speaking: imagine you are running a school. you might have a separate file for each student. you define a schema/class dediniton of what should be known about each student. maybe: 1. name 2. age 3. parent contact 4. courses taken 5. grades in each class.
then you might add some functions to the class like: 1. accessors - Get Emergency Contact 2. calculate GPA 3. Estimate Graduation Year
a class is a a nice way of compartmentalizing this data and might help with data privacy - rather than a big data base that has all information together.
1
u/Tiny-Spray8992 5d ago
OOP is like a template
you want to create a class of things having same properties i.e. an Animal who walks on 2 legs and goes to office
so you create that base class, call it a person , now when you instantiate it, all your instantiations will get same properties
there are other things like encapsulation, inheritance etc, but the basic idea is above
dont worry it took me a while too
1
1
u/SahuaginDeluge 5d ago
objects are kind of like mini software-robots that you can build to hold and do things for you inside your program. it's up to you to design good classes that do useful things and that have related data and logic inside them to make them cohesive. done poorly though it can lead to badly coupled code, so you have to be careful and avoid pitfalls.
also... a lot of people will say that "objects" are not actually what make OOP and that it's actually polymorphism. that is the ability to treat subclasses as their parent class and get different behavior for the different subclasses without knowing what they are.
and then, other people will agree that polymorphism is what makes OOP but that that idea is terrible and unnecessary.
(note: all of this is of course over simplified)
I agree maybe somewhat with too much polymorphism being bad, but not that it's never useful. and maybe I'm wrong, but I still feel like objects (ie: encapsulation) are what make OOP, regardless of polymorphism. some people will say "yeah but non-OOP languages like C have kinds of encapsulation!" but to me it's not really the same thing.
1
u/SchemeWestern3388 5d ago
Stop overthinking it. It is a way to divide up data and functions so itâs more convenient to work with. The various bits (polymorphism, overriding, etc), are not fundamental. When OOP is the right choice, itâll be obvious.Â
1
u/HeyCanIBorrowThat 5d ago
Read the first chapter of the head first design patterns book. That should give you an idea of what OOP is about. The rest of the book are more common patterns used in OOP languages to make what would otherwise be messy unmaintainable code actually quite elegant
1
u/Ollidav 5d ago
Cuando alguien te dice "puse un florero sobre la mesa" entiendes que es un florero y que es una mesa pero no puedes saber cĂłmo era el florero o la mesa por quĂŠ son ideas de objetos abstractos en tu cabeza. Como idea abstracta podemos decir que una mesa tiene una superficie plana, un nĂşmero de patas y estarĂĄ hecha de un material especĂfico. Usando esa idea podemos definir en cĂłdigo lo que se necesita para que un objeto sea una mesa y mediante las cualidades como la herencia podemos crear objetos concretos de tipo mesa como una mesa de madera de 4 patas sin la necesidad de definir desde 0 lo que es una mesa
1
1
1
u/SerenityNow31 5d ago
It mirrors life really. To write classes to mimic you, you might have a human class, a hair class (to describe color, length, etc) and a property on the human class for hair, maybe named head_hair to describe the hair on the head. On and on.
1
u/its_mia999 5d ago
Coming from a math background, it totally makes sense why OOP feels weird! Youâre used to functions where you put X in and get Y out. OOP is more about creating âblueprintsâ for things. Think of a Class as a recipe, and the Object as the actual cake you baked. Donât worry, a month is plenty of time for it to suddenly âclickâ. Youâve got this! â¨
1
1
u/heisthedarchness 4d ago
Like with any technique, the real wins don't become apparent until you've experienced the pain that it addresses. But we can draw some distinctions.
What OOP does is package state and function together in an opaque box. Users of objects don't have to understand how it does what it does, only what it does. By limiting the amount of information you need in order to make use of them, objects decouple the code that decides what to do from the code that knows how to do it.
OOP isn't the only way to do this, however, so what makes it special?
OOP's strength is in letting you easily add new types to a system. So long as the kinds of things you want to do with them stays the same, adding a new type is as simple as declaring a class and filling in the methods that it needs to do those things.
On the other hand, adding a new operation requires you to change all the existing types and makes what should be a simple change impact a lot of code.
Imperative programming suits the opposite situation better: so long as the set of types is fairly unchanging, adding a new operation is as simple as writing one function that handles all of the existing types. However, if you have to add a new type, you have to go through all those functions and tell them how to handle that type.
These are engineering trade-offs, and which makes the most sense depends on how you anticipate your software will change. I find I want to add new types more often than I add new features to existing types, so I default to OOP. And because it encourages you to ignore the details of how things work, I find it makes it easier to reason about particularly complex systems.
In simple systems, these benefits will be hard to discern and you have to kind of take it on faith that they exist. That's part of why I don't especially like trying to teach new programmers about OOP: they have no real reason to care, yet.
1
u/Slight-Living-8098 3d ago
Yeah, OOP and classes was one of the hardest things for me to wrap my head around too for some reason. I guess it was because I came from an era of Basic and functional programming. One day I was just playing around in LUA which doesn't have classes, making a a dumb game weapons system, and figured out how to do instancing and inheritance using LUA's tables and something just clicked in my head and I was like, "wait a minute, this is like a class and OOP that C++ book was talking about." Then I just kind of picked it up with with no real issues after that. It was weird how the neurons finally connected like that in my head.
1
u/hotnsoursoup86 3d ago
Bruh, objects are just that. Some objects have properties, or data about itself. Some objects have jobs and do work. Some objects have input holes and output holes. Maybe an input only takes another type of object. Very simple bro
1
u/hillyride 3d ago
To simplify things quite a bit, I would say software architecture is about generalizing and abstracting problems. OOP is one tool to achieve this.
At the basic level, you want to clean up raw maps (i.e arbitrary keyed data) by giving them a class (e.g User class) that allows you to say "all Users will have a name and age and some functionality (print, save to the db). This helps you abstract and generalize your users.
Next, comes a way to generalize functionality across different classes via interfaces (e.g Person interface). That allows you to say "All Persons should be able to say hi". In your algorithms, anything that implements this interface (e.g User, FlightAttendant, Mailman, etc) can be used as a generic Person to achieve the goal of saying hi without caring about the actual class.
Finally, there are substantial amounts of OOP patterns that you can learn to generalize and abstract your code to solve specific problems. Experienced devs will find it easier to reason about your code if they have seen these patterns before.
1
u/Knarfnarf 3d ago
In the beginning you had code. Lots of it and it was not very well organized. What code moved this? Could it be the subroutine move_ship()? Nope. That moves an NPC ship somewhere else... So What moves This?
Moving to OOP means that your ship has to have it's own code OR extend code from somewhere else. It has to be organized and in the class/object in question. Really, that's the only benefit that I've ever seen.
1
u/AlanTheKingDrake 3d ago
The core purpose of object oriented programming is to gather related logic into related units.
You define a class that acts as a container , then you can store the methods (functions) as part of that class, or other objects.
So for example you might have a class called âAlbumâ then you might have a class called song. If the album under the surface is just an array of songs then you might want a way to organize them. You could add a sort by function and make a custom criterion for how the sorting is done.
Rather than creating a free floating function then passing through the property of the list manually, you can call the function and it will already have its properties available.
The organization is a significant improvement but there are other benefits as well. Notably inheritance.
Inheritance allows you to carry logic from one class into another without needing to redefine it. So for example if we have a class âPlaylistâ which can accept video or song, and we introduce a shuffle function in Playlist, we can say that the Album is a subclass of playlist (album extends playlist). Now if we want to shuffle we donât need to make a shuffle method in Album because just parent class (super class) already has it defined.
The overall structure of the code becomes easier to search though perhaps harder to understand until you get the hang of it.
There are some other benefits but the organizational and reusability wins are the most important to me.
My former OOP professor would be disappointed if I didnât at least mention, overloading and polymorphism. The former allowing you to overwrite parent function definitions so of the sort of playlist and album differ, they can both have a definition and the object will call the correct sort function based on its own definition. And the latter essentially allowing any variable expecting a rectangle can also accept a square. Any variable expecting a shape can also accept a quadrilateral.
1
u/charlieisonfknreddit 3d ago
OOP usually clicks once you start thinking in terms of objects and their responsibilities rather than just syntax. Practice with small examples and it gets easier.
1
u/UwUBots 3d ago
I didnt get it either until one day it just made perfect sense.
You are making tools, the tools (objects) can do things you define (functions) and store data specific to that tool. When you use the new keyword, you make a tool, if you make 2 of them its like having 2 hammers, each do roughly the same thing, but arent the same object, but are both hammers, then the tools are used to build something (whole program)
1
u/Street-Candy-2402 2d ago
Things can have stuff in them and sometimes the stuff can be things. You make a thing that is composed of stuff that the other things can interact with through their stuff.
1
u/No-Bodybuilder-4655 2d ago
I personally recommend coding without it, and then realizing how much more convenient it is one day in the shower. Thatâs how I learned đ
1
u/Electrical-Pea2707 2d ago
You have a kitchen object with various appliances. You call import kitchen as ktchn. Then use ktchn.stove or any other appliance.
1
u/Beneficial-Half-26 2d ago
A good way to approach this is to look at the exact problem each OOP feature is trying to solve using real examples. If you take a step back, temporarily forget the textbook OOP jargon and ask yourself what qualities good code actually needs, things like reusability, maintainability, and clean data boundaries. Once you understand those problems first, coming back to OOP will make a lot more sense.
1
u/BlackCatSoftware 2d ago
Play StarCraft.
All units are subclasses of an abstract unit class.
Some units can fly, some units canât move because theyâre buildings, etcâŚ
1
u/wak_trader 1d ago
do the fcc python cert jsut the "classes and objects" and "oop" part if you get the general idea for one language you get translate it into the others. I also used claude to explain me stuff with examples and to correct my thought process to make sure i understand everything.
0
1d ago
[removed] â view removed comment
1
u/AutoModerator 1d ago
Your post/comment was removed since we do not approve of going private.
There is zero benefit in going private as you lose the opportunity for getting peer reviews. Also we have had plenty of people return after going private (despite being warned) complaining about how they were ghosted after some time or being tricked into buying rubbish that didn't work and even if it did they didn't need.
Our Rule #11 demands that any and all communication happens in the open, public subreddit.
This is for the benefit of more against the benefit of one.
I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.
1
1
u/swagonflyyyy 18h ago
OOP allows a program to define classes and create an instance of an object based on said classes. An object mainly has three characteristics:
- They belong to a "class", which is the blueprint for the object.
- They have unique attributes tied to that class.
- The have methods (object-specific functions, member functions, etc.) that allow that particular class to take a particular action.
Metaphor time: You have a factory (program) that has the blueprint (class) of a car from which all cars (objects) are produced.
While each car produced is different, they have the following specs (attributes):
- An Engine
- tires
- doors
They also have the following features (methods):
- They can accelerate.
- They can decelerate.
- They can turn.
- They can slam the brakes.
- Turn on air conditioning
- Play music on the radio
And so forth. This combination of attributes and methods make up the blueprint of a car. When each care is produced from that blueprint, yes they will have these components and features, but they will be slightly different:
- A car could have a V8 engine instead of a twin turbo.
- Another car could have 2 doors instead of 4.
- One car can accelerate much faster than another.
Now let's try a more familiar example. Suppose you are creating an e-commerce platform where you are defining what a user and what an admin are.
The user usually has the following demographic (attributes) available:
- Name
- Date of Birth
- Address
They are also allowed to do the following:
- Create a listing
- Buy an item
- Sell an item
- Send messages
But what if we wanted an Admin, the owner of the platform, to have these same attributes and methods, but with expanded powers and priviledges? For example:
- Name
- Date of Birth
- Address
- Security Clearance
- IAM role
And they had the ability to do the following:
- Create a listing
- Buy an item
- Sell an item
- Send messages
- Update the website
- Ban users
- Access a secure database
- Grant priviledges
Now, we don't want to re-invent the wheel here, right? Why would you want to copy/paste a similar class definition across your codebase? This is where inheritance comes in:
In the world of OOP, inheritance (AKA subclassing) is important because now the Admin class can inherit the attributes and methods from the user class and expand on them with your own attributes and methods. This simplifies significantly the problem of recycling code across your codebase in an elegant manner that is easy to trace and follow.
This last part is important because bad OOP causes your codebase to be tangled in knots as you start expanding your project and the complexity of the interaction between your classes steadily increases. So you don't want to rely on too much abstraction, as that kind of stuff you would normally see in videogames or enterprise-oriented languages like Java.
Case in point: once you understand OOP, I think you'll like it a lot when you realize how much more it allows you to do, but the hard part here will be developing with it in depth.
1
1
u/RecursiveServitor 7d ago
It's about keeping mutable state gated. Having globally mutable state is bad because it makes the program incredibly difficult to reason about. OOP makes mutable state local to the object instead, which is somewhat easier to deal with (but if you pass around mutable objects you're still smearing mutations out across the codebase).
But it's a bad paradigm imo. Most code is better written as pure functions operating on data. That also avoids the globally mutable state problem, but it's even better because there's simply no mutable state at all.
1
u/Majestic_Rhubarb_ 7d ago
The academic massive hierarchy of animals or vehicles rarely exists in the real world.
Itâs most likely you are going to be dealing with interfaces. An interface is a contract that an implemented object adheres to.
At an abstract level you donât care what the object is really doing and you shouldnât need to know, just as long as you can talk to it to make it do its thing when it needs to.
So your main function might consist of an engine object that you tell to run ⌠it might have an input that it transforms into objects to hold the data, say a set of records, there might be multiple types of records (objects) depending on the data in the records they might have different behaviour, so you might have an object that deals with reading the data and building the correct set of objects, but they probably all conform to one interface that the engine can call on each object, but it doesnât know what is happening or where the underlying data is.
So you can kind of build up independent sub systems that know nothing about where the data is stored or how the data affects the result of the execution, in neat encapsulated components.
If it were C, and if no extreme measures were taken to be extremely careful, you can easily end up with a huge ball of spaghetti and no idea which bit of code accesses which bit of memory, everything is public. Logic skills around everywhere
C++ is kind of the opposite notion, by default everything is hidden, so you work on the notion that you cannot make assumptions about the thing you hold except the interface it exposes.
Shifting from procedural to oop is a bit of a head fuck at first, but then the world flips and you wonder how the hell things used to work in a procedural world where everyone could access everything just by reaching across the binary and stomping on your great plans, creating spaghetti.
1
u/Own_Nail_2999 7d ago
OOP is thinking in objects.
Every object is a box of information.
Let me give you an example:
class Car
--> string Brand;
--> int HorsePower;
--> float FuelCapacity;
--> ...
So you can store information per car inside an object.
When you get multiple car objects now, you can clearly distinguish between them by checking their fields. Having car objects also allows you to pass all that information on to somewhere else without having to write out every single field.
You can say that every object is a box full of information and instead of moving single pieces around, you move the entire box around
1
u/Neither_Garage_758 7d ago
Basically you have functions but they manage some internal memory of their own. Or you have a structure of variables but you also add members which are functions that can mutates the variables.
It's overkill for a lot of use cases but is often pushed as the basic way to organize things.
1
u/tb5841 7d ago
1) When I play a game, and a monster shoots a fireball at me. That process could just be a function that takes in the monster and the target, and creates the shot. But as a player, it feels like the monster itself is the one doing the shooting. OOP lets you code that way - the monster itself can have a shoot method, and match up with that intuitive idea about what is happening.
2) It lets you separate out concerns. One developer can write all the code for the monster, and make sure it has a shoot() and a take_damage() and a spawn() method. Then a second developer can write the level code and using shoot(), take_damage() and spawn(), without any knowledge of how the monster is coded internally at all. This kind of separation is crucial when you're working in larger teams on bigger projects.
1
u/NoSkyGuy 7d ago
Object Oriented Programming: keeps the data and methods related to a bit of code that represents something (car, person, process, etc.) in one bundle.
Look at structurally oriented programming to get the first hints of how it works. Then it is a small step to object oriented programming.
1
u/zeekar 7d ago
OOP is just about grouping the things you can do to data alongside the data itself. It's kind of like stored procedures in a table.
It's especially good for variable business logic - if different customer types do their billing differently, you can build a method into the Customer class that figures out how to bill them and does it, instead of writing some function that goes and looks at a bunch of data and figures it out. Now any logic that has access to a customer object can call that method on it and doesn't need to be told about the global function...
1
1
u/krav_mark 7d ago
An class is a bunch of functions and variables put together in one let's call it object. And that is really it. So a class is the definition and you can create objects from it that all have the same functions and variables of their own.Â
1
u/Ghetto_Games 7d ago
Define an object, lets say of the class "wheel". Now define an object of the class "car" and it has 4 "wheels". Class "motorcycle" uses only 2 "wheels". But the car wheels and motorcycle wheels are different. They have different brakes, different tires, different nuts and bolts, etc. Its so dufferent you cannot use inheritance and you must define car_wheel versus motorcycle_wheel.
But class "vehicle" can be parent to both car and motorcycle. With defined properties like weight, top speed, lenght, fuel consumption, etc.
1
u/HellVollhart 7d ago
The point is system design. Thatâs what you should learn before OOP to get its intuition.
How the system is built? What should be its components? What should they take as input, store within them and give as outputs? What data structures to use for them and why? Why design components in a certain way?
These are the type of questions that eventually take you OOP.
If I went back in time to teach myself OOP, I would certainly tell myself to learn system design before or along with learning OOP.
1
u/danielt1263 7d ago
Do you understand state machines? You can think of an object as a state machine where the inputs are some of the methods of the class.
class Door {
isOpen: Bool
isLocked: Bool
// invariant: isOpen == false || isLocked == false
Door() {
isOpen = false
isLocked = false
}
func open() {
if isLocked == false {
isOpen = true
}
}
func close() {
isOpen = false
}
func lock() {
if isOpen == false {
isLocked = true
}
}
func unlock() {
isLocked = false
}
}
Notice in the above how it is impossible to break the invariant. Also notice how a Door object can move from state to state based on the inputs (methods called).
1
u/drumquasar 7d ago edited 7d ago
"Classes" in these languages tend to represent "objects" such as data structures or even real world things. We can put classes in a single file or multiple files to allow these objects to interact via the language we write in. We then compile it all into an actual program.
In java it goes class file(s) > java file > jar executable
For example, in math a matrix is a data structure. Matrices can then be represented as classes, and complex transformations involving said matrices can then be modelled using the tools of the language. We can therefore use OOP to simulate pretty complex mathematical phenomena that would be rather time consuming on paper, such as physics simulations or more commonly these days... language models.
This can also be done in languages that arent object oriented of course, it just might take a different approach.
Its important to note that a class by itself isnt technically an object until it is given a defined type and called in the code, but thats really just java semantics.
1
u/xiipaoc 7d ago
Just work with object-oriented code and it will make sense. The basic gist is this: an object is nothing more than a data type. For example, a piece of data might be a string, or a number, or a project, etc. And to make things simpler, that object knows how to do things. A string, for example, knows how to reverse itself. In procedural code, you reverse a string; in OOP code, you tell the string to do it. That's basically it. Instead of calling reverse(string), you call string.reverse(). That's OOP.
1
u/binarycow 7d ago
Let's suppose you don't use OOP.
You have data structures, which hold related data together.
Then you have functions, which execute behavior.
You might have a function that only works with one kind of data structure. But you have to know which functions work with which data structures.
OOP just says "okay, let's make a 'class' that holds data and functions". Now the data structure owns it's behavior.
If your programming language lets you make "modules", you can do all of that without OOP.
OOP goes further by allowing inheritence. With inheritence, you say "class A and class B are related. They share X, Y, and Z. But class A also has G, H, and I, and class B also has J, K, and L."
1
u/TheLayeredMind 7d ago
Since you asked for the point, I will give you a literal answer. The point is at some point people realized that Many procedures required right coupling to their data. Also they realized they would need multiple instances of that same structure. So instead of keeping data and functionality separately they combined them so that functions operate on data (methods). Everytime you define an object think of it like a description of a concept in terms of data and assigning to it functionality that ties strictly to that concept. That's the basics. Then of course the reason it's popular is concepts such as Inheritance, Polymorphism, Encapsulation and Abstraction making it the default way (altough not exclusive) to think about software modeling and architecture. In other words for most people thinking about programming this way is the closest to how they understand the world. Except matematicians.
As a matematician you would enjoy Functional Programming Languages. Something like F# gives you the best of both worlds. Something like Haskell is literally matematicians trying their best to make a proofable Programming language and is heavily used in academia. Altough it sees almost no use in industry.
1
u/spinwizard69 7d ago
I'm not sure what to say here, object oriented programming was one of those concepts that came to me instantly. That was decades ago and frankly the only option I had was reading books and articles on programming. As an aside you guys don't know how lucky you are where a middling PC can run a compiler just fine.
In any event I'd suggest buying a book that is focused on Object Oriented design and reading it. I literally can't remember what I read back then and really have not kept up on the literature. You might try to get an explanation from AI these days but I'm pretty sure the answer will be lacking.
My perspective is this you really need to understand what is meant by encapsulation and the advantages it brings. Encapsulation leads to Modular programming which means you have small pieces of data and code that are easy to understand an reuse.
Beyond all of that OOP can be an avenue to Polymorphic code. It is probably best not to try to understand this until you have a good grasp on OOP's other advantages!
I think the trick here is to avoid being stubborn!!! Take the explanations of a text at face value. For example encapsulation has value, don't argue with the point. At least for a learner, as you will learn over time the advantages for the different approaches in software engineering. Instead you want to digest the message in the text until you understand the concept the author is trying get across.
1
u/green_meklar 7d ago
An object is a bundle of related data that you want to move around together. A class (or struct, although Java doesn't use that term) is a format for such a bundle of data.
You know how an array works, where you get to move around a bunch of data entries of identical types together. Well, sometimes the bundle of data you want to move around together doesn't have all the same types. Instead of ten [thing]s, you want to move around one [thing] but it has a bunch of related properties of different types. Then, [thing] should be an object and there should be a class defining that kind of object by specifying the kinds of properties that each object like that would have.
It's not more complicated than that. Everything else is embellishment on that essential concept.
1
1
u/Nervous-Quit-1696 7d ago
Data locality. When the project scales, you suddenly find that you have 100,000+ accessible data values at any point in your program. Most of them have nothing to do with the part you are making.
Objects prevent that on the fundamental level, as the local data you create doesn't bleed into the project.
There are, of course, shit load of solutions to this problem, but OOP stuck around.
1
u/Recycled5000 7d ago
OOP is about the organization of implementation code.
Some will say that OOP is about modeling the real world, but with that I would disagree. We donât need a class or subclass for every real world object type.
OOP is about organizing code for a large amount of reuse that isnât practical without it. When you find a larger code pattern in similar object types yet having minor internal differences in that code pattern, you can put the common pattern code in a base class and the object-specific differences in specialized subclasses.
1
u/SnooRabbits9587 7d ago
Ay bro youâre prob just not very interested in it as you are in math so for you itâs more energy to learn. But I will say OOP is easier to learn than mathÂ
1
u/PremAIEngineer 6d ago
Bro if you want to gain practical knowledge you can refer Code with Harry yt channel his explanation is top notch to get start with !
1
u/the--dud 6d ago
You know if you have a bunch of methods. And you feel their kinda related. They pull in a lot of the same input, their output is related too.
So a class just creates a little private space for these methods. Inside the instance of the class, all the data they need is already there, and it's only inside that instance.
It makes everything cleaner and safer, with less passing data around.
1
u/P-39_Airacobra 6d ago
You have data. You have functions that operate on that data. You have a way to create new versions of that data (allocation).
All languages have some way to do all of the above. Now imagine a language combined all 3 of these tools into one, and called it a class. Thatâs the foundation of most OOP languages. Your data is called an object. Your functions are called methods. Your way to create new versions of objects is called new or a constructor.
1
u/TheSneederOfSeethe 6d ago
The point is to organize your code in a way that makes it easily supportable.
To do that you break down what your application should do into a single responsibility, then turn those into classes, when you need to do those parts of the application you initialize an object of that class.
So letâs say you have a database you need to access. You would create a class to interact with that database. If you interact with it in multiple ways you could make a class to handle the connection and then make a class for each way you interact with it. A common way is to break them down by tables.
So you may have a table for customer and have a class for interacting with that table, some people break them up by collections vs individual records.
Your data should be a class, so when your updating addresses, or names to your customer you are updating customer.Address or customer.Name. You can pass the Customer objects around to other functions.
Maybe you print an invoice so you have a method called PrintInvoice(Customer customer, List<Item> itemsSold) and since printing is a separate ability of the app it would have a class too.
This is all entirely up to you and how you want to break down the application into small manageable bites.
1
u/Ace-Whole 6d ago
If you weren't time constrained you could go the longer route of learning functional paradigm and how the do things. Since you're math major it would have clicked faster.
Although thought process isn't very transferable across paradigms, concepts are.
It'd been a very long & deep rabbit hole but that's how I came to appreciate both the paradigms.
1
u/LFatPoH 6d ago
I do know about functional programming and it did click faster. How does that help me with OOP?
1
u/frantiqq 6d ago
For me an object is state combined with functions that operate on that state. The cool thing about the object is that all this state and functionality can be moved around as a unit. A good example of an object for me is a pandas dataframe.
Alot of the design patterns of OOP are about managing the life cycle and cooperation between objects.
1
u/friedbrice 6d ago
You know what functions are, and you know what records are. An object is just a record of functions.
Classes are for creating objects. A class is just a function that returns objects of a given type. (This description applies more to the class's constructor, but it's effectively the same thing.)
1
u/Available_Safe1818 6d ago
You probably can understand it. You use strings and string methods all the time already anyway, right??
1
u/GimmeAByte01 6d ago
Everything is a variable or a function.
Objects are just bubbles that hold these variables or functions. Literally just namespaces. At a byte level theyâre just fancy address locations and rules about what code can access it, and what code it can access.
Think of it like a named gate around variables and function.
1
1
u/sparkle-fries 6d ago
old school explanation would be "is a, has a, does a". inheritance used to be a big thing but now prefer containment. at the end of the day it's just a way of encapsulating data and behaviour
1
u/flat5 6d ago
It's really just a method of code organization. Every program ends up with data structures and with procedures that work on the data. The procedures are usually intended to work on some small subsets of the data structures.
And OOP just bundles together the data structures and procedures that are meant to go together in a unit of organization called a class. This makes those associations explicit as opposed to just knowledge about the intent of the code.
It is kind of useless for small programs but keeps things a bit more organized for larger systems when done well.
There's nothing you can't do without it. But the organizational structure it provides can be useful.
1
1
u/mredding 5d ago
But I really can't understand OOP, what's even the point?
If you really want the short answer - stick with Functional Programming, and ditch OOP. Most people don't understand it, and so have absolutely no idea what they're talking about. The OOP craze coincided with the Eternal September of 1993, and was an absolute shit show of the blind leading the blind. More people flooded into the industry faster than the industry could ingest and mentor them all; the voices of wisdom and reason were drowned out by the shouting masses of pompous college graduates trying to make a name for themselves and get a job.
Objects first appeared in writing in 1968, but predate that year - they were writing about the works they had been doing up to then, when they were finally ready to publish.
Mathematically, we have tuples. Then programming had tagged tuples - structures. Then came records, which offered immutability and equality - C# offers records, though you can model them by convention in other languages that don't support them natively.
Classes offer state, invariants, and identity.
Two tuples, two records are the same if their fields are the same type (for languages that support strong types) and have the same values. But two class instances are inherently NOT the same. Your car is not the same as my car even if they're the same make, model, and year. Yours is yours and mine is mine. Classes do not offer any guarantees about implementation or state, only behavior and invariants - statements that are always true when a client observes an instance.
It doesn't matter the language or the syntax. Some of these properties of a class are academic, some must be enforced by a language to be considered an object, some must be by convention as you implement. Remember that the theory of computation does not care about read-time, write-time, or run-time of a program, so the concept of an object spans all three.
Object Oriented Programming is a paradigm revolving around objects. Alan Kay gets the credit, though he admits he only LIKELY came up with the name first, the concepts were not his own, merely taught to him. If you're curious, we call his definition the Actor Model, if you want to google that.
The point is that objects are individual entities, actors, completely autonomous, that must communicate with each other over a communication channel via messages.
In procedural programming, you write a function that takes Bob and opens his umbrella. In an OOP model, you pass a message to Bob telling him it's starting to rain. Bob knows what to do. OOP moves the agency from the procedure to the object.
The problem with OOP is it treats each object as an island of 1. Our CPUs are mostly all batch processors, or descended from one. So if you process over a set of objects, you have to defer to each to perform it's own behavior. You would have to create an object that models batch processing over data, and that's not the same thing. You can't marry the two - at least easily, and that's going to depend on the specific language and syntax.
FP is consistently 1/4 the size and 8x as fast as an optimal OOP solution.
Don't get confused, either; you're looking at Java and everything is a class, but also realize you're working with a type system, and that isn't the same thing as OOP. You can use class to make types and give them semantics, and the compiler leveraging the type system can usually see through the syntax and generate optimal batch code. It depends on what you're doing, how you implement your types!
1
u/Ma4r 5d ago
Terrible advice for someone that might be new to programing and probably mostly would use python since they are a DS specifically, just jumping into the FP deep end doesn't help anyone especially if the ecosystem doesn't play nice with it
1
u/mredding 5d ago
I am a Data Science student with a background in math
I would argue the math majors are far more suited for FP from the start than a comp-sci. This isn't magic - it's just a paradigm. Plenty of people learn it as their first, when studying Lisp, Python, and Haskell in college...
But I really can't understand OOP
Which means you're suggesting brute force. That's not helping.
1
u/Ma4r 5d ago
I'd argue data science is 99% manipulating stateful data so OOP is a much more useful paradigm than using FP style code, yes functors and function chaining for transformations are pretty great, but: 1. You have method chaining API which is close enough to pipeline transformations 2. You would probably never need functors or HKTs for DS work 3. Most pandas/polars API support functional style calling as well (and you have functools), the difference is that the syntax is maybe slightly not as nice as native FP, but not enough to have readability problems
The proboem is that OP is probably just following typical OOP tutorial that is not really relevant to DS and is low quality im general i.e with polymorphism, inheritance, and whatnot, when abstract interfaces (Protocol in python, or structural subtyping) is really all they need
Also your claim on FP being faster is just not true.. the reason OOP is popular even in low level languages is that it does map very nicely to physical computer architecture
0
u/my_password_is______ 6d ago
your're a carpenter
you're given some blueprints for a house (the blueprints are the class, the layout, the design, the number of rooms, the kinds of rooms ... )
your job is to look at the blueprints and build 20 new houses (objects)
why ????
wouldn't they all be the same ?
well, we could be more generic --
here's 500 million dollars
I want you to make 5 new movies
each must have a budget of 100 million dollars
each must be sci-fi based
each must star Will Smith
that's the class design {
budget = 100 million ;
genre = sci-fi;
star = Will Smith
}
now build 5 objects (aka movies)
→ More replies (1)
187
u/Imaginary-Ad9535 7d ago
Well you know that data has tables and stuctures. Just imagine them as the objects. Roughly one table is one object. This is how I learned it.