What is Object-Oriented Programming (OOP)? Basic Concepts and Principles

Süleyman Güzey
7 min readAug 28, 2024

--

Object-Oriented Programming (OOP) is a programming paradigm that aims to model real-world entities and concepts in the software development process. This approach makes the software more understandable, flexible, and maintainable. In this article, we will discuss the fundamental concepts and principles of OOP in detail.

Table of Contents

1. Objects and Classes
2. Encapsulation
3. Inheritance
4. Polymorphism
5. Constructors and Destructors
6. Static Members and Methods
7. Garbage Collection
8. Abstract Classes and Methods
9. Interfaces
10. Enumerations
11. Conclusion

Objects and Classes

What is an Object?
An object is a representation of a real-world entity in the software world. For example, consider a human object. This object includes the distinctive features and behaviors of a human.

Features of a Human:

- Height
- Eye Color
- Weight
- IQ Level
- Speaking Style

These features represent the state of the object, while the actions it can perform are called methods.

What is a Class?
A class is a structure that brings together objects with similar features and behaviors. Classes can be thought of as the blueprint or template for objects.

Class Definition Example:

java
public class Human {
// Features
private double height;
private String eyeColor;
private double weight;
private int iqLevel;
private String speakingStyle;

// Methods
public void walk() {
// Walking action
}

public void speak() {
// Speaking action
}

// Constructor
public Human(double height, String eyeColor, double weight, int iqLevel, String speakingStyle) {
this.height = height;
this.eyeColor = eyeColor;
this.weight = weight;
this.iqLevel = iqLevel;
this.speakingStyle = speakingStyle;
}
}

In this example, the `Human` class defines the features and behaviors of a human object. Every object created from the class will have these features and methods.

Encapsulation
Encapsulation is the principle of keeping data and methods together and hiding them from the outside world. This prevents external access to the class’s data directly, allowing controlled management of the data.

Benefits of Encapsulation:

- Protects data and prevents unauthorized access.
- Makes code more readable and maintainable.
- Ensures that changes within a class do not affect external code.

Access Modifiers:

- public: Accessible from anywhere.
- private: Accessible only within the class where it’s defined.
- protected: Accessible within the class and its subclasses.
- (Default): Accessible within the same package.

Example:

java
public class BankAccount {
private double balance;

public double getBalance() {
return balance;
}

public void deposit(double amount) {
if (amount > 0) {
balance += amount;
}
}

public void withdraw(double amount) {
if (amount > 0 && balance >= amount) {
balance -= amount;
}
}
}

In this example, the `balance` variable is defined as `private`, meaning it can only be accessed through the methods within the class.

Inheritance
Inheritance is the process of deriving a new class from an existing class. The new class inherits the properties and behaviors of the parent class and can extend or customize them.

Benefits:

- Reduces code redundancy.
- Provides a more organized and hierarchical structure.
- Enables the creation of flexible and extendable systems.

Key Terms:

- Superclass (Parent Class): The class from which properties and behaviors are inherited.
- Subclass (Derived Class): The class that inherits properties and behaviors from the superclass and extends them.

Example:

java
public class Animal {
public void makeSound() {
System.out.println(“Animal makes a sound.”);
}
}

public class Dog extends Animal {
@Override
public void makeSound() {
System.out.println(“Bark!”);
}
}

public class Cat extends Animal {
@Override
public void makeSound() {
System.out.println(“Meow!”);
}
}

In this example, the `Dog` and `Cat` classes inherit from the `Animal` class and override the `makeSound` method.

Inheritance Rules:

- In Java, each class can have only one superclass (single inheritance).
- Inheritance is implemented using the `extends` keyword.
- A subclass can access the `public` and `protected` members of the superclass.
- Constructors are not inherited, but the superclass constructor can be called using `super()`.

Constructors and Inheritance:

- When a subclass’s constructor is called, the superclass’s constructor runs first.
- The superclass constructor is called using `super()`, and this call must be the first statement in the constructor.
- If `super()` is not explicitly called, the compiler implicitly calls the parameterless constructor of the superclass.

Example:

java
public class Animal {
public Animal() {
System.out.println(“Animal created.”);
}
}

public class Bird extends Animal {
public Bird() {
super();
System.out.println(“Bird created.”);
}
}

In this example, when the constructor of the `Bird` class is called, the constructor of the `Animal` class runs first.

Final Methods and Classes:

- Classes defined with the `final` keyword cannot be inherited.
- Final methods cannot be overridden in subclasses.
- This structure ensures that classes and methods are used in their current form and cannot be modified.

Example:

java
public final class Mathematics {
public final double PI = 3.14;

public final double square(double number) {
return number * number;
}
}

Polymorphism
Polymorphism is the ability of different objects that share the same interface or base class to implement the same method in different ways. This makes the code more flexible and extendable.

Types:

- Method Overriding: Subclasses redefine methods of the superclass according to their needs.
- Method Overloading: Multiple methods with the same name but different parameter lists are defined within the same class.

Example — Method Overriding:

java
public class Shape {
public void draw() {
System.out.println(“Drawing a shape.”);
}
}

public class Circle extends Shape {
@Override
public void draw() {
System.out.println(“Drawing a circle.”);
}
}

public class Rectangle extends Shape {
@Override
public void draw() {
System.out.println(“Drawing a rectangle.”);
}
}

