Published on

OOP Mastery: Complete Object-Oriented Programming Knowledge for Newbies

Authors

Welcome to DanTech0xFF's series of articles on Object-Oriented Programming (OOP) knowledge. In this series, I will focus on conveying Object-Oriented Programming knowledge in the most accessible and easy-to-understand way, with the sole purpose of helping everyone clearly understand, master the knowledge, and apply it well to their studies and future work as a Programmer.

If you already have knowledge of OOP, you can refer to the series of articles on OOP in Kotlin to learn faster.

  • Part 1: OOP Mastery: Types of Classes and Interfaces in Kotlin
  • Part 2: OOP Mastery: Encapsulation in Kotlin
  • Part 3: OOP Mastery: Inheritance in Kotlin
  • Part 4: OOP Mastery: Polymorphism in Kotlin
  • Part 5: OOP Mastery: Abstraction in Kotlin

How Did People Program Before OOP?

The programming work of Programmers has gone through many revolutions and changes to arrive at a method that is the basis and core of all current software - the Object-Oriented Programming method. In this exciting topic, let me introduce you to the programming methods that predecessors used when there was no Object-Oriented Programming (OOP) method.

Imperative Programming

Imperative programming is considered the simplest and most primitive way of programming.

In this stage, a program will consist of Input (input data) - Processing Command Sequence - Output (output data). Most programs in this development stage will be software used to calculate math operations and formulas to help scientists find answers faster. These programs have helped the science fields related to mathematics make great breakthroughs by saving experimentation and calculation time for scientists (Physics, Chemistry, Astronomy, ...)

A program written in Imperative Programming can be visualized as follows:

: Program A
- input
- Command 1 processes input -> output 1
- Command 2 processes output 1 -> output 2
- Command 3 processes output 2 -> output 3
- output

/*In reality, the program will contain more complex logic (loop, if - else, ...) */

It is clear that with this approach, programs become specific to each problem. The code commands written are not reusable between problems.

At this time, people invented a new programming method -> Functional Programming

Functional Programming

In the Functional Programming method, programmers still basically compile software based on designing command sequences for specific problems. However, when approaching functional programming, programmers will choose to handle problems in a general way first, then specific. This will help group reusable logic into functions and share them between multiple problems.

This improvement helps minimize resources spent on repetitive tasks, and they invent libraries that make software design and execution easier.

You can think of libraries like math.h - supporting the reuse of logic for mathematical operations that need to be used many times during calculations.

A program written using functional programming can be modeled as follows

: Program A

include library-1
include library-2
declare self-function-1
declare self-function-2

- input
- library-1$function // describes the use of library-1's function for a purpose
- library-2$function // describes the use of library-2's function for a purpose
- self-function-1 // describes the use of self-function-1 for a purpose
- self-function-2 // describes the use of self-function-2 for a purpose
- output

/*In reality, the program will contain more complex logic (loop, if - else, ...) */

In this approach, the program has become more general and more reusable. This proves that this is a better approach than the procedural approach.

As society develops, social needs increase - people create more and also demand more. Software at this time is no longer simply calculations - at this time, software becomes a system of solutions for people. Organizing programs through functions is no longer suitable for social needs.

Software development at this time also requires more people, and more work is divided. To optimize the resources of Programmers, they came to a new approach, Object-Oriented Programming - by isolating and objectifying the features in the program to make code development and reuse easier.

Definition of Object-Oriented Programming

Object-Oriented Programming (OOP) is a method of approaching problems based on the concept of "Objects". OOP will model software into entities (which can be tangible or intangible); entities will always have 2 basic types of resources: characteristics - attribute and behavior - method.

  • Characteristic - attribute: These are the values that the object holds, which can be updated and changed over time.

For example:

- Design software to draw a window on the computer screen with a width of 200px, a height of 80px, a gray window border, and a white background.
- In this specification, we can design a Window object with the following attributes to serve the program
  - width: 200px
  - height: 80px
  - borderColor: GRAY
  - backgroundColor: WHITE
  • Behavior - method: These are the behaviors that the object can perform. Performing methods can change the value of attributes.
