top of page
Tuyen Nguyen

Unleashing the Power of Abstract Classes in Animal Racing

Updated: Jun 30, 2024

In this article, we'll continue with an example of using the abstract class "Animal" to demonstrate the usage of an abstract class and encapsulate common attributes and behaviours shared among various types of animals within a system.


Start with the Animal class here


public abstract class Animal {
    private String name;
    private int speed;

    public Animal(String name, int speed) {
        this.name = name;
        this.speed = speed;
    }

    public String getName() {
        return name;
    }

    public int getSpeed() {
        return speed;
    }

    public abstract boolean canFly();

    @Override
    public String toString() {
        return name + " {" +
                "speed= " + speed +
                '}';
    }
}

The provided code snippet defines an abstract class called "Animal" with two attributes: "name" and "speed," along with a constructor and getter methods. Especially, it declares an abstract method named "canFly()," indicating that any subclass extending "Animal" must provide its implementation.


Then, create the two subclass "FlyAnimal" and "NonFlyAnimal"


public class FlyAnimal extends Animal{
    public FlyAnimal(String name, int speed) {
        super(name, speed);
    }

    @Override
    public boolean canFly() {
        return true;
    }
}
public class NonFlyAnimal extends Animal{

    public NonFlyAnimal(String name, int speed) {
        super(name, speed);
    }

    @Override
    public boolean canFly() {
        return false;
    }
}

The code defines two subclasses of "Animal": "FlyAnimal" and "NonFlyAnimal." Each subclass provides an implementation for the abstract method "canFly()," specifying whether the animal can fly or not.


Now, "AnimalController" is ready from the previous blog

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class AnimalController {

    public void winnerSpeedWithoutWings(List<Animal> animalList){
        Map<Integer, String> mapAnimal = new HashMap<>();
        for (Animal animal : animalList) {
            if(!animal.canFly()){
                mapAnimal.put(animal.getSpeed(), animal.getName());
            }
        }

        int maxSpeed = Collections.max(mapAnimal.keySet());

        for (Map.Entry<Integer, String> entry : mapAnimal.entrySet()) {
            if(entry.getKey() == maxSpeed){
                System.out.printf("Winner is %s, with the speed is %d", entry.getValue(), entry.getKey());
            }
        }

    }
}

The "AnimalController" class remains unchanged from the previous blog. It contains a method to determine the fastest non-flying animal among a list of animals.


Finally, run your code


import java.security.SecureRandom;
import java.util.Arrays;

public class TestAnimal {
    public static void main(String[] args) {
        Animal horse = new NonFlyAnimal("Horse", new SecureRandom().nextInt(100));
        System.out.println(horse.toString());

        Animal dog = new NonFlyAnimal("Dog", new SecureRandom().nextInt(50));
        System.out.println(dog.toString());

        Animal eagle = new FlyAnimal("Eagle", new SecureRandom().nextInt(100));
        System.out.println(eagle.toString());

        Animal duck = new FlyAnimal("Duck", new SecureRandom().nextInt(50));
        System.out.println(duck.toString());

        Animal lion = new NonFlyAnimal("Lion", new SecureRandom().nextInt(100));
        System.out.println(lion.toString());

        AnimalController animalController = new AnimalController();
        animalController.winnerSpeedWithoutWings(Arrays.asList(horse, dog, eagle, duck, lion));
    }
}

The main method creates instances of various animals and executes the race simulation using the "AnimalController."


Conclusion

In conclusion, let's evaluate the advantages and disadvantages of using an abstract class compared to a concrete class in the context of defining animals within a system.


Advantages of Using an Abstract Class:

  • Abstraction of Common Behavior: An abstract class like "Animal" allows for the encapsulation of common attributes and behaviours shared among different types of animals. This promotes code reuse and ensures consistency in the implementation of shared functionalities.

  • Enforcement of Method Implementation: Abstract methods in the abstract class enforce the implementation of specific behaviours by subclasses. This ensures that subclasses adhere to a contract, providing a clear structure for extending functionality.

  • Flexibility in Inheritance: Subclasses can extend an abstract class to inherit its attributes and behaviours while still having the freedom to define additional functionalities or override existing methods as needed. This promotes flexibility and adaptability in designing class hierarchies.


Disadvantages of Using an Abstract Class:

  • Limited to Single Inheritance: In Java, a class can only inherit from one abstract class, limiting the flexibility of class hierarchies. This can become a constraint when dealing with complex relationships or when multiple inheritance is desired.

  • Tight Coupling: Subclasses are tightly coupled with the abstract class, making it challenging to modify the hierarchy once established. Changes to the abstract class may require modifications to all its subclasses, potentially leading to code maintenance issues.

  • Creation Overhead: Defining an abstract class requires careful consideration of common behaviours and attributes shared among subclasses. This upfront design effort may lead to a more complex class hierarchy than necessary, increasing the cognitive load for developers. In summary, while using an abstract class like "Animal" offers benefits such as the abstraction of common behaviour and enforcement of method implementation, it also introduces limitations such as single inheritance and tight coupling. The decision to use an abstract class versus a concrete class depends on the specific requirements and design considerations of the system being developed.

Opmerkingen


bottom of page