This project demonstrates fundamental Object-Oriented Programming (OOP) concepts through three practical activities implemented in Java.
objects/
├── app/
│ ├── src/main/java/org/example/
│ │ ├── Demo.java # ⭐ MAIN CLASS - Run this!
│ │ │
│ │ ├── UserProfile.java # Activity 1: Encapsulation
│ │ ├── IProfileExporter.java
│ │ ├── JsonProfileExporter.java
│ │ ├── XmlProfileExporter.java
│ │ │
│ │ ├── Notification.java # Activity 2: Inheritance & Polymorphism
│ │ ├── EmailNotification.java
│ │ ├── SmsNotification.java
│ │ ├── PushNotification.java
│ │ ├── NotificationService.java
│ │ │
│ │ ├── Character.java # Activity 3: Composition over Inheritance
│ │ ├── IAttackBehavior.java
│ │ ├── IMovementBehavior.java
│ │ ├── SwordAttack.java
│ │ ├── MagicAttack.java
│ │ ├── WalkingMovement.java
│ │ └── FlyingMovement.java
│ │
│ └── build.gradle.kts
└── README.md
- Java 11 or higher
- Gradle (or use the included Gradle wrapper)
IMPORTANT: The main class is Demo.java located at app/src/main/java/org/example/Demo.java
cd objects/app
./gradlew runOr on Windows:
cd objects\app
gradlew.bat runcd objects
./gradlew :app:runcd objects/app/src/main/java
javac org/example/*.java
java org.example.Demo- Open the
objectsfolder in your IDE (IntelliJ IDEA, Eclipse, VS Code) - Navigate to
app/src/main/java/org/example/Demo.java - Right-click on the file and select "Run 'Demo.main()'"
The Demo class (Demo.java) is the entry point that demonstrates all three activities:
- Creates a
UserProfilewith private fields and public getters/setters - Demonstrates email validation (must contain @)
- Demonstrates password validation (minimum 8 characters)
- Shows abstraction with
JsonProfileExporterandXmlProfileExporter - Exports user profile in multiple formats without modifying the UserProfile class
Expected Output:
=== Activity 1: Encapsulation and Abstraction Demo ===
User profile created successfully!
Username: johndoe
Email: johndoe@example.com
--- Testing Email Validation ---
Error: Email must contain an @ symbol
--- Testing Password Validation ---
Error: Password must be at least 8 characters long
--- Exporting Profile (JSON Format) ---
{
"username": "johndoe",
"email": "johndoe@example.com"
}
--- Exporting Profile (XML Format) ---
<?xml version="1.0" encoding="UTF-8"?>
<UserProfile>
<username>johndoe</username>
<email>johndoe@example.com</email>
</UserProfile>
- Creates an abstract
Notificationbase class - Implements concrete notification types:
EmailNotification,SmsNotification,PushNotification - Uses
NotificationServiceto send notifications polymorphically - Demonstrates the Open/Closed Principle - new notification types can be added without modifying the service
Expected Output:
=== Activity 2: Notification System Demo ===
Sending Email to john@example.com: Welcome to our service!
Sending SMS to +1234567890: Your verification code is 123456
Sending Push Notification to user123: You have a new message
- Creates a flexible
Charactersystem using composition instead of inheritance - Uses behavior interfaces:
IAttackBehaviorandIMovementBehavior - Demonstrates mixing and matching behaviors: Flying Warrior, Walking Mage, etc.
- Shows runtime behavior changes - a warrior can learn magic!
Expected Output:
=== Activity 3: Game Characters Demo ===
--- Flying Warrior ---
Aria is Attacking with a sword! Slash!
Aria is Flying through the air
--- Walking Mage ---
Gandor is Casting a powerful spell! Fireball!
Gandor is Walking on the ground
--- Spell Blade (Flying Mage) ---
Zephyr is Casting a powerful spell! Fireball!
Zephyr is Flying through the air
--- Dynamic Behavior Change ---
Aria learns magic and switches to magic attacks:
Aria is Casting a powerful spell! Fireball!
- Private fields with public getters/setters
- Data validation in setters
- Information hiding
Example: UserProfile class with private username, email, password
- Interfaces define contracts (
IProfileExporter,IAttackBehavior) - Hide implementation details
- Separate "what" from "how"
Example: Different exporters implement the same interface
- Abstract base classes define common behavior
- Derived classes specialize behavior
- Code reuse through class hierarchies
Example: EmailNotification extends Notification
- Treat different types uniformly
- Runtime method dispatch
- Write code that works with parent types
Example: NotificationService.sendBatch() works with any Notification type
- Build complex objects from simple parts
- More flexible than inheritance
- Avoids "class explosion"
Example: Character composed of attack and movement behaviors
The project uses Gradle as the build system. Key configuration in build.gradle.kts:
application {
mainClass = "org.example.Demo" // ⭐ Main class configuration
}Solution: Make sure you're running from the correct directory and the main class is org.example.Demo
Solution: Use the Gradle wrapper: ./gradlew (Linux/Mac) or gradlew.bat (Windows)
Solution: Make sure you have Java 11 or higher installed:
java -versionAfter running and studying this code, you should understand:
- ✅ How to achieve encapsulation with private fields and public methods
- ✅ How to implement abstraction using interfaces
- ✅ How inheritance creates class hierarchies
- ✅ How polymorphism enables flexible, extensible code
- ✅ Why composition is often better than inheritance
- ✅ How to apply the Single Responsibility Principle
- ✅ How to follow the Open/Closed Principle
Try these exercises:
- Activity 1: Add a new
CsvProfileExporterthat exports profiles in CSV format - Activity 2: Add a
SlackNotificationclass without modifyingNotificationService - Activity 3: Create new behaviors like
BowAttackorTeleportMovement
- Go Implementation: See
../objects-go/for the same exercises implemented in Go, with a comparison of how Go approaches OOP differently
This is an educational project for learning OOP concepts.