Object-Oriented Programming in Java

Welcome to the second part of the Learn Java series! In this section, we will dive into one of Java's core concepts: Object-Oriented Programming (OOP). OOP allows us to create programs that are more modular, reusable, and easier to maintain. Java is a fully object-oriented language, which makes OOP essential to mastering the language.

What is Object-Oriented Programming?

OOP is a programming paradigm based on the concept of "objects," which can contain data and code that manipulates the data. The four core principles of OOP are:

Classes and Objects

In Java, a class is a blueprint for creating objects (instances). Each object has fields (attributes) and methods (behavior). Let’s look at an example:

public class Car {
    // Fields (attributes)
    String model;
    String color;
    int year;

    // Constructor
    public Car(String model, String color, int year) {
        this.model = model;
        this.color = color;
        this.year = year;
    }

    // Method (behavior)
    public void start() {
        System.out.println(model + " is starting.");
    }
}

In this example:

Creating an Object

To create an object from the Car class, you would do the following:

public class Main {
    public static void main(String[] args) {
        // Creating an object of the Car class
        Car myCar = new Car("Tesla", "Red", 2023);
        myCar.start();  // Output: Tesla is starting.
    }
}

This code creates an instance of the Car class named myCar and calls its start method.

Inheritance

Inheritance allows one class (subclass) to inherit fields and methods from another class (superclass). Let’s modify our example:

public class ElectricCar extends Car {
    int batteryLife;

    public ElectricCar(String model, String color, int year, int batteryLife) {
        super(model, color, year);
        this.batteryLife = batteryLife;
    }

    public void charge() {
        System.out.println(model + " is charging. Battery life: " + batteryLife + " hours.");
    }
}

In this example:

Polymorphism

Polymorphism allows us to use a subclass object wherever a superclass object is expected. For example:

public class Main {
    public static void main(String[] args) {
        Car myCar = new ElectricCar("Tesla", "Red", 2023, 12);
        myCar.start();  // Output: Tesla is starting.
        
        // myCar.charge();  // This would cause a compilation error because myCar is of type Car, not ElectricCar
    }
}

Here, myCar is a reference of type Car, but it points to an ElectricCar object. The method start() is called based on the object type (ElectricCar), but charge() cannot be called directly since it belongs to the subclass.

Encapsulation

Encapsulation is the practice of keeping fields private and providing public methods to access and modify them. This protects the internal state of an object from unintended modification. For example:

public class Car {
    private String model;
    private String color;
    private int year;

    public Car(String model, String color, int year) {
        this.model = model;
        this.color = color;
        this.year = year;
    }

    // Getter and Setter methods
    public String getModel() {
        return model;
    }

    public void setModel(String model) {
        this.model = model;
    }
}

Here, the fields model, color, and year are private, meaning they can only be accessed through public getter and setter methods.

Abstraction

Abstraction is used to hide the internal implementation details of an object and only expose what is necessary. In Java, abstraction can be achieved using abstract classes and interfaces.

Abstract Classes

An abstract class is a class that cannot be instantiated on its own and is meant to be subclassed. It can have abstract methods (without implementation) that must be implemented by subclasses. Here’s an example:

abstract class Animal {
    abstract void makeSound();

    public void eat() {
        System.out.println("This animal eats food.");
    }
}

class Dog extends Animal {
    @Override
    void makeSound() {
        System.out.println("Woof! Woof!");
    }
}

In this example:

Interfaces

Interfaces in Java are abstract types that can contain method signatures but no implementation. A class can implement multiple interfaces, providing implementations for all of their methods. Here’s an example:

interface Drivable {
    void drive();
}

class Car implements Drivable {
    @Override
    public void drive() {
        System.out.println("The car is driving.");
    }
}

In this example:

Conclusion

Object-Oriented Programming (OOP) is a powerful paradigm that helps you build robust and maintainable software. By understanding the principles of OOP, you can create classes and objects that model real-world entities and interactions more effectively. In this lesson, we covered the core principles of OOP, including encapsulation, inheritance, polymorphism, and abstraction, along with examples to illustrate these concepts.