Author Topic: Let's learn OOP!  (Read 14010 times)

0 Members and 1 Guest are viewing this topic.

Offline FinaleTI

  • Believe in the pony that believes in you!
  • CoT Emeritus
  • LV10 31337 u53r (Next: 2000)
  • *
  • Posts: 1830
  • Rating: +121/-2
  • Believe in the pony that believes in you!
    • View Profile
    • dmuckerman.tumblr.com
Re: Let's learn OOP!
« Reply #15 on: March 15, 2011, 04:40:23 pm »
I like it. It's a pretty good explanation, I think.
I learned OOP in Java for my AP class not all that long ago.


Spoiler For Projects:

My projects haven't been worked on in a while, so they're all on hiatus for the time being. I do hope to eventually return to them in some form or another...

Spoiler For Pokemon TI:
Axe port of Pokemon Red/Blue to the 83+/84+ family. On hold.

Spoiler For Nostalgia:
My big personal project, an original RPG about dimensional travel and a few heroes tasked with saving the world.
Coding-wise, on hold, but I am re-working the story.

Spoiler For Finale's Super Insane Tunnel Pack of Doom:
I will be combining Blur and Collision Course into a single gamepack. On hold.

Spoiler For Nostalgia Origins: Sky's Story:
Prequel to Nostalgia. On hold, especially while the story is re-worked.

Offline calcdude84se

  • Needs Motivation
  • LV11 Super Veteran (Next: 3000)
  • ***********
  • Posts: 2272
  • Rating: +78/-13
  • Wondering where their free time went...
    • View Profile
Re: Let's learn OOP!
« Reply #16 on: March 15, 2011, 04:56:46 pm »
Yeah, it's a good explanation. :)
Java and C# are on pretty equal ground if we want to compare them.
"People think computers will keep them from making mistakes. They're wrong. With computers you make mistakes faster."
-Adam Osborne
Spoiler For "PartesOS links":
I'll put it online when it does something.

Offline Compynerd255

  • LV6 Super Member (Next: 500)
  • ******
  • Posts: 336
  • Rating: +53/-4
  • Betafreak Games
    • View Profile
    • Betafreak Games
Re: Let's learn OOP!
« Reply #17 on: March 15, 2011, 05:32:12 pm »
I'm glad you like my explanation. What I wrote up there is just the surface of OOP. There are a lot of other cool topics you can learn about, such as:
  • Properties (set conditions on access to variables)
  • Inheritance and polymorphism (make one class act like another class)
  • Types and type casting (convert one variable type to another)
  • Namespaces and libraries (subassemblies)
  • Reference and value types
  • Interfaces

Just let me know what you would like to know about, and I'll write a short explanation.
« Last Edit: March 15, 2011, 05:32:54 pm by Compynerd255 »
The Slime: On Hold, preparing to add dynamic tiles

Axe Eitrix: DONE

Betafreak Games: Fun filled games for XBox and PC. Check it out at http://www.betafreak.com



Offline AngelFish

  • Is this my custom title?
  • Administrator
  • LV12 Extreme Poster (Next: 5000)
  • ************
  • Posts: 3242
  • Rating: +270/-27
  • I'm a Fishbot
    • View Profile
Re: Let's learn OOP!
« Reply #18 on: March 15, 2011, 05:43:39 pm »
Now, you might be asking: Why would I ever want to use this? There are two main reasons you would.
First, while it might be easier to manage one ship in low level programming, how about managing 100 of them? To track down all 300 variables, even in a list, would be unbearable, especially if you decided later that ships also need to have health or something. However, if you create a list of Ships, you can manage each ship individually.
Second, objects encapsulate things that you just don't want to manage, or want to protect somehow. For example, our Ship had a subroutine called Move on it to move the ship forward. Instead of having to remember sines and cosines every time a person wanted to move the ship, they could just set the rotation and movement amount and just say "Move". OOP also lets you hide variables that an object needs to know about, but not the rest of the game.

And objects have real-life applications as well, more so than in games. For example, you might want to create an object called CALCnet that manages calculator linking. By using this object, you don't have to worry about all of the little details and issues with CALCnet. All you have to do is start it up, shut it down, and tell it to send frames to people.

