Lesson 0.1: Classes, Objects, and DRY Code
A robot program may begin as a few lines in one file. As the robot gains an arm, a claw, and a second autonomous routine, the same motor rules may appear in several places. A repair in one file can then leave the other copies unchanged.
Object-oriented programming, usually shortened to OOP, organizes those parts into classes. A RobotArm object can store its own field values and provide methods for arm behavior. TeleOp and autonomous can use the same class instead of maintaining separate copies of its rules.
This is one way to keep code DRY: Don't Repeat Yourself. DRY does not prohibit similar-looking lines. It means that an important rule should usually have one implementation.
Classes and Blueprints
Imagine that a team designs a robot arm on paper.
- The drawing includes a name and current power for each arm.
- It specifies how an arm starts, moves, stops, and reports its status.
- The drawing is not a physical arm. It is the plan used to build arms.
That plan is the class. An arm built from it is an object.
| Class | Object |
|---|---|
| A plan written in code | One working instance created from that plan while the program runs |
| Describes the fields and methods its objects will have | Keeps its own field values |
Example: RobotArm | Example: the object referred to by frontArm |
| Usually written once | Can be created zero, one, or many times |
An object is also called an instance of a class. frontArm and rearArm can be two different instances of the same RobotArm class. They share the same method definitions, but each object stores its own name and power.
A cookie cutter is the class. Each cookie produced with it is an object. Changing the frosting on one cookie does not change the others, just as changing one object's fields does not automatically change every object of that class.
A RobotArm Class
public class RobotArm {
private String name;
private double power;
public RobotArm(String name) {
this.name = name;
this.power = 0.0;
}
public void move(double requestedPower) {
power = requestedPower;
}
public void stop() {
move(0.0);
}
public String status() {
return name + " power: " + power;
}
}
This class contains fields, a constructor, and methods.
Fields and Object State
private String name;
private double power;
A field is a variable that belongs to an object. Every RobotArm has its own name and power. Together, those stored values make up the object's state.
private protects these fields from direct changes by unrelated code. The class's own methods remain responsible for keeping the state valid.
Constructors and New Objects
public RobotArm(String name) {
this.name = name;
this.power = 0.0;
}
A constructor has the same name as the class and no return type, not even void. It runs when new creates an object.
The parameter and field are both named name. this.name means "the name field on this object," while the plain name on the right is the value passed into the constructor.
Methods and Object Behavior
public void move(double requestedPower) {
power = requestedPower;
}
A method is a named piece of behavior that belongs to a class. It can receive inputs called parameters, change fields, call another method, or return a result.
movereceives adoubleand changes the object's state.stopcallsmove(0.0)so the power-setting rule remains in one place.statusreturns aStringto the caller.
That stop method is a small example of DRY code. It reuses move instead of creating a second way to update power.
Creating Objects from a Class
The RobotArm class is a definition. These lines create two objects from it:
RobotArm frontArm = new RobotArm("front");
RobotArm rearArm = new RobotArm("rear");
frontArm.move(0.75);
rearArm.move(-0.40);
System.out.println(frontArm.status());
System.out.println(rearArm.status());
Read the first line from right to left:
new RobotArm("front")creates a newRobotArmobject.- Java runs the
RobotArmconstructor with"front"as its argument. - The variable
frontArmstores a reference to that object.
The dot in frontArm.move(0.75) selects the move method on the object referenced by frontArm. The two objects use the same move definition but update different power fields.
An object variable normally stores a reference that tells Java where the object is. Two variables can refer to the same object, and a variable can temporarily refer to no object by containing null. Lesson 0.2 follows those references while code runs.
Reusing One Implementation
Without a mechanism class, several OpModes might each contain their own arm power limits, stop rules, and status formatting. One file may later be fixed while another is forgotten.
With a RobotArm class, each OpMode can use the same public operations:
RobotArm arm = new RobotArm("main arm");
if (gamepad1.left_stick_y < -0.1) {
arm.move(0.75);
} else {
arm.stop();
}
The OpMode determines when the arm should move. The RobotArm class contains how that movement works. If the arm later needs a safety limit, the team can add it to move once, and every OpMode using the method receives the change.
A class does not make code DRY by itself. Five copied methods inside a class are still five copied methods. The relevant question is which class should contain the shared implementation.
Important Java Words
| Term | Meaning in this lesson |
|---|---|
class | Declares a new class definition. |
new | Creates an object and runs its constructor. |
this | Refers to the current object whose method or constructor is running. |
public | Allows code outside the class to use the declared class, constructor, field, or method. |
private | Restricts a member to code inside its own class. |
void | Says that a method returns no value. |
return | Ends a method and can send a value back to its caller. |
static | Makes a member belong to the class itself instead of to each object. |
final | Prevents a variable from being assigned a different value after initialization. |
String is a class supplied by Java, while double, int, and boolean are primitive data types. Class names conventionally begin with an uppercase letter. Variables and methods conventionally begin with a lowercase letter.
Most Java files contain one public class, and the filename matches it. A public class RobotArm normally lives in RobotArm.java.
Check Your Understanding
Consider this code:
RobotArm left = new RobotArm("left");
RobotArm right = new RobotArm("right");
left.move(0.5);
Try to answer before opening the explanation.
How many classes, objects, and references are shown?
There is one class definition involved, RobotArm. The code creates two objects by using new twice. The variables left and right hold two references, one to each object.
Does right's power also become 0.5?
No. left.move(0.5) changes the power field of the object referred to by left. The separate object referred to by right keeps the value assigned by its constructor.
Which part is the blueprint and which part is an instance?
RobotArm is the class, or blueprint. The result of each new RobotArm(...) expression is an object, or instance.
Ready to move on?
Sign in with Google to save your progress with Telemark, or continue without saving.