Panduan OOP Java Lengkap: Kuasai 4 Pilar Pemrograman Berorientasi Objek dalam 7 Hari

By | September 27, 2025

Panduan OOP Java Lengkap: Kuasai 4 Pilar Pemrograman Berorientasi Objek dalam 7 Hari

Pernah nggak sih kamu bingung dengan istilah-istilah OOP seperti inheritance, polymorphism, atau encapsulation? Atau mungkin kamu sudah belajar Java dasar tapi masih struggle untuk membuat program yang terstruktur dan mudah di-maintain? Tenang, kamu nggak sendirian! OOP Java memang seperti belajar bahasa baru—tapi sekali kamu paham konsepnya, semuanya akan jadi masuk akal.

Pemrograman Berorientasi Objek (OOP) adalah cara berpikir tentang programming yang mirip dengan bagaimana kita melihat dunia nyata. Bayangkan setiap object di sekitar kita—mobil, handphone, bahkan kamu sendiri—punya properties dan behavior tertentu. Nah, OOP menerapkan konsep ini dalam programming!

Di panduan lengkap ini, kita akan jelajahi konsep OOP dari dasar sampai advanced, dengan contoh nyata dalam Java. Siap-siap untuk transformasi dari programmer procedural jadi OOP master!

Apa Itu OOP? Memahami Filosofi Dasar

Object-Oriented Programming (OOP) adalah paradigma programming yang mengorganisasi software design around data, atau objects, rather than functions and logic. Instead of thinking about “what steps need to be done,” kita think tentang “what objects interact with each other.”

Analog Sederhana: Dunia Nyata

Bayangkan kamu mau bikin program untuk manage restoran. Dengan pendekatan procedural, kamu akan pikirkan: “Pertama, ambil order. Kedua, masak makanan. Ketiga, sajikan.”

Dengan OOP, kamu akan pikirkan: “Ada object Customer, object Order, object Chef, object Waiter. Mereka berinteraksi satu sama lain.”

4 Pilar OOP yang Wajib Dikuasai

1. Encapsulation (Enkapsulasi) – Kapsul Data

Konsep menyembunyikan detail internal object dan hanya mengekspos functionality yang diperlukan.

Contoh Implementasi:

public class BankAccount {
    // Private fields - hidden from outside
    private String accountNumber;
    private double balance;
    private String ownerName;
    
    // Public methods - exposed interface
    public BankAccount(String accountNumber, String ownerName) {
        this.accountNumber = accountNumber;
        this.ownerName = ownerName;
        this.balance = 0.0;
    }
    
    public void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
            System.out.println("Deposited: " + amount);
        }
    }
    
    public boolean withdraw(double amount) {
        if (amount > 0 && amount <= balance) {
            balance -= amount;
            System.out.println("Withdrawn: " + amount);
            return true;
        }
        return false;
    }
    
    // Getter methods - controlled access
    public double getBalance() {
        return balance;
    }
    
    public String getAccountInfo() {
        return "Account: " + accountNumber + " - Owner: " + ownerName;
    }
}

2. Inheritance (Pewarisan) – Hubungan Parent-Child

Kemampuan class untuk mewarisi properties dan methods dari class lain.

Contoh Implementasi:

// Parent class (Superclass)
public class Vehicle {
    protected String brand;
    protected int year;
    protected double price;
    
    public Vehicle(String brand, int year, double price) {
        this.brand = brand;
        this.year = year;
        this.price = price;
    }
    
    public void start() {
        System.out.println(brand + " is starting...");
    }
    
    public void stop() {
        System.out.println(brand + " is stopping...");
    }
}

// Child class (Subclass) - Inheritance
public class Car extends Vehicle {
    private int numberOfDoors;
    private String fuelType;
    
    public Car(String brand, int year, double price, int doors, String fuel) {
        super(brand, year, price); // Call parent constructor
        this.numberOfDoors = doors;
        this.fuelType = fuel;
    }
    
    // Additional methods specific to Car
    public void honk() {
        System.out.println("Beep beep! " + brand + " is honking!");
    }
    
    // Method overriding - polymorphism in action
    @Override
    public void start() {
        System.out.println(brand + " car is starting with ignition...");
    }
}

// Another subclass
public class Motorcycle extends Vehicle {
    private boolean hasSideCar;
    
    public Motorcycle(String brand, int year, double price, boolean sideCar) {
        super(brand, year, price);
        this.hasSideCar = sideCar;
    }
    
    public void wheelie() {
        System.out.println(brand + " motorcycle is doing a wheelie!");
    }
}

3. Polymorphism (Polimorfisme) – Banyak Bentuk

Kemampuan object untuk mengambil banyak bentuk, biasanya melalui method overriding dan interfaces.

Contoh Implementasi:

// Interface untuk polymorphism
public interface Shape {
    double calculateArea();
    double calculatePerimeter();
}

// Multiple classes implementing the same interface
public class Circle implements Shape {
    private double radius;
    
    public Circle(double radius) {
        this.radius = radius;
    }
    