I don't think I understand the purpose of OOP. Why would you use data abstraction and encapsulation for something like, to use your example, updating ships? Since you're presumably only manipulating a single ship at a time, wouldn't it be more logical to maintain an array of data about all ships. The data about that ship could be loaded into the variables you're manipulating and then reloaded into the array when you're done. It could actually work out very easily if you use "pointers" to the data in the array and a simple subroutine to manipulate the pointers and simultaneously updating the data in the array. It seems like encapsulating the ship data just pushes the mechanics of the program onto the interpreter/compiler. That certainly makes things easier to manage, but computers also have a tendency to write less efficient code than humans.

Also, I genuinely don't understand why you would want local variables. Doesn't that make things confusing when the variable "ShipSpeed" is used differently by three different subroutines? Plus, the OS/program has to maintain a table of all of the local variables, look them up, retrieve them from memory, and swap the appropriate ones in when necessary. That's not a lot of overhead, but it might not be suitable for high speed applications. It would also appear to be less memory efficient than maintaining global variables and being careful not to modify them.

PS: Your "Calcnet" example seems to be similar to calling another program or subroutine.
« Last Edit: March 15, 2011, 05:45:41 pm by Qwerty.55 »
∂²Ψ    -(2m(V(x)-E)Ψ
---  = -------------
∂x²        ℏ²Ψ

Offline Compynerd255

  • LV6 Super Member (Next: 500)
  • ******
  • Posts: 336
  • Rating: +53/-4
  • Betafreak Games
    • View Profile
    • Betafreak Games
Re: Let's learn OOP!
« Reply #19 on: March 15, 2011, 06:07:31 pm »
I don't think I understand the purpose of OOP. Why would you use data abstraction and encapsulation for something like, to use your example, updating ships? Since you're presumably only manipulating a single ship at a time, wouldn't it be more logical to maintain an array of data about all ships. The data about that ship could be loaded into the variables you're manipulating and then reloaded into the array when you're done. It could actually work out very easily if you use "pointers" to the data in the array and a simple subroutine to manipulate the pointers and simultaneously updating the data in the array. It seems like encapsulating the ship data just pushes the mechanics of the program onto the interpreter/compiler. That certainly makes things easier to manage, but computers also have a tendency to write less efficient code than humans.

Also, I genuinely don't understand why you would want local variables. Doesn't that make things confusing when the variable "ShipSpeed" is used differently by three different subroutines? Plus, the OS/program has to maintain a table of all of the local variables, look them up, retrieve them from memory, and swap the appropriate ones in when necessary. That's not a lot of overhead, but it might not be suitable for high speed applications. It would also appear to be less memory efficient than maintaining global variables and being careful not to modify them.

PS: Your "Calcnet" example seems to be similar to calling another program or subroutine.
First, as my example shows, if you don't use OOP programming, you would simply keep a multidimensional array of all of the properties of each of the ships. Now, if you have already defined what you want the ship to do, that's fine. But what if you want to add a property to the ship? You would have to change all of your array offsets to fit the new ship! However, if you instead kept an array of Ships, then adding a property isn't a problem.

Private variables are another important thing. For the Ship class, we don't really need any local variables. A better example of where you would need private variables is in a networking class. You don't want to have to tell the program to connect to such and such a port or use such and such a timeout. But the network class needs to know about these things. So, when you write the networking class, all of the little details are hidden from you, so all you have to worry about is doing things with the network. Private variables also prevent you from making foolish mistakes, like modifying variables you shouldn't be.

Also, what classes help us do is make code more portable and mobile. In non-OOP, a lot of pieces of code are interweaved and hard to seperate when you want to use them somewhere else. If you use OOP right, you can take that class into another application and use it again. For example, you might have a method that draws all of the game objects to the screen. However, if you are developing for multiple problems, you might want multiple "DrawTool" classes that respond to different protocols (e.g. one that draws on an 89, one that draws on an old PC, and one that draws on an XBox).
« Last Edit: March 15, 2011, 06:23:29 pm by Compynerd255 »
The Slime: On Hold, preparing to add dynamic tiles

Axe Eitrix: DONE

Betafreak Games: Fun filled games for XBox and PC. Check it out at http://www.betafreak.com



Ashbad

  • Guest
Re: Let's learn OOP!
« Reply #20 on: March 15, 2011, 07:28:52 pm »
I love his explanation, was more well thought out than mine ^-^

Well then, maybe I should introduce inheritance?

What is inheritance?  speaking in vague terms, it's the relations between classes.  In example: let's say you have a quadrilateral class, but then you say 'Oh my, what if I want to relate shapes such as squares and rhombuses that are quadrilaterals but with special ways to calculate their areas and perimeters and such?  No probs -- this is where inheritance can be our friend ;)

You see, think of it like this:  All squares are quadrilaterals, but are all quadrilaterals squares?  Usually not.  So, they share many features such as 4 sides, a total of 360 degrees in internal angles sum, and such.  But squares have some other things that define them:  All sides are equal (always), all angles are Right angles, all lines are perpendicular, Area is S^2, etc.  So, how can we make the square inherit some of these basic qualities from class quadrilateral?  By declaring it a subclass!

Code: (Java) [Select]
public class Square extends Quadrilateral {
  private int[] sideLengths;
  private float[] angles;
 
  public void Square(float sideLength) {
    sideLengths = new int[4] = { sideLength, sideLength, sideLength, sideLength,};
    angles = new float[4] = { 90.0f, 90.0f, 90.0f, 90.0f};
  }

  @override
  public int Area() {
    return sideLengths[0]^2;
  }
}

As you can see, this class now extends class Quadrilateral.  Also, pretend class quadrilateral contains a Area() method that returns the area of the figure.  This is where a new thing comes in: @override.  While this is (usually) only found in Java (EDIT: I mean the @override operator, not the fact of overriding, which is actually found in almost all OOP languages), it just denotes an overriding of a super's method.  Now, if you don't understand half of the terms I just said, that's fine.  Here's a list.  Go study it for 3 hours:

- Super: refers to the class that is the superclass of the one you're working in.  In this example, class Quadrilateral.
- Overriding methods:  When you extend a class to another one, you inherit all of the methods that the super contained (besides the constructor, which actually can be overridden, but don't worry about that now.)  When you override the method, you make the method do something specific to your sub class -- in this case, instead of working a long formula to calculate the polygon's area, you can simply calculate one of the side's length squared.

[will continue later, gotta eat >.<]
« Last Edit: March 15, 2011, 07:57:19 pm by Ashbad »

Offline calcdude84se

  • Needs Motivation
  • LV11 Super Veteran (Next: 3000)
  • ***********
  • Posts: 2272
  • Rating: +78/-13
  • Wondering where their free time went...
    • View Profile
Re: Let's learn OOP!
« Reply #21 on: March 15, 2011, 07:45:03 pm »
Encapsulation and polymorphism (along with inheritance) are probably the key features of OOP. They make your code modular, flexible, extensible, and many other things.
Encapsulation (namely private variables) allows you to ignore the inner workings of another class/object and use the methods it provides. It frees you from having to deal with all the underlying things directly (like the networking and display examples) and allows delegation of tasks.
Polymorphism and inheritance also allow a common interface to classes. Example (Java):
Code: [Select]
abstract class IntegerOperation {
    public abstract int selfOperation();
    public abstract int binaryOperation(int otherArgument); //"abstract" just means that I'm not defining these methods
}
//IntegerOperation is a class that names two methods, selfOperation() and binaryOperation(int), that both return an int
//It is extended twice here:
class IncrementAdd extends IntegerOperation {
    public int number;
    public int selfOperation() {
        return number+1;
    }
    public int binaryOperation(int otherArgument) {
        return number+otherArgument;
    }
}
//Also here:
class DecrementSubtract extends IntegerOperation {
    public int number;
    public int selfOperation() {
        return number-1;
    }
    public int binaryOperation(int otherArgument) {
        return number-otherArgument;
    }
}
//And the main code here:
public class Main {
    public static void main(String[] args) {
        IntegerOperation intOp = new IncrementAdd();
        intOp.number = 5;
        System.out.println(intOp.selfOperation()); //Prints 6
        intOp = new DecrementSubtract();
        intOp.number = 20;
        System.out.println(intOp.binaryOp(13)); //Prints 7
    }
}
So, despite the two methods having different definitions in the two classes, we can use each as an IntegerOperation and invoke its methods. Yay polymorphism! :)
Note: And yeah, we're trying to sell you OOP :P
Edit: And this was written before Ashbad's post. It demonstrates inheritance and polymorphism.
"People think computers will keep them from making mistakes. They're wrong. With computers you make mistakes faster."
-Adam Osborne
Spoiler For "PartesOS links":
I'll put it online when it does something.

Ashbad

  • Guest
Re: Let's learn OOP!
« Reply #22 on: March 15, 2011, 07:55:43 pm »
yay polymorphism!  good addition to the thread, I must say ^-^ very nice indeed :)

