Reusing Implementations through Inheritance

Inheritance

Every class that you create in Java is a subclass, its ultimate parent is the Object class that every class inherits even if you dont declare it. To inherit a class we use the extends keyword the extended class is known as the parent or base class or superclass, the object performing the extending is known as the child (derived) or subclass

There are three types of inheritance:

A subclass is said to be of type superclass and an instance of the subclass can be used anywhere an instance of the superclass can be used basically subclass 'IS A' of the superclass

There are a few rules regarding IS-A and HAS-A relationships

IS-A
(inheritance)

In OO, the concept of IS-A is based on inheritance, IS-A is a way of saying "this thing is a type of that thing", for example a dog is a type of animal so a dog IS-A animal, bentley IS-A car, apple IS-A fruit, etc

This is expressed in Java through the keyword extends
   public class Vehicle { ... }
   public class Car extends Vehicle { ... }
   public class Ka extends Car { ... }

So we can say that "Ka IS-A car" and "Ka IS-A Vehicle" because a class is said to be "a type of" anything further up in its inheritance tree.

When using the extends keyword a class inherits all accessible member variables and methods

public class TestAnimal {
   public void static main (String[ ] args) {
      Horse h = new Horse();

      h.getEat();                              // getEat() method inherited from Animal
      h.food = "Hay and Oats";           // change the inherited (from Animal) food variable

     System.out.println("I like to eat " + h.food);
}

class Animal {
   public String food = "Green Stuff";

   public void getEat() {
        System.out.println("General food from the Animal class");
   }
}

class Horse extends Animal {
    // Will inherit Animals getEat() method and food member variable
}

HAS-A
(usage)

HAS-A relationships are based on usage, rather than inheritance, in other words class A HAS-A B if code in class A has a reference to an instance of class B for example "city HAS-A road".

The below Horse class has an instance variable of type Halter, so you can say that "Horse HAS-A Halter" (Horse has a reference to Halter). This means that you can invoke any of the methods in Halter, this is good OO practice as we do not need to duplicate the methods in Halter and this means that any other class can use Halter methods thus reducing code.

public class Animal { ... }
public class Horse extends Animal {
   private Halter myHalter;

   public void tie(LeadRope rope) {
      myHalter.tie(rope);              // delegate tie behavior to Halter Object
   }
}

Users of the Horse class think that the Horse class has Halter behavior, the Horse class may have a method called tieRope but this method could delegate this to the Halter tieRope method (as seen above), users of Horse class should never know that there is a Halter, only that is capable of things you ask it to do.


There are visual object modeling languages such has the Unified Modeling Language (UML) which allow designers to design and easily modify classes without having to write code first because object-oriented components are represented graphically. This helps coders to create a map of the class relationships and helps them recognize errors before coding begins. There are many design patterns available which cover a lot of different types of projects.

To obtain what class an object belongs to you can use the following

what class an object belongs to System.out.println("The class of object " + obj + " is " + obj.getClass().getName() );

A class consists of two types of elements:

The rules for inheritance is as follows:

Create and Extend Abstract Classes

An abstract class is a class that is declared with the abstract modifier and it may or may not include abstract methods. An abstract class defers some or all of its implementation to its subclass and thus an abstract class cannot be instantiated. An abstract class is use to define common attributes and behavior for a class that will extend it.

The class example of an abstract class is the Animal class which is extended by the Dog class, as you normally will not instantiate an Animal class, the Animal class will contain common attributes and behavior that can be used by several animals, for example walk, bite, number of legs, etc. A class that is not abstract is called a concrete class. Note to remember is that an abstract class needs a subclass to implement its methods, thereby forcing commonality of interface. If one method is declared abstract then the class itself needs to be abstract as well, fields cannot be declared abstract.

Abstract class rules are as follows:

Minimal abstract class
abstract class AbstractClass {}
abstract class
public abstract class Vehicle {

    // We create an enum which describes possible subclasses
    protected enum VehicleType {
        Automobile, Motorcycle, Moped, Bicycle, Scooter
    }

    // These attributes will be common to all subclasses
    private VehicleType type;
    private String owner;
    private String make;

    // Standard Constructor
    public Vehicle(VehicleType type, String owner, String make) {
        this.type = type;
        this.owner = owner;
        this.make = make;
    }

    // toString method
    public String toString() {
        return "Vehicle{" +
                "type=" + type +
                ", owner='" + owner + '\'' +
                ", make='" + make + '\'' +
                '}';
    }

    // As the below are all abstract they will need to be implemented by the subclass
    public abstract void drive();

    public abstract void park();

    public abstract void makeNoise();
}
    
// Vehicle is a concrete class which extends the abstract class Vehicle
public class Auto extends Vehicle {

    // Create a constructor that is a pass thru to Vehicle constructor
    public Auto(VehicleType type, String owner, String make) {
        super(type, owner, make);
    }

    // Implement Vehicle's drive method
    public void drive() {
        System.out.println("Release Brake, go");
    }

    // Implement Vehicle's park method
    public void park() {
        System.out.println("Parallel or back in?");
    }

    // Implement Vehicle's makeNoise method
    public void makeNoise() {
        System.out.println("Vroom Vroom");
    }

    // Main method creates an instance of Auto and demonstrates calling the
    // concrete methods
    public static void main(String[] args) {
        Auto car = new Auto(VehicleType.Automobile, "Allen", "Ford");
        System.out.println(car);
        car.drive();
        car.park();
        car.makeNoise();
    }
}

I have not covered Interfaces yet but here is a table of the differences between abstract class and an interface. If you want to provide common, implemented functionality among all implementations of your component, use an abstract class. Abstract classes allow you to partially implement your class, whereas interfaces contain no implementation for any members.

Abstract classInterface
Abstract class can have abstract and non-abstract methods.Interface can have only abstract methods. Since Java 8, it can have default and static methods also.
Abstract class can define public, protected, package-private or private concrete methodsAll abstract methods are public
An abstract method must be declared abstractIf a method has no body by default its implicity abstract
Abstract class doesn't support multiple inheritance.Interface supports multiple inheritance.
Abstract class can have final, non-final, static and non-static variables.Interface has only public, static and final variables.
Abstract class can provide the implementation of interface.Interface can't provide the implementation of abstract class.
The abstract keyword is used to declare abstract class.The interface keyword is used to declare interface.
An abstract class can extend another Java class and implement multiple Java interfaces.An interface can extend another Java interface only.
An abstract class can be extended using keyword "extends". An interface can be implemented using keyword "implements".
A Java abstract class can have class members like private, protected, etc.Members of a Java interface are public by default.

Enable Ploymorphism by Overriding Methods

Utilize Ploymorphism to cast and call Methods

Distinguish Overloading, Overriding and Hiding