Inheritance Lesson

Inheritance: Building on Your Blueprints

Inheritance is a powerful OOP concept that allows a new class to be based on an existing class, inheriting its fields and methods. This promotes code reusability and creates a logical "is-a" relationship between your robot's components.

The "Is-A" Relationship

Inheritance is used to model an "is-a" relationship. For example, a `Shooter` is a type of `Mechanism`. A `Drivetrain` is a type of `Subsystem`.

Parent and Child Classes

  • Superclass (Parent): The existing, more general class (e.g., `Mechanism`).
  • Subclass (Child): The new, more specific class that inherits from the superclass (e.g., `Shooter`).

The subclass gets all the `public` and `protected` members of its superclass for free, so you don't have to rewrite common code.

An FRC Example: `Mechanism` and `Shooter`

Let's create a general `Mechanism` class that all our robot's mechanisms can share. It will have a motor and a basic `stop()` method. Then, we'll create a `Shooter` class that inherits from it and adds its own specific logic.

// The Superclass (Parent)
public class Mechanism {
    // 'protected' means this is accessible by subclasses
    protected Spark m_motor; 

    public Mechanism(int motorPort) {
        m_motor = new Spark(motorPort);
        System.out.println("Mechanism constructor called.");
    }

    public void stop() {
        m_motor.set(0.0);
    }
}

// The Subclass (Child) uses the 'extends' keyword
public class Shooter extends Mechanism {
    private Encoder m_encoder;

    public Shooter(int motorPort, int encoderPort) {
        // 'super(motorPort)' MUST be the first line.
        // It calls the constructor of the parent (Mechanism) class.
        super(motorPort); 
        m_encoder = new Encoder(encoderPort);
        System.out.println("Shooter constructor called.");
    }

    // This is a method unique to the Shooter
    public void setRPM(double rpm) {
        // ... logic to convert RPM to motor speed ...
        m_motor.set(calculatedSpeed); // We can use m_motor because it was inherited!
    }
}
    

The `super` Keyword

The `super` keyword is used to refer to the parent class. It has two main uses:

  • `super(...)` in a Constructor: As seen above, it calls the constructor of the superclass. This is required and must be the very first line in the subclass's constructor.
  • `super.methodName()`: Lets you call a method from the parent class, even if you've overridden it in the child class.

Method Overriding

Sometimes a subclass needs to provide a more specific implementation of a method it inherited. This is called method overriding. The `@Override` annotation is used to tell the compiler you intend to do this, which helps catch errors.

public class Intake extends Mechanism {
    public Intake(int motorPort) {
        super(motorPort);
    }

    // This Intake has a special way of stopping.
    @Override
    public void stop() {
        // Maybe we want to coast to a stop instead of braking.
        m_motor.setIdleMode(IdleMode.kCoast);
        super.stop(); // We can still call the original parent method if needed.
    }
}
    

Test Your Knowledge

Question: When creating a constructor for a subclass (e.g., `Shooter`), what must the very first line of code do?