Inheritance and Polymorphism

Inheritance

Inheritance is a unique trait of classes. Just like a child inherits genes from their parents, a subclass (child class) inherits attributes and methods from a superclass (parent class). However, each subclass can only have a single superclass, though a superclass can have multiple subclasses. The relationship between a subclass and a superclass is known as an IS-A relationship, while the relationship between a class and its attributes is known as a HAS-A relationship. For example, if the class Honda is a subclass of the class Car, you could say that Honda IS-A Car. If Honda contains the attribute hondaLogo, you could say thet Honda HAS-A hondaLogo.

Declaring Child Classes

A child class is declared using the extends keyword. For example, take a look at the code shown below.

// In a file called Car.java
public class Car {
  String colour;
  int year;
  int gas;
  int mileage;
  public Car(String c, int y, int g, int m) {
    colour = c;
    year = y;
    gas = g;
    mileage = m;
  }
  // Other Car methods
}

// In a file called Honda.java
public class Honda extends Car {
  String model;
  public Honda(String c, int y, int g, int m, String mod) {
    super(c, y, g, m);
    model = mod;
  }
  // Other Honda methods
}


In this case, the class Honda is a subclass of the superclass Car. As a result, Honda can inherit the methods of Car. The attributes of Car can also be inherited by Honda with the super keyword, which calls the constructor of the Car class.

Access Modifiers

Access Modifiers can be used to specify where a class or method can be accessed from. The public modifier allows an attribute or method to be accessed globally, while the protected modifier only allows an attribute or method to be accessed from inside the class or its subclasses. If a modifier is not specified, java will default to the default modifier, which allows a method or attribute to be accessed from inside the class and subclasses in the same package. Finally, the private modifier only allows a method or attribute to be accessed from inside a class. Private methods are not inherited, and unless specific methods exist to get and set the values of private attributes, they cannot be accessed by a subclass.

Polymorphism

Polymorphism - meaning many forms - allows for the same method to result in different actions depending on the type of object it is called from.

Overriding

Overriding is a type of polymorphism, and happens when a class and its subclass have a method with the same signature, but different functions. In this case, the printType() method that is executed depends on the type of the object. If the object has the same type as the superclass, the superclass method will be executed, but if the object has the same type as the subclass, the subclass method will be executed instead.

// In a file called Car.java
public class Car {
  public Car() {
      
  }
  
  public void printType() {
    System.out.println("I am a car");
  }
}

// In a file called Honda.java
public class Honda extends Car {
  public Honda() {
      
  }
  
  public void printType() {
      System.out.println("I am a honda");
  }
}

// In a file called Driver.java
public class Driver {
  public static void main(String[] args) {
    Car car1 = new Car();
    Honda car2 = new Honda();
    car1.printType(); // I am a car
    car2.printType(); // I am a honda
  }
}


Since car1 is of type Car, car1.printType(); will call the printType() method of Car. However, even though Honda is a subclass of Car, Honda has overridden the printType() method of Car with its own printType() method, and so car2.printType() will call the printType() method of Honda since car2 is of type Honda.