Inheritance

Inheritance

Inheritance is the process in which a class is able to access and utilize the properties, methods, and fields of a parent class. This is useful for when you don't want to define multiple classes that share functionality because you can just have the parent hold that functionality and allow childen classes to specialize wherever needed.

Inheriting from a Parent Class

Sticking to our Pet class example, let's define two kinds of pets, Cat and Dog. Given that both of these animals tend to be pets, it makes sense to have them be children of the Pet class.

Declare children to be parents of another class by using the extends keyword:

	
    public static class Cat extends Pet {
        Cat(String name, int weight) {
            super(name, weight);
        }

        void meow() {
            System.out.println("Meow!");
        }
    }

    public static class Dog extends Pet {
        Dog(String name, int weight) {
            super(name, weight);
        }

        void bark() {
            System.out.println("Bark!");
        }
    }
	

For reference, this is how the parent Pet class looks like:

	
    public static class Pet {
        String name;
        int weight;

        Pet(String name, int weight) {
            this.name = name;
            this.weight = weight;
        }

        void printInfo() {
            System.out.println("Name: " + name + " Weight: " + weight + " pounds.");
        }
    }
	

Both children classes, Cat and Dog, extend the Pet class. What this means is that now both of them have access to the same properties that Pet has defined, namely name, weight, and printInfo().

If you were wondering about what super does, that just calls the constructor of the parent class and passes in the necessary parameters up the chain. This ensures that the child class is still a valid type of its parent.

Creating Children objects

Now that we have the parent and children classes defined, we can create objects from them and truly illustrate the usefulness of inheritance in Java.

Let's put it all together and create both a cat and dog.

	
    public class Main {

        public static class Pet {
            String name;
            int weight;

            Pet(String name, int weight) {
                this.name = name;
                this.weight = weight;
            }

            void printInfo() {
                System.out.println("Name: " + name + " Weight: " + weight + " pounds.");
            }
        }

        public static class Cat extends Pet {
            Cat(String name, int weight) {
                super(name, weight);
            }

            void meow() {
                System.out.println("Meow!");
            }
        }

        public static class Dog extends Pet {
            Dog(String name, int weight) {
                super(name, weight);
            }

            void bark() {
                System.out.println("Bark!");
            }
        }

        public static void main(String[] args) {
            Dog dog = new Dog("Scooby", 4);
            dog.bark();
            dog.printInfo();

            Cat cat = new Cat("Tinkerbell", 9);
            cat.meow();
            cat.printInfo();
        }
    }
	
	
    Bark!
    Name: Scooby Weight: 4 pounds.
    Meow!
    Name: Tinkerbell Weight: 9 pounds.
	

Notice what happened here. Only a dog can bark and only a cat can meow, so it makes sense that only those classes can call those respective methods. But notice how both objects were able to call printInfo(), which uses name and weight? That is, of course, because Dog and Cat are still valid instance of Pet and thus have access to those sames properties just like any Pet.

Using inheritance, we were able to create specialized children classes that inherit functionality from the parent class that they extend from for free. This helps keep logically connected classes linked by their parent which helps structure our overall program much better.