Unit 4: Object-Oriented Programming
These two advanced OOP concepts are crucial for achieving abstraction. They allow us to define a "contract" for what a class must do, without specifying exactly how it should be done, leading to more flexible and powerful robot code.
An abstract class is a special type of class that cannot be instantiated on its own—you can't create an object from it. It serves as a base for other classes to inherit from, providing a mix of implemented and unimplemented methods.
Use an abstract class when you have a strong "is-a" relationship and want to provide some common, shared code. For example, an `Intake` is a `Mechanism`, and all mechanisms might share a common `getName()` method, but each will have a unique `run()` method.
// 1. The Abstract Superclass
// You cannot write 'new Mechanism()' - it's abstract.
public abstract class Mechanism {
private String name;
public Mechanism(String name) {
this.name = name;
}
// A concrete method: it's fully implemented and shared by all subclasses.
public String getName() {
return this.name;
}
// An abstract method: it has no body. Subclasses MUST provide an implementation.
public abstract void runMechanism();
}
// 2. A Concrete Subclass
public class Intake extends Mechanism {
public Intake() {
super("Intake"); // Call the parent constructor
}
// We MUST implement the abstract method from Mechanism.
@Override
public void runMechanism() {
System.out.println("Intake rollers are spinning.");
}
}
An interface is a pure blueprint of behaviors. It defines a set of methods that a class must implement, but it provides no implementation for them. An interface defines a "can-do" relationship.
Use an interface when you want to define a capability that can be shared by unrelated classes. For example, a `Drivetrain`, a `Shooter`, and a `Limelight` are all very different, but they all can be logged to the dashboard. An interface is also how Java achieves a form of multiple inheritance.
// 1. The Interface: A contract for what a class MUST do.
public interface Loggable {
// Any class that implements Loggable MUST have this method.
void logToDashboard();
}
// 2. An Implementing Class
// A Drivetrain is not a Loggable, but it CAN BE Loggable.
public class Drivetrain extends SubsystemBase implements Loggable {
// ... other drivetrain code ...
@Override
public void logToDashboard() {
SmartDashboard.putNumber("Drivetrain Speed", getCurrentSpeed());
}
}
// 3. Another Implementing Class
public class Shooter extends SubsystemBase implements Loggable {
// ... other shooter code ...
@Override
public void logToDashboard() {
SmartDashboard.putNumber("Shooter RPM", getRPM());
}
}
Question: Your robot has a `Drivetrain` and an `Arm`, which are very different mechanisms. You want to ensure both have a `resetSensors()` method. What is the best OOP tool for this?