Pengenalan Pemrograman Berorientasi Objek (OOP)
Perbedaan Procedural dan Object Oriented |
Dalam dunia pemrogramman, ada yang disebut dengan
Paradigma Pemrogramman. Paradigma pemrograman adalah sebuah filosofi
yang mendasari cara programmer berpikir dan menulis kode. Paradigma ini
menentukan bagaimana program disusun, bagaimana data diorganisir, dan
bagaimana program berinteraksi dengan pengguna. Dua jenis paradigma yang
umum dijumpai adalah Procedural Programming dan
Object Oriented Programming (OOP).
Analoginya, Procedural Programming bagaikan mengikuti langkah-langkah dalam
sebuah resep atau panduan. Setiap langkah terhubung dengan langkah
sebelumnya, membentuk urutan instruksi yang terstruktur. Pendekatan ini
cocok untuk project kecil dan sederhana, di mana program didefinisikan
sebagai kumpulan prosedur yang berurutan.
function hitungTotalNilai(nilaiArr) {
let total = nilaiArr.reduce((total, nilai) => total + nilai, 0);
return total;
}
function hitungRataRata(nilai) {
const totalNilai = hitungTotalNilai(nilai);
const jumlahNilai = nilai.length;
const rataRata = totalNilai / jumlahNilai;
return rataRata;
}
const nilaiUjian = [80, 75, 90, 85, 95];
const totalNilai = hitungTotalNilai(nilaiUjian);
const rataRataNilai = hitungRataRata(nilaiUjian);
console.log(`Total nilai ujian: ${totalNilai}`);
console.log(`Rata-rata nilai ujian: ${rataRataNilai}`);
Sedangkan OOP berfokus pada `Object`, yakni sebuah entitas atau benda
yang memiliki data (property) dan kemampuan (method). OOP
bagaikan merancang sebuah blueprint atau skema untuk membuat objek tersebut.
class Mahasiswa {
constructor(nama, nilai) {
this.nama = nama;
this.nilai = nilai;
}
hitungTotalNilai() {
let total = this.nilai.reduce((total, nilai) => total + nilai, 0);
return total;
}
hitungRataRata() {
const totalNilai = this.hitungTotalNilai();
const jumlahNilai = this.nilai.length;
const rataRata = totalNilai / jumlahNilai;
return rataRata;
}
displayMessage() {
console.log(`Nama: ${this.nama}`);
console.log(`Total Nilai: ${this.hitungTotalNilai()}`);
console.log(`Rata-rata Nilai: ${this.hitungRataRata()}`);
}
}
const mahasiswa1 = new Mahasiswa("Budi", [80, 75, 90]);
const mahasiswa2 = new Mahasiswa("Ani", [85, 95, 90]);
mahasiswa1.displayMessage();
mahasiswa2.displayMessage();
Dasar-Dasar Pemrograman Berorientasi Objek
Object dalam Javascript
Object ibarat wadah yang berisi berbagai informasi tentang
suatu entitas atau benda. Object memiliki property (seperti
nama, warna, bentuk) untuk menyimpan data tentang object tersebut,
dan method (function yang ada di dalam object) yang
memungkinkan object untuk melakukan tindakan.
const mobil = {
name: "Toyota Avanza", // Property
max_kecepatan: 120, // Property
kecepatan: 0, // Property
tambahKecepatan: function (num) { // Method
if (this.kecepatan + num > this.max_kecepatan) {
return 'Melebihi maximum kecepatan.';
}
this.kecepatan += num;
return this.kecepatan;
},
kurangiKecepatan: function (num) { // Method
if (this.kecepatan - num < 0) {
return 'Kecepatan tidak boleh negatif.';
}
this.kecepatan -= num;
return this.kecepatan;
}
};
console.log(mobil.kecepatan);
console.log(mobil.tambahKecepatan(45));
console.log(mobil.kurangiKecepatan(20));
Dalam object di Javascript, terdapat keyword this yang
memiliki fungsi merujuk kepada object yang sedang dieksekusi. Secara
sederhana, property dalam object bisa diibaratkan seperti variable, untuk
mengakses property tersebut kita gunakan keyword this. Contohnya
pada bagian this.kecepatan merujuk kepada property
kecepatan dalam object tersebut.
Membuat Object Menggunakan Class
Visualisasi Class |
Ketika kita ingin membuat object dengan struktur yang sama berulang kali,
dua pendekatan utama dapat digunakan adalah membuat
Function Constructor atau Class.
Function Constructor merupakan cara lama untuk membuat
object di Javascript. Cara ini berfokus pada function yang mengembalikan
object baru dengan struktur yang telah ditentukan.
function Mobil(name, max_kecepatan) {
this.name = name,
this.max_kecepatan = max_kecepatan;
this.kecepatan = 0;
this.tambahKecepatan = (num) => {
if (this.kecepatan + num > this.max_kecepatan) {
return 'Melebihi maximum kecepatan.';
}
this.kecepatan += num;
return this.kecepatan;
}
this.kurangiKecepatan = (num) => {
if (this.kecepatan - num < 0) {
return 'Kecepatan tidak boleh negatif.';
}
this.kecepatan -= num;
return this.kecepatan;
}
}
const Mobil_Toyota = new Mobil("Toyota Avanza", 120);
console.log(Mobil_Toyota.tambahKecepatan(130));
console.log(Mobil_Toyota.kurangiKecepatan(19));
const Mobil_Tesla = new Mobil("Tesla Model S", 115);
console.log(Mobil_Tesla.tambahKecepatan(40));
console.log(Mobil_Tesla.kurangiKecepatan(20));
Pada Javascript versi ES6, diperkenalkan fitur Class untuk membuat
sebuah object dengan sintaks yang lebih ringkas. Di dalam class terdapat
method constructor untuk mendefinisikan property dalam object
tersebut
class Mobil {
constructor(name, max_kecepatan) {
this.name = name,
this.max_kecepatan = max_kecepatan;
this.kecepatan = 0;
}
tambahKecepatan = (num) => {
if (this.kecepatan + num > this.max_kecepatan) {
return 'Melebihi maximum kecepatan.';
}
this.kecepatan += num;
return this.kecepatan;
}
kurangiKecepatan = (num) => {
if (this.kecepatan - num < 0) {
return 'Kecepatan tidak boleh negatif.';
}
this.kecepatan -= num;
return this.kecepatan;
}
}
const Mobil_Wuling = new Mobil("Wuling Confero S", 185);
console.log(Mobil_Wuling.name);
console.log(Mobil_Wuling.max_kecepatan);
console.log(Mobil_Wuling.tambahKecepatan(185));
console.log(Mobil_Wuling.kurangiKecepatan(50));
Konsep Lanjutan Pemrograman Berorientasi Objek
Inheritance
Visualisasi Inheritance |
Inheritance (Pewarisan) adalah mekanisme di mana suatu class
dapat mewarisi properti dan method dari class lain. Class yang mewarisi
properti dan method dari class lain disebut subclass (class turunan), sedangkan class yang diwarisi disebut superclass atau
parent class (class induk).
// Parent class (superclass)
class Animal {
constructor(name, age) {
this.name = name;
this.age = age;
}
eat(food) {
console.log(`${this.name} is eating ${food}.`);
}
sleep(hours) {
console.log(`${this.name} is sleeping for ${hours} hours.`);
}
}
// Subclass 1
class Bird extends Animal {
constructor(name, age, species) {
super(name, age);
this.species = species;
}
fly(distance) {
console.log(`${this.name} has flown a distance of ${distance} meters`);
}
}
// Subclass 2
class Cat extends Animal {
constructor(name, age, color) {
super(name, age);
this.color = color;
}
walk(distance) {
console.log(`${this.name} has walked a distance of ${distance} meters`);
}
meow() {
console.log(`${this.name} is meowing.`);
}
}
const myBird = new Bird("Kenari", 3, "canary");
const myCat = new Cat("Oren", 2, "orange");
myBird.fly(200);
myCat.meow();
myCat.walk(3141592653589);
Berikut penjelasan mengenai kata kunci konsep Inheritance di Javascript:
- extends : Digunakan untuk membuat subclass dari superclass.
- super : Digunakan dalam method constructor subclass yang berfungsi mengambil property dan method dari superclass.
- this : Dalam konteks Inheritance, this digunakan untuk mengakses properti dan method dari superclass maupun subclass.
Polymorphism
Visualisasi Polymorphism |
Polymorphism adalah kemampuan yang memungkinkan objek untuk
menunjukkan perilaku yang berbeda tergantung pada konteksnya. Hal ini
sering terjadi dalam hubungan Inheritance, di mana class turunan
(subclass) mewarisi method dengan nama yang sama dari class
induknya (superclass), tetapi perilaku method tersebut dapat
diubah sesuai dengan kebutuhan dalam implementasi class turunannya.
class Shape {
constructor(name) {
this.name = name;
}
// Base Method
getArea() {
console.log("Area calculation not implemented for base Shape class!");
}
}
class Square extends Shape {
constructor(name, side) {
super(name);
this.side = side;
}
// Override method
getArea() {
return this.side * this.side;
}
}
class Circle extends Shape {
constructor(name, radius) {
super(name);
this.radius = radius;
}
// Override method
getArea() {
return Math.PI * this.radius * this.radius;
}
}
function calculateArea(shape) {
console.log(shape.getArea());
}
let mySquare = new Square("Square", 5);
let myCircle = new Circle("Circle", 3);
calculateArea(mySquare);
calculateArea(myCircle);
Encapsulation
Visualisasi Encapsulation |
Encapsulation adalah konsep dalam OOP yang berfungsi
menyembunyikan detail implementasi internal suatu class. Ini artinya
pengguna class (programmer lain) tidak perlu tahu cara data disimpan di
dalamnya. Interaksi dengan data di dalam class dapat dilakukan melalui
method yang bersifat public yang telah dirancang dengan baik,
seperti setter untuk merubah data dan getter untuk
mengambil data. Hal ini bertujuan untuk mencegah manipulasi langsung
terhadap data sensitif.
Konsep utama dalam Encapsulation adalah Access
Modifier yakni konsep untuk menentukan hak akses terhadap data
atau method di dalam class. Terdapat tiga jenis access modifier yakni:
- Public : Data bisa diakses dari dalam class maupun luar class.
- Private : Data hanya bisa diakses dari dalam class tersebut.
- Protected : Data hanya bisa diakses dari dalam class tersebut dan class turunannya (sub-class).
Javascript tidak sepenuhnya mendukung konsep Access Modifier. Secara
default, semua data dalam class secara otomatis memiliki access modifier
public dan untuk membuatnya private atau
protected menggunakan tanda `_` tetapi ini hanya
kebiasaan yang disepakati beberapa programmer. Namun pada
Javascript versi ES2022, fitur access modifier
private atau bisa digunakan dengan menambahkan
tanda `#` pada property atau method.
class BankAccount {
#accountID; // Private Property
#ownerName; // Private Property
_balance; // Protected Property
constructor(ownerName) {
this.#accountID = crypto.randomUUID();
this.#ownerName = ownerName;
this._balance = 0;
}
getAccountID() {
return this.#accountID;
}
getOwnerName() {
return this.#ownerName;
}
getBalance() {
return this._balance;
}
setOwnerName(newOwnerName) {
this.#ownerName = newOwnerName;
}
deposit(amount) {
this._balance += amount;
console.log(`Deposit of $${amount} successful. New balance: $${this._balance}`);
}
withdraw(amount) {
if (amount > this._balance) {
console.log("Insufficient funds.");
} else {
this._balance -= amount;
console.log(`Withdrawal of $${amount} successful. New balance: $${this._balance}`);
}
}
}
class SavingsAccount extends BankAccount {
#interestRate; // Private Property
constructor(ownerName, interestRate) {
super(ownerName);
this.#interestRate = interestRate;
}
#calculateInterest() { // Private Method
const interest = this._balance * this.#interestRate;
return interest;
}
addMonthlyInterest() {
const earnedInterest = this.#calculateInterest();
this._balance += earnedInterest;
console.log(`New balance after adding interest: $${this._balance}`);
}
getBalance() {
return this._balance + this.#calculateInterest();
}
}
// Usage example
// Bank Account
const JohnSmith_BankAccount = new BankAccount("John Smith");
JohnSmith_BankAccount.deposit(1250);
JohnSmith_BankAccount.withdraw(500);
console.log("Account ID:", JohnSmith_BankAccount.getAccountID());
console.log("Current Balance:", JohnSmith_BankAccount.getBalance());
// Savings Account
const Sucipto_SavingsAccount = new SavingsAccount("Sucipto", 0.03);
Sucipto_SavingsAccount.deposit(6000);
Sucipto_SavingsAccount.addMonthlyInterest();
console.log("Account ID:", Sucipto_SavingsAccount.getAccountID());
console.log("Current Balance:", Sucipto_SavingsAccount.getBalance());
// Set New Name
const Maulana_SavingsAccount = new SavingsAccount("Maulana", 0.07);
console.log("Original Owner Name:", Maulana_SavingsAccount.getOwnerName());
Maulana_SavingsAccount.setOwnerName("Prof. Maulana S.Kom");
console.log("Updated Owner Name:", Maulana_SavingsAccount.getOwnerName());
Typescript, bahasa pemrograman turunan Javascript, secara native
mendukung konsep OOP seperti access modifier. Kode Javascript di atas
dapat ditulis ulang dengan Typescript sebagai berikut:
class BankAccount {
private accountID: string;
private ownerName: string;
protected balance: number;
constructor(ownerName: string) {
this.accountID = crypto.randomUUID();
this.ownerName = ownerName;
this.balance = 0;
}
getAccountID(): string {
return this.accountID;
}
getOwnerName(): string {
return this.ownerName;
}
getBalance(): number {
return this.balance;
}
setOwnerName(newOwnerName: string): void {
this.ownerName = newOwnerName;
}
deposit(amount: number): void {
this.balance += amount;
console.log(`Deposit of $${amount} successful. New balance: $${this.balance}`);
}
withdraw(amount: number): void {
if (amount > this.balance) {
console.log("Insufficient funds.");
} else {
this.balance -= amount;
console.log(`Withdrawal of $${amount} successful. New balance: $${this.balance}`);
}
}
}
class SavingsAccount extends BankAccount {
private interestRate: number;
constructor(ownerName: string, interestRate: number) {
super(ownerName);
this.interestRate = interestRate;
}
private calculateInterest(): number {
const interest = this.balance * this.interestRate;
return interest;
}
addMonthlyInterest(): void {
const earnedInterest = this.calculateInterest();
this.balance += earnedInterest;
console.log(`New balance after adding interest: $${this.balance}`);
}
getBalance(): number {
return this.balance + this.calculateInterest();
}
}
// Usage example
// Bank Account
const JohnSmith_BankAccount = new BankAccount("John Smith");
JohnSmith_BankAccount.deposit(1250);
JohnSmith_BankAccount.withdraw(500);
console.log("Account ID:", JohnSmith_BankAccount.getAccountID());
console.log("Current Balance:", JohnSmith_BankAccount.getBalance());
// Savings Account
const Sucipto_SavingsAccount = new SavingsAccount("Sucipto", 0.03);
Sucipto_SavingsAccount.deposit(6000);
Sucipto_SavingsAccount.addMonthlyInterest();
console.log("Account ID:", Sucipto_SavingsAccount.getAccountID());
console.log("Current Balance:", Sucipto_SavingsAccount.getBalance());
// Set New Name
const Maulana_SavingsAccount = new SavingsAccount("Maulana", 0.07);
console.log("Original Owner Name:", Maulana_SavingsAccount.getOwnerName());
Maulana_SavingsAccount.setOwnerName("Prof. Maulana S.Kom");
console.log("Updated Owner Name:", Maulana_SavingsAccount.getOwnerName());
Interface
Interface adalah deklarasi kumpulan method yang harus
diimplementasikan oleh class. Interface tidak menyediakan implementasi
method, melainkan hanya mendefinisikan "kontrak" yang harus dipatuhi
oleh class yang mengimplementasikannya. Hal yang dideklarasikan dalam
Interface meliputi nama dan tipe data yang dikembalikan (return) dari
method tersebut.
Javascript tidak mendukung fitur Interface. Namun, hal ini bisa
digantikan dengan Typescript. Keyword implement digunakan
untuk mendeklarasikan bahwa suatu class mengimplementasikan interface
tertentu.
interface IArticle {
// Property
title: string;
author: string;
content: string;
// Methods
getWordCount(): number;
getSummary(): string;
printArticle(): string;
}
class Article implements IArticle {
public title: string;
public author: string;
public content: string;
constructor(title: string, author: string, content: string) {
this.title = title;
this.author = author;
this.content = content;
}
getWordCount(): number {
return this.content.split(" ").length;
}
getSummary(): string {
const summaryLength = 100;
return this.content.substring(0, summaryLength) + "...";
}
printArticle(): string {
return `${this.title}\nBy: ${this.author}\n\n${this.content}`;
}
}
// Usage
let myArticle = new Article(
"Cara Kolaborasi di Github",
"John Smith",
`Pertama, Fork dan clone repository. Kedua, Buat clone repository. Ketiga, Buat branch baru.
Keempat, Lakukan perubahan. Kelima, Commit dan push. Keenam, Buat pull request.
Ketujuh, Tunggu review. Kedelapan, Merge.`,
);
console.log(myArticle.getWordCount());
console.log(myArticle.getSummary());
console.log(myArticle.printArticle());
Kelebihan dan Kekurangan Pemrograman Berorientasi Objek di JavaScript
Kelebihan
1. Reusability
Konsep seperti inheritance dan polymorphism membuat kode yang ditulis
dalam class dapat digunakan kembali di class turunannya sehingga
mengurangi duplikasi kode.
2. Modularity
OOP membantu memecah kode menjadi class-class yang lebih kecil dan
terisolasi. Hal ini membuat kode lebih terstruktur, mudah dipahami, dan
dikelola.
3. Scalability
OOP memungkinkan pengembangan aplikasi yang scalable karena kemampuannya
dalam mengorganisasi dan mengelola kode dengan baik, sehingga
mempermudah penambahan fitur dan modifikasi di masa mendatang.
Kekurangan
1. Kurangnya Fitur OOP
Javascript bukanlah bahasa pemrogramman murni berorientasi object
seperti Java. Fitur OOP seperti access modifier dan interface tidak
didukung secara native.
2. Kompleksitas Kode
Implementasi OOP dalam JavaScript dapat meningkatkan kompleksitas kode,
terutama bagi programmer yang tidak terbiasa dengan konsep OOP.
3. Overhead Performa
Mendefinisikan class dan object dalam JavaScript membutuhkan resource
tambahan dibandingkan dengan function tradisional. Hal ini berdampak
pada performa program, terutama pada perangkat dengan resource terbatas.
Kesimpulan
Pemrograman berorientasi objek (OOP) merupakan paradigma pemrograman
yang digunakan untuk membangun aplikasi yang kompleks dan terstruktur.
OOP menawarkan konsep seperti encapsulation, inheritance, polymorphism,
dan abstraction, yang dapat membantu programmer untuk menulis kode yang
lebih modular dan reusable. Namun perlu diperhatikan bahwa Javascript
bukanlah bahasa pemrogramman yang secara murni berorientasi object. Ada
beberapa fitur OOP yang tidak didukung dalam Javascript tetapi hal ini
bisa ditangani menggunakan library atau menggunakan bahasa pemrogramman
Typescript.
Apakah paradigma OOP harus digunakan dalam JavaScript? Jawabannya
tergantung pada kebutuhan dan kompleksitas projek yang sedang
dikerjakan. Untuk projek kecil dan sederhana, Procedural Programming
mungkin lebih cocok. Namun, untuk projek yang kompleks, OOP menawarkan
fitur bermanfaat yang dapat membantu programmer membangun projek yang
lebih maintainable.
0 Komentar