This is one of the more complex and hard to learn portions of OOP, so it's fine if you people who are learning as we post along don't get it yet.  You will.  Oh yes, you will.

Offline Binder News

  • LV8 Addict (Next: 1000)
  • ********
  • Posts: 785
  • Rating: +46/-3
  • Zombie of Tomorrow
    • View Profile
Re: Let's learn OOP!
« Reply #23 on: March 15, 2011, 08:11:58 pm »
I'll take a stab at Dynamic Memory.

Lets say you need to have a bunch of Contacts for your email account. Obviously, you don't know at compile-time how many Contacts the user will have.
With OOP, I can just say:
Code: [Select]
ArrayList<ContactInfo> contacts = new ArrayList<ContactInfo>();
for (int i=0; i<(# of contacts); i++)
{
    contacts.add(new ContactInfo(name,email,phoneNumber));
}
An ArrayList automatically changes its size when you add or remove objects. I could create 100 Contacts or 5, and it wouldn't matter.
I can also insert one in the middle with ease. Wouldn't that be a nightmare in ASM? :)
Spoiler For userbars:







Hacker-in-training!   Z80 Assembly Programmer     Axe Programmer
C++ H4X0R             Java Coder                           I <3 Python!

Perdidisti ludum     Cerebrum non habes

"We are humans first, no matter what."
"Fame is a vapor, popularity an accident, and riches take wings. Only one thing endures, and that is character."
Spoiler For Test Results:





Offline calcdude84se

  • Needs Motivation
  • LV11 Super Veteran (Next: 3000)
  • ***********
  • Posts: 2272
  • Rating: +78/-13
  • Wondering where their free time went...
    • View Profile
Re: Let's learn OOP!
« Reply #24 on: March 15, 2011, 08:15:48 pm »
Binder hinted at them, so who wants to do generics? ;D
Binder: just a personal preference, but I would declare contacts as a List<ContactInfo> (obviously it's still an ArrayList<ContactInfo>, but it encourages you to type your methods and other code for the more generic List<ContactInfo> (and it lets you quickly swap ArrayList<> for another type of List<> if need be). Others may differ.
« Last Edit: March 15, 2011, 08:16:05 pm by calcdude84se »
"People think computers will keep them from making mistakes. They're wrong. With computers you make mistakes faster."
-Adam Osborne
Spoiler For "PartesOS links":
I'll put it online when it does something.

Offline Binder News

  • LV8 Addict (Next: 1000)
  • ********
  • Posts: 785
  • Rating: +46/-3
  • Zombie of Tomorrow
    • View Profile
Re: Let's learn OOP!
« Reply #25 on: March 15, 2011, 08:22:37 pm »
I know, I was just keeping it simple. I'll take generics as well.

Generics give you the ability to write code to handle a wide range of problems.
Instead of having to make one array class for Dogs, one for Cats, and one for Birds, I can just do:
Code: [Select]
List<Dog> = new ArrayList<Dog>();
List<Cat> = new ArrayList<Cat>();
List<Bird> = new ArrayList<Bird>();
All I have to do is change two words, and it will take care of all the details. :)
It won't even let me put a Dog into a List of Cats. Why? They aren't the same type. :)
THAT would be hard in ASM (the type-checking I mean).

...

Or maybe not. But it's still a lot less code. :)

Spoiler For userbars:







Hacker-in-training!   Z80 Assembly Programmer     Axe Programmer
C++ H4X0R             Java Coder                           I <3 Python!

Perdidisti ludum     Cerebrum non habes

"We are humans first, no matter what."
"Fame is a vapor, popularity an accident, and riches take wings. Only one thing endures, and that is character."
Spoiler For Test Results:





Ashbad

  • Guest
Re: Let's learn OOP!
« Reply #26 on: March 15, 2011, 08:23:45 pm »
I see you used the Diamond operator there ^-^ a Java exclusive, so methinks.  I think I might as well explain that too :)

