- Lab
- Core Tech

Guided: Java SE 21 Developer (Exam 1Z0-830) - Object-oriented Programming
This code lab will teach you how to apply core object-oriented programming principles in Java by building a festival performance application. You'll learn how to implement encapsulation, abstraction, inheritance, and polymorphism through hands-on tasks. By the end of this lab, you'll have practical experience building object-oriented Java applications.

Path Info
Table of Contents
-
Challenge
Introduction
Welcome to the lab Guided: Java SE 21 Developer (Exam 1Z0-830) - Object-oriented Programming.
Object-Oriented Programming (OOP) is a programming paradigm that organizes code into objects, which are instances of classes containing both data and behavior. Java, being an object-oriented language, supports OOP's core principles: encapsulation, inheritance, polymorphism, and abstraction.
Consider this scenario:
// Without OOP String performanceName = "The Coders"; String performanceType = "music"; int startTime = 1900; int duration = 60; int numberOfPerformers = 4; // With OOP MusicPerformance performance = new MusicPerformance( "The Coders", new TimeSlot(1900, 60), "Rock", 4 );
The OOP approach provides several advantages:
- Encapsulation: Data and behavior are bundled together, with access control
- Inheritance: Common characteristics can be shared through class hierarchies
- Polymorphism: Different objects can be treated uniformly through common interfaces
- Abstraction: Complex systems can be simplified by hiding implementation details
In this lab, you'll work with a Festival Performance Management application that demonstrates these principles:
- Creating an inheritance hierarchy of performance types
- Implementing encapsulated data with getters and setters
- Using polymorphism to handle different performance types uniformly
- Applying abstraction to define common behaviors ---
Familiarizing with the Program Structure
The application includes the following classes in the
src/main/java
directory:com.pluralsight.festival.Performance
: An abstract base class defining common structure for all performance typescom.pluralsight.festivalMusicPerformance
,com.pluralsight.festival.ComedyPerformance
, andcom.pluralsight.festival.DancePerformance
: Concrete classes extendingPerformance
com.pluralsight.festival.TimeSlot
: A utility class for managing performance schedulingcom.pluralsight.festival.Stage
: A class managing a collection of performancescom.pluralsight.festival.Main
: The application's entry point demonstrating the usage of all components
The
TimeSlot
class is fully implemented. Other classes are partially implemented with TODO comments indicating where you'll need to add or modify code.You can compile and run the application using the Run button located at the bottom-right corner of the Terminal. However, the application will not compile initially, but this issue will be resolved after completing the first task.
Begin by examining the code to understand the program's structure. Once you're ready, proceed with the coding tasks. If you need help, you can find solution files in the
solution
directory, organized by steps (e.g.,step2
,step3
, etc.). Each solution file follows the naming convention[filename]-[step]-[task].java
(e.g.,Performance-2-1.java
instep2
). -
Challenge
Implementing Encapsulation and Abstraction
Encapsulation
Encapsulation bundles data and the methods that operate on that data within a single unit (class), controlling access through access modifiers:
public class BankAccount { // Data is private private double balance; // Public access getter method public double getBalance() { return balance; } // Public access method public void deposit(double amount) { if (amount > 0) { balance += amount; } } }
These are the access modifiers that apply to fields and methods:
private
: Only accessible within the classprotected
: Accessible within the package and by subclassespublic
: Accessible from anywhere- Default (no modifier): Accessible only within the package
Also, inside getter or setter methods, you can perform validations, conversions, or other operations before retrieving or modifying the data.
In the next task, you'll apply these principles to implement encapsulation. ---
Abstraction
Abstraction defines a contract for what an object can do without specifying how it's done. In Java, one way to achieve abstraction is through abstract classes and methods.
Here's an example of an abstract class with an abstract and a concrete method:
public abstract class Shape { public abstract double calculateArea(); // Abstract method public void display() { // Concrete method System.out.println("Area: " + calculateArea()); } }
If a class contains at least one abstract method, the class should be marked as abstract.
Abstract methods:
- Must be implemented by concrete subclasses
- Cannot have a body in the abstract class
- Force subclasses to provide specific implementations
The benefits of using abstract classes include:
- Define a common interface for related classes
- Share code through concrete methods
- Ensure consistent behavior across implementations
- Prevent instantiation of incomplete classes
In the next task, you'll apply these principles to implement abstraction.
-
Challenge
Building the Inheritance Hierarchy
When creating class hierarchies in Java, subclasses inherit fields and methods from their parent class using the
extends
keyword:public class Animal { private String name; public Animal(String name) { this.name = name; } } public class Dog extends Animal { // ... }
This relationship creates an is-a relationship between classes.
Subclasses must call their parent's constructor using
super()
. This call:- Must be the first statement in the constructor
- Ensures proper initialization of inherited fields
- Can pass arguments to match the parent's constructor parameters
public class Dog extends Animal { private String breed; public Dog(String name, String breed) { super(name); // Call parent constructor first this.breed = breed; } }
Notice that in the above example,
breed
is not passed tosuper()
because this is a field that only exists in theDog
class.Depending on its access modifiers, fields and methods can be inherited from the parent class. However, methods can be overridden (redefined) to provide custom behavior for the subclasses.
When overriding methods from a parent class:
- Use the
@Override
annotation to catch errors - Match the method signature exactly
- Provide a new implementation specific to the subclass
- Cannot reduce the visibility of the inherited method
public class Vehicle { public String getSpecs() { return "Generic vehicle"; } } public class Car extends Vehicle { @Override public String getSpecs() { return "Four-wheeled vehicle"; } }
Remember:
- Abstract methods must be implemented by concrete subclasses
- The
@Override
annotation helps prevent accidental method overloading - Each subclass can provide its own specialized behavior while maintaining the parent's contract
In the upcoming tasks, you'll apply these concepts to create specialized performance types with their own unique descriptions:
- A comedy performance adds comedian name and adult-only status to track stand-up comedy shows.
- A dance performance adds number of dancers and dance style to represent choreographed shows.
- A music performance adds genre and number of performers to represent band or solo performances.
-
Challenge
Implementing Polymorphic Behavior
Polymorphism allows you to treat objects of different types through a common interface. This feature enables you to write more flexible and maintainable code.
For example, when you store objects of different types in a collection or variable of their common supertype, Java automatically calls the correct implementation of overridden methods:
abstract class Animal { public abstract String makeSound(); } class Dog extends Animal { @Override public String makeSound() { return "Woof!"; } } class Cat extends Animal { @Override public String makeSound() { return "Meow!"; } } // Using polymorphism List<Animal> animals = new ArrayList<>(); animals.add(new Dog()); animals.add(new Cat()); // Each animal uses its own implementation for (Animal animal : animals) { System.out.println(animal.makeSound()); }
When managing collections of related objects:
- Store objects using the most general type possible
- Process objects uniformly through their common interface
- Let each object's specific implementation handle the details
In the next tasks, you'll apply these concepts to manage different types of performances through a common interface, allowing each type to provide its specific behavior while being handled uniformly.
-
Challenge
Instantiating Objects
When creating objects in Java, you can store them in variables of their own type or any of their parent types. This flexibility is key to polymorphic behavior.
Creating objects involves:
- Using the
new
keyword - Calling a constructor with appropriate parameters
- Storing the reference in a variable
// Direct type reference Vehicle sedan = new Car("Model S", 4); // Parent type reference (polymorphic) Vehicle truck = new Truck("F-150", 6);
You can assign objects to variables of:
- The exact class type
- Any parent class type
- Any interface the class implements
interface Drawable { } class Shape implements Drawable { } class Circle extends Shape { } // All these are valid Circle circle = new Circle(); Shape shape = new Circle(); Drawable drawable = new Circle();
When instantiating objects:
- Parameters must match one of the class's constructors
- Arguments must be in the correct order
- Arguments must be of compatible types
class Book { public Book(String title, String author, int pages) { // ... Validations and initialization } } // Creating with valid parameters Book book = new Book("Java Programming", "John Smith", 400);
In the next tasks, you'll apply these concepts to create different types of performances while maintaining type safety and proper initialization.
- Using the
-
Challenge
Conclusion
Congratulations on successfully completing this Code Lab!
To compile and run the application, you can either click the Run button in the bottom-right corner of the screen or use the Terminal with the following commands:
-
Compile and package the application:
mvn clean package
-
Execute the application:
java -cp target/festival-manager-1.0-SNAPSHOT.jar com.pluralsight.festival.Main
The program will output the scheduled performances.
You can try adding more performances of different types or modify the existing ones in the
Main
class. In particular, see what happens when you schedule overlapping performances. ---Extending the Program
Here are some ideas to further enhance your skills and extend the application's capabilities:
-
Create a
TheatrePerformance
class with props list and cast size -
Add a composite pattern to group performances into festivals or themed shows
-
Implement the state pattern for performance lifecycle (Setup, Ready, Running, Completed)
These extensions emphasize different OOP principles and design patterns while adding practical functionality to the festival management system. ---
Related Courses in Pluralsight's Library
If you'd like to continue building your Java skills or explore related topics, check out these courses available on Pluralsight:
These courses cover a wide range of Java programming topics. Explore them to further your learning journey in Java!
-
What's a lab?
Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.
Provided environment for hands-on practice
We will provide the credentials and environment necessary for you to practice right within your browser.
Guided walkthrough
Follow along with the author’s guided walkthrough and build something new in your provided environment!
Did you know?
On average, you retain 75% more of your learning if you get time for practice.