Inheritance and it's use

  • it doesn't really make sense to redefine the methods for gas and breaks for every single car, when it will do the same thing
  • Instead you can use case for inheritance. We can define a base "Car Class" that has the methods and attributes common to every car - steering methods, gas and break methods, and attributes like speed and miles per gallon.
  • Each car will "extend" from this base class. This means that it "inherits" the methods and attributes in the base Car Class (this is why it's called Inheritance). But each of the new car classes, for example a Bugatti Class, will have its own special methods and attributes.
  • Super class: generic methods all objects would have
  • Protected is an access modifier so that the attribute isn't affected by outside modifiers.
public class Car {
    protected String brandName;
    protected double range;
    protected double doorNumber;
    protected double maxSpeed;
    
    // Constructor for the attributes present in the superclass
    public Car(String brandName, double range, double doorNumber, double maxSpeed) {
        this.brandName = brandName;
        this.range = range;
        this.doorNumber = doorNumber;
        this.maxSpeed = maxSpeed;
    }
    
    public void gas () {
        System.out.println("Go!");
    }
    
    public void brake () {
        System.out.println("Stop!");
    }
    
    public void gearShift () {
        System.out.println("Use the stick");
    }
    
    public void steer () {
        System.out.println("turning left...");
    }
    
    public void horn () {
        System.out.print("honking... ");
    }
}
public class TeslaModelS extends Car {
    // Additional attribute not present in the superclass
    protected String hornSound; 
    
    // Constructor for Subclass
    public TeslaModelS(String brandName, double range, double doorNumber, double maxSpeed, String hornSound) {
        // We use the Superclass constructor for the shared attributes through the keyword "super"
        super(brandName, range, doorNumber, maxSpeed);
        // hornSound is not in the Superclass, so we add it separately in the constructor
        this.hornSound = hornSound;
    }
    
    // We use override to change the functionality in the subclass of an existing method in the superclass
    @Override
    public void gearShift () {
        System.out.println("Use the gear selector next to the wheel");
    }
    public void steer () {
        System.out.println("turning right...");
    }
    
    // Here, we don't fully change the functionality of the existing horn method in the superclass
    // Instead, we take all of the functionality of the superclass method, and then add on to it
    public void horn () {
        super.horn();
        System.out.println(hornSound);
    }
    
    public static void main(String[] args) {
        // 5 argument constructor
        TeslaModelS modelS = new TeslaModelS("Tesla", 396, 4, 200, "eugh");
        // Example of late binding
        Car car = new TeslaModelS("Tesla", 396, 4, 200, "brrr");
        // We can still use the methods from the child class, even though we didn't mention them in the subclass!
        modelS.gas();
        // Using the overridden method
        modelS.gearShift();
        modelS.steer();
        // Using the method we added on to
        modelS.horn();
        car.horn();
    }
    
    
}
TeslaModelS.main(null);
Go!
Use the gear selector next to the wheel
turning right...
honking... eugh
honking... brrr

Overiding Methods

  • Overriding allows a subclass or child class to provide a specific implementation of a method that has already been provided by a super-classes or parent classes.
  • When a method in a subclass has the same name, same parameters or signature, and same return type (or sub-type) as a method in its super-class, then the method in the subclass will override the method in the super-class.
// the existing method in the superclass
public void gearShift () {
    System.out.println("Use the stick");
}

public void steer () {
    System.out.println("turning left...");
}

// We use override to change the functionality in the subclass of an existing method in the superclass
@Override
public void gearShift () {
    System.out.println("Use the gear selector next to the wheel");
}
public void steer () {
    System.out.println("turning right...");
}
|   @Override
static methods cannot be annotated with @Override

Super keyword

  • Way to use constructors in the superclass and methods in the superclass in a child class.

Inheritance Hierarchy

  • similar to looking at it like a family tree. A is the superclass, or the head of the family. The descendants are the subclasses.

Polymorphism

  • It means that we do one thing in many ways through inheritance.
  • if you want to do a single method in a single class, but in different ways
public class ToyotaCamry extends Car {
    
    public ToyotaCamry (String brandName, double range, double doorNumber, double maxSpeed) {
        super(brandName, range, doorNumber, maxSpeed);
    }
    
    @Override
    public void gearShift () {
        System.out.println("Manual shift!");
    }
    
    public void turbo (int a) {
        System.out.println("Engaging turbo " + a);
    }
    
    public void turbo (int a, int b) {
        System.out.println("Engaging turbo " + a + " and nitro " + b);
    }
    
        
    public static void main(String[] args) {
        // 4 superclass argument constructor
        ToyotaCamry camry = new ToyotaCamry("Toyota", 348, 4, 145);
        // Using the overridden method
        camry.gearShift();
        // Using the overloaded method
        camry.turbo(1);
        camry.turbo(1, 1);

    }
}
ToyotaCamry.main(null);

Object Superclass

  • Object class is the superclass of all other classes in Java
  • Object is part of the java.lang package (know for imports)
  • Important Object class methods include: boolean equals(Object x) & String toString()
  • Object class' subclasses override the equals and toString methods

toString Method

  • Prints out the attributes of an object
  • Converts string object into a string

equals Method

  • Compares two strings
  • Returns a boolean value of true if equal, otherwise returns false