    @Override
    public double calculateArea() {
        return Math.PI * radius * radius;
    }
    
    @Override
    public double calculatePerimeter() {
        return 2 * Math.PI * radius;
    }
}

public class Rectangle implements Shape {
    private double width;
    private double height;
    
    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }
    
    @Override
    public double calculateArea() {
        return width * height;
    }
    
    @Override
    public double calculatePerimeter() {
        return 2 * (width + height);
    }
}

// Using polymorphism in action
public class ShapeCalculator {
    public void printArea(Shape shape) {
        System.out.println("Area: " + shape.calculateArea());
    }
    
    public void printPerimeter(Shape shape) {
        System.out.println("Perimeter: " + shape.calculatePerimeter());
    }
}

4. Abstraction (Abstraksi) – Menyembunyikan Kompleksitas

Konsep menyembunyikan detail implementasi dan hanya menampilkan functionality kepada user.

Contoh Implementasi:

// Abstract class - cannot be instantiated
public abstract class Employee {
    protected String name;
    protected int employeeId;
    protected double baseSalary;
    
    public Employee(String name, int employeeId, double baseSalary) {
        this.name = name;
        this.employeeId = employeeId;
        this.baseSalary = baseSalary;
    }
    
    // Abstract method - must be implemented by subclasses
    public abstract double calculateSalary();
    
    // Concrete method - common functionality
    public String getEmployeeInfo() {
        return "ID: " + employeeId + " - Name: " + name;
    }
}

// Concrete classes implementing abstract class
public class FullTimeEmployee extends Employee {
    private double bonus;
    
    public FullTimeEmployee(String name, int id, double salary, double bonus) {
        super(name, id, salary);
        this.bonus = bonus;
    }
    
    @Override
    public double calculateSalary() {
        return baseSalary + bonus;
    }
}

public class PartTimeEmployee extends Employee {
    private int hoursWorked;
    private double hourlyRate;
    
    public PartTimeEmployee(String name, int id, double hourlyRate, int hours) {
        super(name, id, 0); // Base salary not used for part-time
        this.hourlyRate = hourlyRate;
        this.hoursWorked = hours;
    }
    
    @Override
    public double calculateSalary() {
        return hoursWorked * hourlyRate;
    }
}

Konsep Penting Lainnya dalam OOP Java

Class vs Object

Class: Blueprint atau template untuk membuat objects
Object: Instance specific dari class

// Class definition
public class Student {
    private String name;
    private int age;
    
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

// Creating objects from the class
Student student1 = new Student("Alice", 20);  // Object 1
Student student2 = new Student("Bob", 22);    // Object 2

Constructor

Special method yang dipanggil ketika object dibuat.

public class Book {
    private String title;
    private String author;
    private int pageCount;
    
    // Default constructor
    public Book() {
        this.title = "Unknown";
        this.author = "Unknown";
        this.pageCount = 0;
    }
    
    // Parameterized constructor
    public Book(String title, String author, int pages) {
        this.title = title;
        this.author = author;
        this.pageCount = pages;
    }
    
    // Copy constructor
    public Book(Book other) {
        this.title = other.title;
        this.author = other.author;
        this.pageCount = other.pageCount;
    }
}

Static vs Instance Members

public class Calculator {
    // Instance variable - different for each object
    private String model;
    
    // Static variable - shared across all objects
    public static final String MANUFACTURER = "TechCorp";
    private static int calculatorCount = 0;
    
    public Calculator(String model) {
        this.model = model;
        calculatorCount++; // Increment static counter
    }
    
    // Instance method
    public String getModel() {
        return model;
    }
    
    // Static method
    public static int getCalculatorCount() {
        return calculatorCount;
    }
}

// Usage
Calculator calc1 = new Calculator("Model X");
Calculator calc2 = new Calculator("Model Y");

System.out.println(Calculator.getCalculatorCount()); // 2
System.out.println(Calculator.MANUFACTURER); // TechCorp

Implementasi Real-World: Sistem Manajemen Perpustakaan

Mari buat sistem lengkap dengan menerapkan semua konsep OOP:

// Abstract base class
public abstract class LibraryItem {
    protected String title;
    protected String itemId;
    protected boolean isAvailable;
    
    public LibraryItem(String title, String itemId) {
        this.title = title;
        this.itemId = itemId;
        this.isAvailable = true;
    }
    
    public abstract String getItemType();
    
    public boolean borrowItem() {
        if (isAvailable) {
            isAvailable = false;
            return true;
        }
        return false;
    }
    
    public void returnItem() {
        isAvailable = true;
    }
    
    // Getters and setters
    public String getTitle() { return title; }
    public String getItemId() { return itemId; }
    public boolean isAvailable() { return isAvailable; }
}

// Concrete classes
public class Book extends LibraryItem {
    private String author;
    private String isbn;
    private int pageCount;
    
    public Book(String title, String itemId, String author, String isbn, int pages) {
        super(title, itemId);
        this.author = author;
        this.isbn = isbn;
        this.pageCount = pages;
    }
    
