36% complete
Object-Oriented Programming in Java
Object-Oriented Programming (OOP) is a programming paradigm that uses "objects" to design applications. In this tutorial, you'll learn the core concepts of OOP in Java and how to implement them in your programs.
What is Object-Oriented Programming?
Object-Oriented Programming (OOP) is a programming approach that organizes software design around objects rather than functions and logic. An object is a self-contained unit that contains data (attributes) and procedures (methods) that operate on that data.
Java is a primarily object-oriented language, which means almost everything in Java is an object. Understanding OOP concepts is crucial for effective Java programming.
Core Principles of OOP
There are four main principles of Object-Oriented Programming:
Encapsulation
Bundling data (attributes) and methods (functions) that operate on the data into a single unit (class), and restricting direct access to some of the object's components.
Inheritance
The ability of a class to inherit properties and methods from a parent class, enabling code reuse and establishing a relationship between classes.
Polymorphism
The ability to present the same interface for different underlying forms (data types). It allows objects of different classes to be treated as objects of a common superclass.
Abstraction
Hiding complex implementation details and showing only the necessary features of an object. It reduces complexity by hiding irrelevant details.
Classes and Objects
Classes
A class is a blueprint or template that defines the variables and methods common to all objects of a certain kind. In Java, a class is declared using the class
keyword:
1// Class declaration2public class Car {3 // Instance variables (attributes)4 private String make;5 private String model;6 private int year;7 private double fuelLevel;89 // Constructor10 public Car(String make, String model, int year) {11 this.make = make;12 this.model = model;13 this.year = year;14 this.fuelLevel = 0.0;15 }1617 // Methods18 public void startEngine() {19 System.out.println("Engine started!");20 }2122 public void drive() {23 if (fuelLevel > 0) {24 System.out.println("The car is driving...");25 fuelLevel -= 0.1;26 } else {27 System.out.println("Cannot drive. The fuel tank is empty.");28 }29 }3031 public void refuel(double amount) {32 fuelLevel += amount;33 System.out.println("Fuel level is now: " + fuelLevel);34 }3536 // Getter methods37 public String getMake() {38 return make;39 }4041 public String getModel() {42 return model;43 }4445 public int getYear() {46 return year;47 }4849 public double getFuelLevel() {50 return fuelLevel;51 }52}
Objects
An object is an instance of a class. When a class is defined, no memory is allocated until an object is created. To create an object, you use the new
keyword followed by a call to a constructor:
1// Creating objects from the Car class2public class CarDemo {3 public static void main(String[] args) {4 // Create car objects5 Car myCar = new Car("Toyota", "Corolla", 2022);6 Car friendsCar = new Car("Honda", "Civic", 2021);78 // Using object methods9 myCar.refuel(5.0);10 myCar.startEngine();11 myCar.drive();1213 // Accessing object properties using getter methods14 System.out.println("My car is a " + myCar.getYear() + " " +15 myCar.getMake() + " " + myCar.getModel());1617 friendsCar.refuel(3.5);18 System.out.println("Friend's car fuel level: " + friendsCar.getFuelLevel());19 }20}
Important:
Each object created from a class has its own set of instance variables. Changes to one object's instance variables don't affect other objects of the same class.
Encapsulation
Encapsulation is the technique of making the fields in a class private and providing access to them via public methods. It's a protective barrier that keeps the data and code safe from external interference and misuse.
Benefits of Encapsulation
- Data Hiding: The implementation details are hidden from the outside world
- Increased Flexibility: You can change the implementation without affecting the code that uses the class
- Reusability: Encapsulated code can be reused easily
- Testing: Encapsulated code is easier to test as the units are well-defined
Implementing Encapsulation
In Java, encapsulation is implemented by:
- Declaring the instance variables of a class as private
- Providing public setter and getter methods to modify and view the variables' values
1public class BankAccount {2 // Private variables (encapsulated)3 private String accountNumber;4 private String accountHolder;5 private double balance;67 // Constructor8 public BankAccount(String accountNumber, String accountHolder) {9 this.accountNumber = accountNumber;10 this.accountHolder = accountHolder;11 this.balance = 0.0;12 }1314 // Getter methods15 public String getAccountNumber() {16 return accountNumber;17 }1819 public String getAccountHolder() {20 return accountHolder;21 }2223 public double getBalance() {24 return balance;25 }2627 // Setter method with validation28 public void setAccountHolder(String accountHolder) {29 if (accountHolder != null && !accountHolder.isEmpty()) {30 this.accountHolder = accountHolder;31 }32 }3334 // Methods that modify private data35 public void deposit(double amount) {36 if (amount > 0) {37 balance += amount;38 System.out.println(amount + " deposited. New balance: " + balance);39 } else {40 System.out.println("Invalid deposit amount.");41 }42 }4344 public void withdraw(double amount) {45 if (amount > 0 && amount <= balance) {46 balance -= amount;47 System.out.println(amount + " withdrawn. New balance: " + balance);48 } else {49 System.out.println("Invalid withdrawal amount or insufficient funds.");50 }51 }52}
Inheritance
Inheritance is a mechanism by which one class (child or subclass) can inherit the properties and methods of another class (parent or superclass). It promotes code reuse and establishes a relationship between classes.
In Java, inheritance is implemented using the extends
keyword:
1// Parent class2public class Vehicle {3 protected String make;4 protected String model;5 protected int year;67 public Vehicle(String make, String model, int year) {8 this.make = make;9 this.model = model;10 this.year = year;11 }1213 public void startEngine() {14 System.out.println("Engine started!");15 }1617 public void stopEngine() {18 System.out.println("Engine stopped.");19 }2021 public String getInfo() {22 return year + " " + make + " " + model;23 }24}2526// Child class inheriting from Vehicle27public class Car extends Vehicle {28 private int numberOfDoors;29 private boolean isConvertible;3031 public Car(String make, String model, int year, int numberOfDoors, boolean isConvertible) {32 super(make, model, year); // Call the parent constructor33 this.numberOfDoors = numberOfDoors;34 this.isConvertible = isConvertible;35 }3637 // Override parent method38 @Override39 public void startEngine() {40 System.out.println("Car engine started with key.");41 }4243 // New method specific to Car44 public void honk() {45 System.out.println("Honk! Honk!");46 }4748 // Getter methods49 public int getNumberOfDoors() {50 return numberOfDoors;51 }5253 public boolean isConvertible() {54 return isConvertible;55 }56}
Types of Inheritance
Java supports several types of inheritance:
Type | Description | Java Support |
---|---|---|
Single Inheritance | A class inherits from one parent class | Supported |
Multiple Inheritance | A class inherits from multiple parent classes | Not supported directly (but can be achieved with interfaces) |
Multilevel Inheritance | A class inherits from a child class (chain of inheritance) | Supported |
Hierarchical Inheritance | Multiple classes inherit from a single parent class | Supported |
Polymorphism
Polymorphism means "many forms" and it occurs when we have many classes that are related to each other by inheritance. It allows us to perform a single action in different ways.
In Java, polymorphism is mainly divided into two types:
1. Compile-time Polymorphism (Method Overloading)
Method overloading allows a class to have more than one method with the same name if their parameter lists are different:
1public class Calculator {2 // Method overloading example34 // Method to add two integers5 public int add(int a, int b) {6 return a + b;7 }89 // Method to add three integers (different number of parameters)10 public int add(int a, int b, int c) {11 return a + b + c;12 }1314 // Method to add two doubles (different parameter types)15 public double add(double a, double b) {16 return a + b;17 }1819 // Method to concatenate two strings (different parameter types)20 public String add(String a, String b) {21 return a + b;22 }23}
2. Runtime Polymorphism (Method Overriding)
Method overriding occurs when a subclass has the same method as the parent class. In this case, the method in the subclass overrides the method in the parent class:
1// Parent class2class Animal {3 public void makeSound() {4 System.out.println("Animal makes a sound");5 }6}78// Child class overriding the method9class Dog extends Animal {10 @Override11 public void makeSound() {12 System.out.println("Dog barks: Woof! Woof!");13 }14}1516// Child class overriding the method17class Cat extends Animal {18 @Override19 public void makeSound() {20 System.out.println("Cat meows: Meow!");21 }22}2324// Using polymorphism25public class AnimalDemo {26 public static void main(String[] args) {27 // Create an array of Animal objects28 Animal[] animals = new Animal[3];29 animals[0] = new Animal();30 animals[1] = new Dog();31 animals[2] = new Cat();3233 // Call the makeSound method for each animal34 for (Animal animal : animals) {35 animal.makeSound(); // This will call the appropriate method based on the actual object type36 }3738 // Output:39 // Animal makes a sound40 // Dog barks: Woof! Woof!41 // Cat meows: Meow!42 }43}
Abstraction
Abstraction is the concept of hiding the complex implementation details and showing only the necessary features of an object. It helps in reducing programming complexity and effort.
In Java, abstraction can be achieved using:
1. Abstract Classes
An abstract class is a class that cannot be instantiated and may contain abstract methods (methods without a body):
1// Abstract class2abstract class Shape {3 // Abstract method (no implementation)4 public abstract double calculateArea();56 // Concrete method7 public void display() {8 System.out.println("This is a shape with area: " + calculateArea());9 }10}1112// Concrete subclass13class Circle extends Shape {14 private double radius;1516 public Circle(double radius) {17 this.radius = radius;18 }1920 // Implementation of abstract method21 @Override22 public double calculateArea() {23 return Math.PI * radius * radius;24 }25}2627// Concrete subclass28class Rectangle extends Shape {29 private double length;30 private double width;3132 public Rectangle(double length, double width) {33 this.length = length;34 this.width = width;35 }3637 // Implementation of abstract method38 @Override39 public double calculateArea() {40 return length * width;41 }42}
2. Interfaces
An interface is a completely abstract class that contains only abstract methods and constants:
1// Interface2interface Drawable {3 void draw(); // Abstract method (by default)45 // Default method (Java 8+)6 default void display() {7 System.out.println("Displaying drawable object");8 }9}1011// Class implementing the interface12class Circle implements Drawable {13 private double radius;1415 public Circle(double radius) {16 this.radius = radius;17 }1819 // Implementation of interface method20 @Override21 public void draw() {22 System.out.println("Drawing a circle with radius: " + radius);23 }24}2526// Class implementing the interface27class Rectangle implements Drawable {28 private double length;29 private double width;3031 public Rectangle(double length, double width) {32 this.length = length;33 this.width = width;34 }3536 // Implementation of interface method37 @Override38 public void draw() {39 System.out.println("Drawing a rectangle with length: " + length + " and width: " + width);40 }41}
Practice Exercises
- Create a class hierarchy for different types of vehicles (car, motorcycle, truck) with appropriate properties and methods.
- Implement a banking system with different types of accounts (savings, checking) that inherit from a common base account class.
- Design a shape class hierarchy with methods to calculate area and perimeter for different shapes.
- Create a payroll system for different types of employees (full-time, part-time, contractor) with different payment calculations.
- Implement an e-commerce system with products, customers, and orders using object-oriented principles.
Summary
In this tutorial, you've learned:
- The four main principles of Object-Oriented Programming: Encapsulation, Inheritance, Polymorphism, and Abstraction
- How to create classes and objects in Java
- How to implement encapsulation by using private fields and public methods
- How to use inheritance to create class hierarchies
- How to achieve polymorphism through method overloading and overriding
- How to implement abstraction using abstract classes and interfaces
Object-Oriented Programming is a powerful paradigm that can help you create more modular, flexible, and maintainable code. As you continue your Java journey, you'll find that mastering these concepts will greatly enhance your ability to design and implement complex software systems.
In the next tutorials, we'll dive deeper into specific OOP concepts like classes and objects, inheritance, and interfaces.
Related Tutorials
Learn about decision making and loops in Java.
Learn moreDeep dive into creating and using classes and objects in Java.
Learn moreLearn how to extend classes and create class hierarchies in Java.
Learn more