CMUQ 15-121 Classes, Objects, and OOP
1. Introduction
While Python includes support for objects, you don’t actually need to use them in order to write a program. Java, however, is fundamentally object oriented. In Java, everything is an object.
Objects allow us to collect data and the actions that operate on that data into one entity.
- The data is called fields or instance variables. These are things the object needs to store.
- The actions are called methods. These are things an object needs to do.
A class provides the blueprint of what an object should look like. When you want to actually create one, then you create an instance of the class called an object.
Consider the following sample code for the hero in an adventure game. Our hero has two instance variables: hitPoints
(the amount of damage the hero can take until death) and an array of items
representing the inventory. There are also two methods: getHit
that deducts damage from the hit points, and isDead
that tells you if the hero is dead.
public class Hero { /* * This class has two instance variables */ private int hitPoints; private Item[] items; /* * This class had two methods */ public void getHit(int damage) { this.hitPoints -= damage; } public boolean isDead() { if (hitPoints <= 0) { return true; } else { return false; } } }
It is important to note that defining the Hero
class does not create an object. This is just the class, the blueprint for a hero. In order to instantiate a hero we need a line like Hero bob = new Hero()
. After that line runs, bob
is hero object. We create one from blueprint represented by the class.
2. Visibility Modifiers
You may have noticed that in most of the examples so far both methods and instance variables have keywords in front of them like public
and private
. These keywords impact which code, outside of the object, is allowed to access that item.
public
means that the item is accessible to anyone. So, for example, the two methods in ourHero
class above are public. Ifbob
is our object, then anywhere in the program that has a copy ofbob
can callbob.getHit(5)
, because thegetHit
method is public.protected
means that item is accessible to code in the same package, the same class, and even subclasses. (We’ll talk about subclasses later.)- If you don’t specify visibility, then it receives package-private. This means the item is accessible inside the package and inside the class.
private
means that data is only accessible inside the class.
2.1. Summary Table
Consider this table summarizing the visibility modifiers:
Modifier | Class | Package | Subclass | Everywhere Else |
---|---|---|---|---|
public |
X | X | X | X |
protected |
X | X | X | |
none used | X | X | ||
private |
X |
2.2. Conventions
There are a few rules about visibility followed by convention (meaning unofficial rules followed by most programmers):
- Instance variables should be
private
. If you need to access them from outside the class code (which is likely) you should write methods to facilitate this. - Methods that will be used from outside the class should be
public
. - Methods that will only be used inside the class should be
private
. Usually these are helper methods that you write to assist you when writing the public methods.
3. Constructors
Every class needs at least one constructor. A constructor is a special method that is used by the class to instantiate an object. Typically, the constructor allocates and initializes the instance variables. You can have more than one constructor, as long as the different constructors have different parameters. If you don’t include a constructor, then Java will automatically include a default constructor that does almost nothing.
Remember our hero class from above? Here it is again, this time with some constructors. Either constructor can be used to instantiate an object from the Hero
class.
public class Hero { /* * This class has two instance variables */ private int hitPoints; private Item[] items; /* * This class has two constructors */ public Hero() { this.hitPoints = 10; this.items = new Item[10]; } public Hero(int hitPoints) { this.hitPoints = hitPoints; this.items = new Item[10]; } /* * This class had two additional methods */ public void getHit(int damage) { this.hitPoints -= damage; } public boolean isDead() { if (hitPoints <= 0) { return true; } else { return false; } } }
4. Aside: Static
Let’s take a moment to talk about something else you’ve seen so far: static
. When a method or instance variable is declared static
that means that it is accessible as part of the class itself, not just as part of instantiated objects.
4.1. Static Methods
The most common reason to declare a method static
is because you are writing a helper function that is useful outside the class. For example, the Math
class provided by Java includes a number of static methods related to mathematics. If you want to take the power of something, you can simply call the pow
method of the Math
class directly: Math.pow(2,10)
. You don’t need to instantiate a Math
object before calling the method.
4.2. Static Instance Variables
The most common reason to declare an instance variable static
is because it is a constant that is useful outside the class. Returning to our Math
example, the Math
class has a static instance variable called PI
that stores the value of the mathematical constant \(\pi\). You can access it using Math.PI
without first needing to create an instance of a Math
object.
4.3. Main Method
You’ve seen a number of the examples so far include a main
method. The main
method is a special static
method. If you tell Java to execute a class, it searches that class for a main
method that is static
and calls that. This is how you specify which code should run first in your program.
The main method is always declared static using the following signature:
public static void main(String args[])