    @Override
    public String getItemType() {
        return "Book";
    }
    
    // Additional methods specific to Book
    public String getAuthor() { return author; }
    public String getIsbn() { return isbn; }
}

public class DVD extends LibraryItem {
    private String director;
    private int duration; // in minutes
    private String rating;
    
    public DVD(String title, String itemId, String director, int duration, String rating) {
        super(title, itemId);
        this.director = director;
        this.duration = duration;
        this.rating = rating;
    }
    
    @Override
    public String getItemType() {
        return "DVD";
    }
}

// Interface for borrowable items
public interface Borrowable {
    boolean borrow(String borrowerId);
    boolean returnItem(String borrowerId);
    double calculateLateFee(int daysLate);
}

// Implementing interface
public class AdvancedBook extends Book implements Borrowable {
    private String currentBorrower;
    private LocalDate dueDate;
    
    public AdvancedBook(String title, String itemId, String author, String isbn, int pages) {
        super(title, itemId, author, isbn, pages);
    }
    
    @Override
    public boolean borrow(String borrowerId) {
        if (super.borrowItem()) {
            this.currentBorrower = borrowerId;
            this.dueDate = LocalDate.now().plusWeeks(2);
            return true;
        }
        return false;
    }
    
    @Override
    public boolean returnItem(String borrowerId) {
        if (borrowerId.equals(currentBorrower)) {
            super.returnItem();
            this.currentBorrower = null;
            this.dueDate = null;
            return true;
        }
        return false;
    }
    
    @Override
    public double calculateLateFee(int daysLate) {
        return daysLate * 1000; // Rp 1000 per day
    }
}

// Main class to test the system
public class LibraryManagementSystem {
    public static void main(String[] args) {
        // Create library items
        Book book1 = new Book("Java Programming", "B001", "John Doe", "123-456", 350);
        DVD dvd1 = new DVD("Inception", "D001", "Christopher Nolan", 148, "PG-13");
        AdvancedBook advancedBook = new AdvancedBook("Advanced Java", "B002", "Jane Smith", "789-012", 500);
        
        // Test polymorphism
        LibraryItem[] items = {book1, dvd1, advancedBook};
        
        for (LibraryItem item : items) {
            System.out.println(item.getTitle() + " - Type: " + item.getItemType());
        }
        
        // Test borrowing system
        advancedBook.borrow("USER123");
        System.out.println("Book borrowed: " + !advancedBook.isAvailable());
    }
}

Best Practices OOP dalam Java

1. Prinsip SOLID

  • S – Single Responsibility Principle
  • O – Open/Closed Principle
  • L – Liskov Substitution Principle
  • I – Interface Segregation Principle
  • D – Dependency Inversion Principle

2. Design Patterns yang Umum

// Singleton Pattern Example
public class DatabaseConnection {
    private static DatabaseConnection instance;
    
    private DatabaseConnection() {
        // Private constructor
    }
    
    public static DatabaseConnection getInstance() {
        if (instance == null) {
            instance = new DatabaseConnection();
        }
        return instance;
    }
}

// Factory Pattern Example
public class AnimalFactory {
    public static Animal createAnimal(String type) {
        switch (type.toLowerCase()) {
            case "dog": return new Dog();
            case "cat": return new Cat();
            case "bird": return new Bird();
            default: throw new IllegalArgumentException("Unknown animal type");
        }
    }
}

Common Mistakes dan How to Avoid Them

1. God Classes (Classes yang Terlalu Besar)

Problem: Satu class melakukan terlalu banyak hal
Solution: Break down into smaller, focused classes

2. Tight Coupling

Problem: Classes terlalu dependent satu sama lain
Solution: Use interfaces and dependency injection

3. Improper Inheritance

Problem: Using inheritance for code reuse instead of “is-a” relationship
Solution: Favor composition over inheritance when appropriate

Tools dan Resources untuk Belajar OOP Java

Recommended IDEs:

  • IntelliJ IDEA (Highly recommended)
  • Eclipse
  • NetBeans

Learning Resources:

  • Oracle Java Documentation
  • Head First Java (Book)
  • Java Programming Masterclass (Udemy)

Kesimpulan: OOP sebagai Foundation yang Kuat

Menguasai OOP Java bukan hanya tentang menghafal syntax, tapi tentang mengadopsi cara berpikir yang baru dalam memecahkan masalah programming. Dengan empat pilar utama—encapsulation, inheritance, polymorphism, dan abstraction—kamu bisa membangun software yang:

  • Lebih terorganisir dan mudah dipahami
  • Lebih mudah di-maintain dan extend
  • Reusable components yang menghemat waktu development
  • Scalable architecture untuk project besar

Ingat, belajar OOP itu seperti belajar naik sepeda—mungkin awkward di awal, tapi sekali kamu bisa, kamu nggak akan lupa lagi. Practice consistently, build small projects, dan soon you’ll be thinking in objects naturally!

Ready to become an OOP master? Start by implementing the library management system above, then create your own project using these concepts!