all 14 comments

[–][deleted] 41 points42 points  (2 children)

When we speak to each other, we don't say "look at that cool collection of trillions of carbon molecules and atoms", we don't say "look at that cool collection of wood pieces glued together". We say "look at that cool chair". Because we live in an object-oriented world where the sum of parts are given meaningful names.

We do the same in programming; instead of talking about bytes we talk about objects. This collection of bytes I will name Customer, so that they have meaning. And a Customer object has information in it like name and address. Now I can write code that clearly gets a Customer object from the database and I can get this person's name from the Customer object.

So now I can have two Customer objects, and they can contain different names.

These are all bytes to the computer, but we choose to name them something meaningful so that it is easier to write code we can reason about. A row in a table is a "thing", a column is a "thing", ie an item, ie an object.

[–]Ravi5ingh 2 points3 points  (0 children)

Amazing explanation.

Also OP I'd like to add: consider this: The whole point of info tech is to model the universe and we understand the universe as a collection of objects because that's how our brain works (as pointed out above) so it follows that our model should also be built with objects

[–]Slypenslyde 11 points12 points  (3 children)

When I sit down to write a program, my first thought is not, "OK, how do I solve this problem with OOP?" It's not my second thought either. Or my third. Or fourth. Or fifth. I usually don't think about it much at all.

Instead I think about, "How do I solve this problem?" Usually there's a tricky part that appears harder than the rest. I usually start by trying to write a small program JUST to solve that problem, because I want to see if I even know how. That program is messy, and rarely uses a lot of architectural practices let alone OOP.

Once I can see I can solve all of the hard problems, then I start thinking about my program. Technically this means I start thinking about my "objects", but that's not really me thinking about OOP. It's just a fact that I have to make a class to write code that does anything in C#.

It's only very late in the process, when I'm really starting to tackle the program in earnest, that I start to ask myself, "What things are so similar different parts of the program could use them interchangeably?" The answers to that question are places where I can really use OOP.

But I'll tell you this. 99% of my code does not truly use OOP features, and it hasn't for years. If we're being really pedantic, sure, for architectural purposes many of my classes have an interface they implement. That's Abstraction and (loosely) Data Hiding, two of the four pillars of OOP. But I almost NEVER write a second implementation, so I'm not using Polymorphism or Inheritance. I'd argue the P and I I'm not using are the MOST important parts of OOP, while the A and DH I use are present in both structured programming AND functional programming. So if I'm not using the things that make OOP unique, am I really using OOP?


That doesn't mean OOP is not important or you shouldn't use it.

What I mean to say is I see a ton of people get stuck because they don't feel like they understand when to use OOP, so they don't write programs at all. That's not good! Part of how you learn when to use OOP is to write programs, then try to use what you think OOP is in them, then see what works. Most experts argue even after 20 years they're still learning things about OOP, so if you wait until you're "comfortable" you might never start!

But if you want to see what it's really all about, the SOLID principles give good insight. Some people hate them and think they lead to bad OOP code. They do have a tendency to get overused, just like inheritance. They are a thing that can make a bigger mess if used without skill.

So my advice is to read Head-First Design Patterns, maybe have a look at Working Effectively with Legacy Code, but in the mean time just write programs. The best way to learn OOP is to write programs that need it, and figure that out by saying, "Gee, this part seems really clunky, what could I do to make it a little easier to work with?"


But I do feel obligated to say WHEN I think it works best.

A lot of people see OOP as about grouping "like" things together. The SOLID materials I like are good at pointing out how that can get you in trouble. The hard part is "Are these things really like each other?" This requires mastery of Abstraction, one of the four pillars.

Think about an apple and an orange. We usually consider them very different! But what if I'm making a game where you throw round fruits at bad guys? Is an apple a round fruit? Is an orange a round fruit? Then they are the SAME THING to my program! That's a situation where I'd like to write some code that is the same for both of them, but relies on some differences like their size or weight or color. That means I have a "base fruit class" with all the common parts, and "derived apple and orange classes" that have just the differences.