- Inheriting the above specification, the window now has the ability to resize
- In this specification, we can design a Window object with the following behaviors to serve the program
  - function draw() -> used to display on the computer screen
  - function setSize(width, height) -> used to update the width and height values of the window

After having the specifications and Object-Oriented solutions for a program, we proceed to deploy it into the source code.

To clearly understand how to deploy Object-Oriented source code, you need to master the basic concepts of Object-Oriented programming.

Basic concepts in Object-Oriented

Class Concept

Class in Object-Oriented Programming is a blueprint for an Entity. You can imagine Class as the blueprint of a house, which includes all the indexes: door location, color of tables and chairs, house height, wind direction, feng shui ... all packed in a blueprint. Similarly, in programming, when we want to group certain characteristics and behaviors about an entity, we need to create a Class.

Here you need to imagine that we not only Objectify tangible entities such as Houses, animals, and people, but we can also Objectify intangible entities. For example, the logic of copying data from File A to File B, the logic of accessing data from the Database, the structure of a power equation problem n, ...

import java.io.File

class FileCopier {
    fun copy(sourcePath: String, destinationPath: String) {
        File(sourcePath).inputStream().use { input ->
            File(destinationPath).outputStream().use { output ->
                input.copyTo(output)
            }
        }
    }
} // Example of Objectifying a File Copy logic

Object Concept

Object is the product of the blueprint - Class mentioned above.

Each Class can produce many products (Objects), each Object in the process of running the program can have its indexes, states, and behaviors changed to carry different data inside for different purposes.

fun main(args: Array) {
    // Create an object of FileCopier class
    val fileCopier = FileCopier()

    // Define source and destination paths
    val source = "source.txt"
    val destination = "destination.txt"

    // Call the copy function with object reference
    fileCopier.copy(source, destination)

    println("File copied successfully!")
}

Encapsulation

Encapsulation is understood as the ability to hide the attributes and methods that are inside a Class.

Depending on the programming language, encapsulation can be expressed strongly or weakly. Most programming languages support 3 levels of encapsulation: private, protected, and public.

class BankAccount {
    private var balance: Double = 0.0

    fun deposit(amount: Double) {
        if (amount > 0) {
            balance += amount
            println("Deposit successful. Current balance: $balance")
        } else {
            println("The deposit amount must be greater than 0.")
        }
    }

    fun withdraw(amount: Double) {
        if (amount > 0 && amount
        animal.makeSound()
    }
}
open class Shape {
    open fun calculateArea(): Double {
        return 0.0
    }
}

// Ví dụ vê Override trong Kotlin
class Circle(val radius: Double) : Shape() {
    override fun calculateArea(): Double {
        return Math.PI * radius * radius
    }
}

class Rectangle(val width: Double, val height: Double) : Shape() {
    override fun calculateArea(): Double {
        return width * height
    }
}

Abstraction

Abstraction - an interesting feature in the approach of object-oriented programming.

Abstraction is expressed through the fact that when designing the features of the software, Programmers will focus on designing the workflow of behaviors (behaviour / method) and then divide them into Classes without going into specific details. The Classes designed at this stage are called Abstract Class, or can also be called Interface in some cases.

Example: Designing a solution for the problem of managing a list of students of a programming training center.

In the first step, we cannot immediately choose the database (SQL, or MySQL) or even Google Sheet and start writing code. Instead, we start thinking about the workflow of this solution, the tasks that need to be done by the application, and gradually develop it.

data class Student(val id: Long)
interface StudentDataAccessLayer {
  fun insertStudent(student: Student)
  fun deleteStudent(student: Student): Boolean
  fun deleteStudent(val ids: List): Int
  fun updateStudent(student: Student): Boolean
} // This work is the Abstract design for the software

Once there is an Abstract Layer for the features, the realization (Implementation) will be discussed and implemented later.

SOLVE THE PROBLEM BEFORE CODE IT!

Core Values of Object-Oriented Programming

Object-Oriented Programming was created with the purpose of increasing code reusability, helping software design become more intuitive in the process of communication between people. Object-oriented also benefits from easier software expansion, making software maintenance easier for Programmers.