you see, the diamond operator basically adds General Types to a class that can be defined during instantiation.  This is actually something I learned on my own today with the Java tutorials!! w00t.  I'm a fast learning learner mesothinks.

Anyways, this is defined as the practice of Generics.  Basically, they can do a numbar of things to assist in the instantiation of classes and defining in a more specific way what exactly the class describes.  The <> operator is used to denote the generics associated with that class.  Like so:

Code: (Java) [Select]
public class Generics<T> {
  private T t;
  public void Generics() {
    t = new T();
  }
}

this sets up a class so that it will accept a generic, T, to fill in the spots denoted by T.  You can even think of it as a 'variable' for a currently undefined type of class.  Let's call the class here:

Code: (Java) [Select]
Generics<Lobstar> blueLobster = new blueLobster<Lobstar>();
this would make the instance blueLobster have a class framework that looks like this:

Code: (Java) [Select]
public class Generics<Lobstar> {
  private Lobstar t;
  public void Generics() {
    t = new Lobstar();
  }
}

as you can see, this can be very useful in a variety of applications - especially in a case like binder's where you can create a list of a Generic type, and the type can be of your choosing at instantiation.

I know it's rough, but it's not an easy topic to learn x.x  especially the advanced features I purposely left out because I'm still self-learning them.

Offline uberspire

  • LV3 Member (Next: 100)
  • ***
  • Posts: 61
  • Rating: +57/-0
    • View Profile
    • Uberspire