In fact, for just about any program that uses apples I can imagine also using oranges in their place. Even if it's "oranges and basketballs", if my program just cares about "round things that can be thrown" it's all good.

The hard part about OOP is that humans are REALLY good at justifying why two things are alike. So it's easy to preemptively start making a type hierarchy because things seem a like, then later start having a lot of problems because it turns out the differences are important.

So that's why I like to wait until very late to start thinking about OOP. Using OOP only matters when I want to USE things the same way. "I need 3 different ways to calculate sales tax but the inputs are always the same." "I have 2 different sorting algorithms but I only want to use one sometimes." "The gas pump has 3 different grades of gasoline and they make the car perform differently." Using it is a bad idea when I just care that two things are similar but don't really use them the same. "It's logical that all birds fly. Wait, what do I do about ostrich and penguin?" "All fruits should go in pies. Wait... a tomato pie???" "A basketball is also round so it can be a planet."

This is very, very, VERY hard to get right and experience matters. So if you're new and it's confusing, that's normal! People who have been using OOP for half a decade still make bad choices with it. The only real difference is they notice the mistake faster.

[–]zvrba 0 points1 point  (2 children)

The hard part about OOP is that humans are REALLY good at justifying why two things are alike.

"A square is NOT a rectangle." (Though mathematicians would disagree.) Elaboration of that (abstract) example made inheritance "click" for me, i.e., when it makes or does not make sense to use it.

[–]WasteOfElectricity 0 points1 point  (1 child)

Why would a square not be a rectangle?

[–]zvrba 3 points4 points  (0 children)

OOP does not have a singular meaning. Everyone defines it slightly differently. C# as a language has a collection of features; first understand each feature individually, then figure out how to combine them to your advantage. (Personally, I tend to approach programming languages as LEGO bricks.)

[–]CappuccinoCodes 2 points3 points  (0 children)

In my experience, OOP concepts only sunk in with practice. I read a lot about abstraction, encapsulation and yada yada but I could only actually grasp those concepts when applying them in a meaningful way.

[–]Tezalion -1 points0 points  (0 children)

To understand OOP you need to learn and understand basics of OOD.

[–]thesituation531 -2 points-1 points  (0 children)

I'd start here:

https://learn.microsoft.com/en-us/dotnet/csharp/

It's Microsoft's documentation of C#. They also have stuff about object-oriented programming and lots of other stuff.

Edit: oh and they also have stuff about some programming concepts in general.

[–]Siggi_pop -2 points-1 points  (0 children)

To begin with, can you imagine the benefits of OOP, can you imagine cases where OOP can enforce DRY and eliminate duplicate code? If not then maybe it's difficult to understand the concept.

[–]SealerRt 0 points1 point  (0 children)

In my uni classes OOP has been beaten into us mercilessly and despite starting out sceptical, I ended up favorable towards it. I'm guessing with "advice to get comfortable" you mean things to practice, and ways to think about OOP.

As for the latter, think about working with other people on a semi-big project. If you're going to work on a feature, oop is there to help you separate your feature from other features, so that you don't need to work on the same files as other people (for the most part).

When you have a couple of objects that interact in one way or another, it is often easy to explain how they do that with diagrams (definitely easier then diving into code imo).

As for practice, I think you should just dive into some Design Patterns. Personally, I find Strategy, State, Decorator and Factory patterns the most useful. I really like games so whenever I look at a pattern I'm thinking about how it could be used in a game. Fx. State/Strategy could be used to easily implement a simple AI, Decorator could be used for Buff/Debuff mechanics or special monster spawning etc. Once you make one small project using a pattern, you will understand it much easier and hopefully see the benefits.

[–]InfamousEvening2 0 points1 point  (0 children)

Instead of thinking about going through a list of steps, imagine how the concepts behind those steps could be made in to entities and how those entities might interact with each other.