# 7 - Classes and Objects

## Are you just throwing out words now, what are Classes and Objects?
We are now getting into a powerful concept in programming in general that can be a little difficult to comprehend at first. The concept is called Object Oriented Programming, or OOP. Essentially what you're doing, is creating representations of a thing, and that things characteristics and behaviors, in code. The thing might be a real world object, it might not be, but to start out with, we're going to look at it from the context of creating real world objects in code, because that'll make the most sense. On top of that, a lot of the time spent Robot Programming is creating and manipulating representations of real world things in your code. 

Classes are templates, blueprints used to define what an object should have for characteristics (how big it is, how tall, how short, how fast, does it have teeth and if so how many, etc.) and behaviors (can it bite, does it dance, can it jump up and down, etc.). You can't have an Object without a class that comes before it, the class gives you the framework to build an Object. 

When making a class, the characteristics should be relevant to the Object you're wanting to represent, and the behaviors it needs to convey. Trees don't have teeth, so your class for a Tree shouldn't have anything referencing teeth, of the tree biting something. Likewise, a dog doesn't have leaves, so no need to write a behavior for the dog to make it photosynthesize light into sugar. 

Objects are created from classes. You fill in the characteristics you defined in the Class with values, keeping with the tree example, you might have values for the height of the tree, the diameter of the tree, the type of tree. All of those things are characteristics of a specific tree. You could create one tree that's 5 meters tall, .5 meters around, and is an Oak tree, while creating a completely different tree that's 2 meters tall, .15 meters around, and is a Maple tree. You can create many representations of the same type of Object from a single class. 

Now, representing trees in code, not so useful for our purposes. But once we get into Robot Programming, you'll have classes that create Objects that represent Motor Controllers, Sensors, the Driver's Station, Cameras, all kinds of stuff, all real world objects represented by structures in code. 

## What does a class definition look like?
Let's start off with this small class and talk about how it looks

```
class SomeClass():
    def __init__(self, someParameter, someOtherParameter):
        self.instanceVariable1 = someParameter
        self.instanceVariable2 = someParameter

    def doSomething(self):
        print(self.instanceVariable1)
        print(self.instanceVariable2)

    def doSomethingElse(self):
        return self.instanceVariable1 + self.instanceVariable2
```

Above, we start off by saying class <i>ClassName</i>(): this just defines what our class name is going to be so we can reference it later. 

Next, we have def __init__(self), this is our constructor. It's a special method (a set of code that can be called by name) that is used to build Objects based on the class we create. The names inside the parenthesis are called parameters, these are special variables that are used to pass information into methods from outside the class. Classes are meant to encapsulate the information they contain and hide it away from prying eyes unless it's accessed in some way through a behavior (a method). So parameters allow us to hand information in that wouldn't otherwise be there. 

The <i>self</i> parameter is important when building classes, because it stores our characteristics (also called instance variables) that we to contain inside of our created objects. You'll notice that in all methods in our class, not just __init__, self is a parameter. This is how the other methods (behaviors) in our resulting objects will be able to access the instance variables we set up in __init__ for later use. 

The other methods (behaviors) <i>doSomething</i> and <i>doSomethingElse</i> are the actions that our created objects will be able to take. You get to define how this behaviors work, and you can have as many or as few as are necessary to make your representation work the way you want it to. 

Notice for a moment in <i>doSomethingElse</i> there is a <i>return</i> statement. Return makes it so that the behavior produces a value, you can take that value, much like you would from a method like input() and store it in a variable. We'll see this when we look at creating an object down below. 

## So how do I create an Object from a Class?
Well, lets assume for the moment that we defined SomeClass in a file called OtherClasses.py, using that information, lets look at the code below:

```
import OtherClasses

thisIsSomeClass = OtherClasses.SomeClass(1, 2)
thisIsSomeClassAgain = OtherClasses.SomeClass(3, 4)

print(thisIsSomeClass.doSomethingElse())
print(thisIsSomeClassAgain.doSomethingElse())
```

First, we import the OtherClasses file by name, this makes SomeClass available to us to use. Then, we create two variables, thisIsSomeClass and thisIsSomeClassAgain, and create two different representations of SomeClass, the first using the values 1 and 2, the second using 3 and 4. 

By doing this, we've created two Objects from the same class that will produce different results when asking each separate object to do something. 

The first print statement deals with thisIsSomeClass, which has 1 and 2 for values. We saw above that doSomethingElse returns the sum of the instance variables we created, those instance variables have the values we pass in as parameters when we create an Object using SomeClass, in this case, the values 1 and 2. So when doSomethingElse runs, it will return, in this case, the value of 1 + 2, which is three. So the line print(thisIsSomeClass.doSomethingElse()) will print 3 to the console.

The next line is similar but not the same, because now we're dealing with the Object stored in thisIsSomeClassAgain, that Object was created using 3 and 4, we call doSomethingElse for that Object too, which adds 3 + 4, to get 7. So the line print(thisIsSomeClassAgain.doSomethingElse()) will print 7 to the console.

## This feels like a lot of information, is this a lot of information?
It is, Classes and Objects can do so much, even more than what has been demonstrated in this lesson. It's a hard concept to convey quickly. For Robot Programming, at least at the beginner to low intermediate levels, an in depth understanding of Classes and Objects isn't super important, but it's good to know they exist, because once you decide to start making more complex robot programs, it may make sense to move certain aspects of your code into a class/object type of structure. On top of that, certain styles of Robot Programming require you to create many different classes (and subsequently, many different objects) in order for your robot to work. Take this early introduction to Classes and Objects into memory and hold onto it, even if you couldn't quite make this setup yourself for your own real world object if you wanted to, again, it's still good to have a general idea of what they are, because they will show up in your robot code, even if you don't realize in the moment that's what you're looking at. 