Exercise Overview
How to Use These Exercises
These exercises are designed to reinforce your understanding of Java inheritance and polymorphism including class hierarchies, method overriding, abstract classes, interfaces, and polymorphic behavior. Start with the easy exercises and progress to more challenging ones as you build confidence.
Tips for Success:
- Understand the relationship between base and derived classes
- Practice method overriding with @Override annotation
- Learn to use abstract classes and interfaces effectively
- Master polymorphic behavior and dynamic binding
- Follow inheritance design principles
Easy Exercises - Start Here!
Basic Inheritance
EasyCreate a simple inheritance hierarchy with a base class and derived class.
Requirements:
- Create a base class called
Animal
with attributes: name, age - Create a derived class called
Dog
that extends Animal - Add a breed attribute to Dog
- Create constructors for both classes
- Override the toString() method in Dog
- Test the inheritance relationship
Expected Output:
Animal: Buddy, Age: 3
Dog: Buddy, Age: 3, Breed: Golden Retriever
Animal: Whiskers, Age: 2
Dog: Max, Age: 5, Breed: German Shepherd
Hints:
- Use
extends
keyword to create inheritance - Use
super()
to call parent constructor - Use
protected
for attributes accessible by subclasses - Override
toString()
to provide meaningful output - Test with both Animal and Dog objects
Method Overriding
EasyPractice method overriding with the @Override annotation.
Requirements:
- Add a
makeSound()
method to Animal class - Override
makeSound()
in Dog class to return "Woof!" - Create a
Cat
class that extends Animal - Override
makeSound()
in Cat to return "Meow!" - Use @Override annotation for all overridden methods
- Test all three classes
Expected Output:
Animal sound: Some animal sound
Dog sound: Woof!
Cat sound: Meow!
Testing polymorphic behavior:
Animal (Dog): Woof!
Animal (Cat): Meow!
Hints:
- Use
@Override
annotation for clarity - Method signature must match exactly (name, parameters, return type)
- Access modifier can be the same or more accessible
- Test with both direct calls and polymorphic calls
- Use
super.makeSound()
if you want to call parent method
Polymorphism
EasyDemonstrate polymorphism using method overriding and dynamic binding.
Requirements:
- Create an array of Animal objects containing different animal types
- Loop through the array and call makeSound() on each animal
- Demonstrate that the correct sound is produced for each animal type
- Create a method that accepts an Animal parameter and calls makeSound()
- Show polymorphic behavior with different animal types
Expected Output:
Polymorphic behavior demonstration:
Woof!
Meow!
Woof!
Using method with Animal parameter:
Animal 1: Woof!
Animal 2: Meow!
Animal 3: Woof!
Hints:
- Use
Animal[]
to store different animal types - Dynamic binding occurs at runtime based on actual object type
- Same method call produces different results based on object type
- Use enhanced for loop to iterate through array
- Create a helper method to demonstrate polymorphic calls
Medium Exercises - Build Your Skills!
Abstract Classes
MediumCreate and use abstract classes to define common behavior.
Requirements:
- Make Animal class abstract
- Add an abstract method
getSpecies()
to Animal - Implement
getSpecies()
in Dog and Cat classes - Create another abstract method
getHabitat()
- Demonstrate that you cannot instantiate Animal directly
- Add concrete methods to abstract class
Expected Output:
Dog species: Canis familiaris
Dog habitat: Domestic
Cat species: Felis catus
Cat habitat: Domestic
Trying to create Animal directly:
Error: Cannot instantiate abstract class Animal
Hints:
- Use
abstract
keyword for class and methods - Abstract methods have no implementation in parent class
- Concrete methods can exist alongside abstract methods
- Subclasses must implement all abstract methods
- Abstract classes cannot be instantiated directly
Interfaces
MediumCreate and implement interfaces to define contracts.
Requirements:
- Create an interface called
Playable
with methodplay()
- Create an interface called
Trainable
with methodtrain()
- Implement both interfaces in Dog class
- Implement only Playable in Cat class
- Demonstrate interface usage with different animal types
- Use interface as parameter type
Expected Output:
Dog is playing fetch
Dog is being trained to sit
Cat is playing with yarn
Testing with interface parameter:
Playable animal: Dog is playing fetch
Playable animal: Cat is playing with yarn
Hints:
- Use
interface
keyword to define interfaces - Use
implements
keyword to implement interfaces - Interfaces can have multiple implementations
- Classes can implement multiple interfaces
- Use interfaces as parameter types for flexibility
Method Overloading vs Overriding
MediumUnderstand the difference between method overloading and overriding.
Requirements:
- Create overloaded methods in Animal class (different parameters)
- Override methods in subclasses (same signature)
- Demonstrate both overloading and overriding in same class
- Show how Java chooses between overloaded methods
- Compare compile-time vs runtime binding
Expected Output:
Overloading examples:
Animal: makeSound() - Some animal sound
Animal: makeSound(3) - Some animal sound repeated 3 times
Overriding examples:
Dog: makeSound() - Woof!
Cat: makeSound() - Meow!
Combined demonstration:
Dog: makeSound() - Woof!
Dog: makeSound(2) - Woof! Woof!
Hints:
- Overloading: same name, different parameters (compile-time)
- Overriding: same signature, different implementation (runtime)
- Overloading can exist in same class or inheritance hierarchy
- Overriding only exists in inheritance hierarchy
- Use
@Override
annotation for clarity
Hard Exercises - Master the Concepts!
Complex Inheritance Hierarchy
HardCreate a complex inheritance hierarchy with multiple levels.
Requirements:
- Create a hierarchy: Animal → Mammal → Dog/Cat → SpecificBreeds
- Add appropriate attributes and methods at each level
- Use method overriding at multiple levels
- Implement interfaces at different levels
- Demonstrate polymorphic behavior throughout hierarchy
- Create utility methods that work with any level
Expected Output:
Hierarchy demonstration:
Golden Retriever: Canis familiaris (Mammal)
- Sound: Woof!
- Habitat: Domestic
- Breed: Golden Retriever
- Training: Advanced
Persian Cat: Felis catus (Mammal)
- Sound: Meow!
- Habitat: Domestic
- Breed: Persian
- Play: Loves yarn
Hints:
- Plan the hierarchy carefully before implementation
- Use
super()
to call parent constructors - Consider which methods should be abstract vs concrete
- Use interfaces for cross-cutting concerns
- Test polymorphic behavior at each level
Design Patterns with Inheritance
HardImplement common design patterns using inheritance and polymorphism.
Requirements:
- Implement Factory Pattern for creating different animal types
- Implement Strategy Pattern for different behaviors
- Implement Template Method Pattern with abstract classes
- Create a registry system for animal types
- Demonstrate runtime type checking and casting
- Add reflection capabilities for dynamic behavior
Expected Output:
Factory Pattern:
Created: Dog (Golden Retriever)
Created: Cat (Persian)
Strategy Pattern:
Dog behavior: Aggressive
Cat behavior: Calm
Template Method:
Animal lifecycle: Born → Grow → Reproduce → Die
Registry System:
Registered animals: Dog, Cat, Bird
Available types: [Dog, Cat, Bird]
Hints:
- Factory Pattern: centralize object creation
- Strategy Pattern: encapsulate algorithms
- Template Method: define algorithm skeleton
- Use
instanceof
for type checking - Use
Class.forName()
for reflection