Upcasting and Polymorphism:

java
public class Main {
public static void main(String[] args) {
Shape shape1 = new Circle();
Shape shape2 = new Rectangle();

shape1.draw(); // Output: Drawing a circle.
shape2.draw(); // Output: Drawing a rectangle.
}
}

In this example, the `Shape` reference holds different subclass objects, demonstrating polymorphism.

Notes:

- Polymorphism cannot be achieved through static methods.
- Polymorphism enhances software extensibility and maintainability.

Constructors and Destructors

Constructors
Constructors are special methods called when a new object is created from a class. They are used to set up the initial state of an object.

Features:

- Must have the same name as the class.
- Do not specify a return type.
- Can be overloaded, meaning multiple constructors with different parameter lists can be defined.
- `this()` can be used to call other constructors within the same class.
- `super()` can be used to call constructors from the superclass.

Example:

java
public class Car {
private String brand;
private String model;
private int year;

public Car() {
this(“Unknown”, “Unknown”, 0);
}

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

Destructors
In Java, destructors are not defined directly. Memory management is handled automatically by the Garbage Collector. However, the `finalize()` method can be used for resource cleanup or special operations before an object is garbage collected.

Note: The use of the `finalize()` method is not recommended in Java 9 and later versions.

Static Members and Methods
Static members are class-level members shared by all objects. They can be accessed directly through the class name without creating an instance.

Features:

- Defined with the `static` keyword.
- Hold a common value for all objects.
- Only static members can be accessed within static methods.
- Often used for helper functions and constants.

Example:

java
public class Mathematics {
public static final double PI = 3.1415;

public static double square(double number) {
return number * number;
}
}

public class Main {
public static void main(String[] args) {
double area = Mathematics.PI * Mathematics.square(5);
System.out.println(“Area of the circle: “ + area);
}
}

Static Blocks

- Executed once when the class is loaded.
- Used to initialize static variables.

Example:

java
public class Settings {
public static String appName;

static {
appName = “Demo Application”;
System.out.println(“Static block executed.”);
}
}

Garbage Collection
Garbage Collection is a mechanism in Java that automatically manages memory. Unused objects are identified and removed from memory, preventing memory leaks.

Features:

- Runs automatically in the background.
- The `System.gc()` method can be called to request Garbage Collection.
- The Garbage Collector works with a priority-based approach.

Memory Leaks and Java:
Java significantly reduces the risk of memory leaks through automatic Garbage Collection. However, care must still be taken when using resources like file handles, database connections, etc.

Abstract Classes and Methods

Abstract Classes
An abstract class cannot be instantiated and may include both abstract methods (without implementation) and concrete methods (with implementation).

Features:

- Defined with the `abstract` keyword.
- Abstract methods must be overridden in derived classes.
- Used to define a general concept, leaving specific implementations to subclasses.

Example:

java
public abstract class Shape {
public abstract void draw(); // Abstract method

public void commonMethod() {
System.out.println(“Common functionality”);
}
}

public class Circle extends Shape {
@Override
public void draw() {
System.out.println(“Drawing a circle”);
}
}

Abstract Methods

Abstract methods are defined without implementation in abstract classes and must be overridden in subclasses.

Example:

java
public abstract class Vehicle {
public abstract void startEngine();
}

public class Car extends Vehicle {
@Override
public void startEngine() {
System.out.println(“Car engine started.”);
}
}

Interfaces
Interfaces are collections of method signatures (declarations) and constants. Classes implement interfaces by providing concrete implementations for all the methods declared in the interface.

Features:

- Defined with the `interface` keyword.
- Methods are implicitly `public` and `abstract`.
- Multiple interfaces can be implemented by a single class.
- Interface variables are implicitly `public`, `static`, and `final`.

Example:

java
public interface Drivable {
void accelerate();
void brake();
}

public class Car implements Drivable {
@Override
public void accelerate() {
System.out.println(“Car is accelerating.”);
}

@Override
public void brake() {
System.out.println(“Car is braking.”);
}
}

Differences Between Interfaces and Abstract Classes:

- Interfaces support multiple inheritance, while abstract classes do not.
- Interfaces cannot have constructors, instance variables, or concrete methods (until Java 8 introduced default methods).
- Abstract classes are used for classes that are closely related, while interfaces are used to specify roles or abilities.

Enumerations
Enumerations (enums) represent a group of named constants. Enums are useful when a variable can only take one of a predefined set of values.

Features:

- Defined with the `enum` keyword.
- Enum constants are implicitly `public`, `static`, and `final`.
- Can include methods, constructors, and fields.

Example:

java
public enum Day {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
}

public class Main {
public static void main(String[] args) {
Day today = Day.WEDNESDAY;
System.out.println(“Today is: “ + today);
}
}

Conclusion
Object-Oriented Programming (OOP) is a powerful paradigm that models real-world concepts and entities, making software development more intuitive, maintainable, and scalable. The core principles of OOP — Encapsulation, Inheritance, Polymorphism, and Abstraction — form the foundation of modern software design. Mastering these concepts is crucial for any developer aiming to build robust and flexible applications.

--

--

Süleyman Güzey
Süleyman Güzey

Written by Süleyman Güzey

Software Engineering 3rd Year Student I am developing my skills in the fields of artificial intelligence and embedded systems.

No responses yet