Re: Let's learn OOP!
« Reply #27 on: March 15, 2011, 08:33:13 pm »
I see you used the Diamond operator there ^-^ a Java exclusive, so methinks.  I think I might as well explain that too :)
Java uses the diamond operator for generics, which came from C++'s usage of the diamond operator for templates. Perl also has a diamond operator, however it's used differently.

Offline calcdude84se

  • Needs Motivation
  • LV11 Super Veteran (Next: 3000)
  • ***********
  • Posts: 2272
  • Rating: +78/-13
  • Wondering where their free time went...
    • View Profile
Re: Let's learn OOP!
« Reply #28 on: March 15, 2011, 08:36:59 pm »
An example generic class, with two methods, display() and setThing(T):
Code: [Select]
class GenericClass<T> { //T stands for a certain class. Could be anything.
    public T thing;
    public void display() {
        System.out.println(thing.toString());
    }
    public void setThing(T thing) {
        this.thing = thing; //this.thing refers to the thing in this object, not the argument thing
}
public class Main {
    public static void main(String[] args) {
        GenericClass<String> test = new GenericClass<String>();
        test.setThing("Hello World!");
        test.display();
        GenericClass<Object> test2 = new GenericClass<Object>();
        test.setThing(new Object());
        test.display();
    }
}
So we use GenericClass in two ways: one where T is String, the other where T is Object. When you do that, you can pretty much pretend that all the T's in the class definition were replace with either String or Object. :) setThing(T) works as either setThing(String) or setThing(Object) depending on whether the object is a GenericClass<String> or GenericClass<Object>.
Generics are extremely powerful, and C#, C++, Java, and possibly others have them.
Edit: Is it really called the diamond operator? Also, aren't generics like templates?
"People think computers will keep them from making mistakes. They're wrong. With computers you make mistakes faster."
-Adam Osborne
Spoiler For "PartesOS links":
I'll put it online when it does something.

Offline Binder News

  • LV8 Addict (Next: 1000)
  • ********
  • Posts: 785
  • Rating: +46/-3
  • Zombie of Tomorrow
    • View Profile
Re: Let's learn OOP!
« Reply #29 on: March 15, 2011, 08:38:18 pm »
Time for another mini-lesson. The topic: Run-Time Type Information (RTTI)

So let's say you made this awesome editor for something. Now you want to allow people to write PLUGINS for it.
But oh noes, you wrote it in C++. Kinda tricky adding this in later, isn't it? You'll have to have some way for the editor to load plugin, DYNAMICALLY!
So, I could place Suzie's plugin in the plugins folder, and Bob's, and it would find them both and load them. But what if you change the API, or something. And how will you load the DLL?
Easy with Java/C#. Because they are compiled into ASM at RUNTIME, any libraries can be found, compiled, and used at RUNTIME! All you have to do is load the class file, and you can use the class. Also, if the plugin was built against an API, the API will be available because the API libraries/program was the first thing to be loaded. A great example is Bukkit.
Spoiler For userbars:







Hacker-in-training!   Z80 Assembly Programmer     Axe Programmer
C++ H4X0R             Java Coder                           I <3 Python!

Perdidisti ludum     Cerebrum non habes

"We are humans first, no matter what."
"Fame is a vapor, popularity an accident, and riches take wings. Only one thing endures, and that is character."
Spoiler For Test Results: