Masukkan Password
43 Metode Penggantian & Modifikasi Terproteksi
Di lecture ini ada 2 konsep utama yang sangat penting dalam inheritance TypeScript:
- Method overriding β child class mengganti implementasi method milik parent.
protectedaccess modifier β property/method bisa digunakan oleh parent dan child class, tetapi tidak bisa diakses sembarangan dari luar.
Saya jelaskan dari dasar supaya hubungan antara private, protected, inheritance, dan overriding benar-benar jelas.
1. Gambaran besar lecture ini
Sebelumnya kita punya inheritance seperti ini:
Person
ββββββββΌβββββββ
β β β
name gender dateOfBirth
β β
βββ calculateAge()
β
ββββββ΄ββββββ
β β
Employee Athlete
Employee dan Athlete mewarisi Person.
Misalnya:
class Person {
name: string;
gender: string;
dateOfBirth: string;
calculateAge() {
// logic menghitung umur
}
}
Kemudian:
class Employee extends Person {
salary: number;
getSalary() {
// logic salary
}
}
Karena Employee extends Person, maka Employee mendapatkan fitur dari Person.
Tetapi lecture ini bertanya:
Bagaimana kalau
Employeeingin punya cara sendiri untuk menghitung umur?
Nah, di sinilah kita masuk ke method overriding.
2. Apa itu Method Overriding?
Method overriding adalah ketika child class membuat method dengan nama yang sama dengan method yang sudah ada di parent class, tetapi dengan implementasi/logic yang berbeda.
Contoh sederhana:
class Person {
calculateAge() {
return 30;
}
}
class Employee extends Person {
calculateAge() {
return 35;
}
}
Perhatikan:
Person.calculateAge()
dan
Employee.calculateAge()
Namanya sama:
calculateAge()
Tetapi implementasinya berbeda.
Jadi:
Person
βββ calculateAge()
β
logic A
Employee extends Person
βββ calculateAge()
β
logic B
Employee meng-override calculateAge() milik Person.
3. Analogi sederhana Method Overriding
Bayangkan ada perusahaan.
Person punya aturan:
“Untuk menghitung umur, gunakan cara A.”
Kemudian Employee mengatakan:
“Saya tetap menggunakan konsep menghitung umur, tetapi khusus Employee saya ingin menggunakan cara B.”
Maka Employee tidak perlu membuat nama method baru seperti:
calculateEmployeeAge()
Cukup:
calculateAge()
Karena Employee sedang mengganti perilaku dari method parent.
4. Contoh dari lecture
Misalnya parent class:
class Person {
name: string;
dateOfBirth: string;
gender: string;
constructor(
name: string,
dateOfBirth: string,
gender: string
) {
this.name = name;
this.dateOfBirth = dateOfBirth;
this.gender = gender;
}
calculateAge() {
const currentYear = new Date().getFullYear();
const birthYear = new Date(this.dateOfBirth).getFullYear();
return currentYear - birthYear;
}
}
Di sini Person memiliki:
calculateAge()
yang menghitung:
tahun sekarang - tahun lahir
Misalnya:
2024 - 1991 = 33
5. Kemudian Employee melakukan overriding
Sekarang kita buat:
class Employee extends Person {
calculateAge() {
return 2024 - new Date(this.dateOfBirth).getFullYear();
}
}
Perhatikan bahwa kita membuat:
calculateAge()
lagi di Employee.
Ini bukan method baru yang benar-benar berbeda.
Ini adalah override dari:
Person.calculateAge()
6. Apa yang terjadi ketika object dibuat?
Misalnya:
const person = new Person(
"John",
"08/30/1991",
"Male"
);
Kemudian:
person.calculateAge();
Yang dipanggil adalah:
Person.calculateAge()
Karena object tersebut adalah instance dari Person.
Sekarang:
const employee = new Employee(
"John",
"08/30/1991",
"Male"
);
Lalu:
employee.calculateAge();
Yang dipanggil adalah:
Employee.calculateAge()
bukan:
Person.calculateAge()
karena Employee sudah meng-override method tersebut.
7. Cara mudah mengingat overriding
Bayangkan seperti ini:
Parent:
calculateAge()
β
"cara menghitung umur versi parent"
Child:
calculateAge()
β
"cara menghitung umur versi child"
Ketika kita memanggil:
employee.calculateAge();
TypeScript akan menggunakan versi yang dimiliki Employee.
Jadi:
Person object
β
Person.calculateAge()
Employee object
β
Employee.calculateAge()
8. Lalu apa hubungannya dengan private?
Nah, di sinilah bagian lecture yang sangat penting.
Di awal lecture, dateOfBirth diubah menjadi:
private dateOfBirth: string;
Misalnya:
class Person {
name: string;
gender: string;
private dateOfBirth: string;
constructor(
name: string,
dateOfBirth: string,
gender: string
) {
this.name = name;
this.dateOfBirth = dateOfBirth;
this.gender = gender;
}
}
Sekarang dateOfBirth adalah private.
Artinya:
dateOfBirthhanya boleh digunakan di dalam classPerson.
9. private bukan berarti “tidak bisa diwariskan”
Ini adalah salah satu bagian yang sering membingungkan pemula.
Ketika:
class Employee extends Person
kita memang mewarisi struktur/perilaku dari Person.
Tetapi member yang private tidak bisa diakses langsung oleh child class.
Misalnya:
class Person {
private dateOfBirth: string;
constructor(dateOfBirth: string) {
this.dateOfBirth = dateOfBirth;
}
}
Kemudian:
class Employee extends Person {
calculateAge() {
return new Date(this.dateOfBirth);
}
}
Ini error.
Kenapa?
Karena:
private dateOfBirth
hanya boleh diakses di:
Person
Bukan di:
Employee
Walaupun Employee adalah child dari Person.
10. Visualisasi private
Misalnya:
Person
βββββββββββββββββββββββββββββββ
β private dateOfBirth β
β β
β calculateAge() β
β β β
β boleh akses dateOfBirth β
βββββββββββββββββββββββββββββββ
β
β extends
β
βββββββββββββββββββββββββββββββ
β Employee β
β β
β β tidak boleh akses β
β dateOfBirth langsung β
βββββββββββββββββββββββββββββββ
Jadi private sangat ketat.
11. Lalu kita membutuhkan protected
Masalahnya sekarang:
Bagaimana kalau kita ingin
dateOfBirthtidak boleh diakses oleh sembarang code dari luar, tetapi tetap ingin child class sepertiEmployeebisa menggunakannya?
Jawabannya:
protected
Jadi:
private dateOfBirth: string;
diubah menjadi:
protected dateOfBirth: string;
12. Apa arti protected?
protected berarti:
Property atau method hanya bisa diakses dari class tersebut dan class turunannya (child classes).
Jadi:
Person
β
boleh akses protected
Employee extends Person
β
boleh akses protected
Athlete extends Person
β
boleh akses protected
kode dari luar
β
β tidak boleh akses protected
13. Perbedaan public, private, dan protected
Ini bagian yang wajib banget dipahami.
| Modifier | Di dalam class | Child class | Dari luar |
|---|---|---|---|
public | β | β | β |
protected | β | β | β |
private | β | β | β |
Cara mengingatnya:
public
Semua orang boleh akses.
Class
βββ Child
βββ Outside
β
β
private
Hanya class pemiliknya.
Person
β
β
Employee
β
β
Outside
β
β
protected
Class pemilik + child classes.
Person
β
β
Employee
β
β
Athlete
β
β
Outside
β
β
14. Kembali ke contoh dateOfBirth
Sekarang kita ubah:
private dateOfBirth: string;
menjadi:
protected dateOfBirth: string;
Sehingga:
class Person {
name: string;
gender: string;
protected dateOfBirth: string;
constructor(
name: string,
dateOfBirth: string,
gender: string
) {
this.name = name;
this.dateOfBirth = dateOfBirth;
this.gender = gender;
}
calculateAge() {
const currentYear = new Date().getFullYear();
const birthYear =
new Date(this.dateOfBirth).getFullYear();
return currentYear - birthYear;
}
}
Sekarang Employee bisa mengakses:
this.dateOfBirth
karena Employee adalah child class.
15. Employee bisa mengakses protected
Contohnya:
class Employee extends Person {
calculateAge() {
const birthYear =
new Date(this.dateOfBirth).getFullYear();
return 2024 - birthYear;
}
}
Ini sekarang valid.
Kenapa?
Karena:
dateOfBirth
adalah:
protected
dan Employee merupakan subclass dari Person.
16. Tetapi dari luar tetap tidak boleh
Walaupun Employee bisa mengaksesnya:
class Employee extends Person {
calculateAge() {
return new Date(this.dateOfBirth).getFullYear();
}
}
kode seperti ini tetap tidak boleh:
const employee = new Employee(...);
console.log(employee.dateOfBirth);
Karena dari luar class:
employee.dateOfBirth
β tidak boleh.
Jadi protected bukan berarti public.
17. Analogi protected yang mudah
Bayangkan sebuah rumah.
public
Seperti ruang tamu:
Siapa pun boleh masuk.
private
Seperti kamar pribadi:
Hanya pemilik rumah yang boleh masuk.
protected
Seperti ruang keluarga:
Pemilik rumah dan anggota keluarga boleh masuk, tetapi tamu umum tidak.
Kalau:
Person = orang tua
Employee = anak
maka property protected bisa digunakan oleh:
Person β
Employee β
tetapi bukan oleh:
orang dari luar β
18. Full contoh yang lebih lengkap
Mari kita gabungkan semuanya:
class Person {
name: string;
gender: string;
protected dateOfBirth: string;
constructor(
name: string,
dateOfBirth: string,
gender: string
) {
this.name = name;
this.dateOfBirth = dateOfBirth;
this.gender = gender;
}
calculateAge() {
const currentYear = new Date().getFullYear();
const birthYear =
new Date(this.dateOfBirth).getFullYear();
console.log("calculate age of person called");
return currentYear - birthYear;
}
}
Kemudian:
class Employee extends Person {
calculateAge() {
const birthYear =
new Date(this.dateOfBirth).getFullYear();
console.log("calculate age of employee called");
return 2024 - birthYear;
}
}
Sekarang:
const employee = new Employee(
"John",
"08/30/1991",
"Male"
);
console.log(employee.calculateAge());
Output:
calculate age of employee called
33
Kenapa "calculate age of employee called"?
Karena:
Employee
sudah meng-override:
Person.calculateAge()
19. Bagaimana membuktikan bahwa overriding benar-benar terjadi?
Lecture menggunakan:
console.log()
di kedua method.
Parent:
calculateAge() {
console.log("calculate age of person called");
// ...
}
Child:
calculateAge() {
console.log("calculate age of employee called");
// ...
}
Kemudian:
const employee = new Employee(...);
employee.calculateAge();
Output:
calculate age of employee called
Ini membuktikan bahwa method Employee yang digunakan.
20. Bagaimana kalau Employee tidak punya calculateAge()?
Misalnya kita hapus:
class Employee extends Person {
}
Kemudian:
const employee = new Employee(...);
employee.calculateAge();
Karena Employee tidak memiliki calculateAge() sendiri, TypeScript akan mencari ke parent:
Employee
β
tidak menemukan calculateAge()
β
Person
β
menemukan calculateAge()
β
gunakan Person.calculateAge()
Jadi inheritance bekerja seperti pencarian.
21. Cara berpikir method lookup
Misalnya:
employee.calculateAge()
JavaScript/TypeScript secara konsep akan mencari:
Apakah Employee punya calculateAge()?
β
βββ YES β gunakan Employee.calculateAge()
β
βββ NO
β
Apakah Person punya?
β
βββ YES β gunakan Person.calculateAge()
Ini membantu memahami kenapa overriding bekerja.
22. Apa bedanya overriding dengan membuat method baru?
Misalnya parent:
class Person {
calculateAge() {}
}
Kalau child:
class Employee extends Person {
calculateAge() {}
}
Ini:
overriding
Karena nama method sama.
Tetapi kalau:
class Employee extends Person {
calculateSalary() {}
}
Ini bukan overriding.
Ini adalah:
method baru milik Employee.
Jadi:
calculateAge()
β
sudah ada di parent
β
dibuat ulang di child
β
OVERRIDING
Sedangkan:
calculateSalary()
β
belum ada di parent
β
dibuat di child
β
METHOD BARU
23. Kenapa overriding berguna?
Bayangkan kita punya:
Person
βββ calculateAge()
Employee extends Person
βββ calculateAge()
Athlete extends Person
βββ calculateAge()
Semua orang punya konsep:
calculateAge()
Tetapi masing-masing bisa punya cara menghitung yang berbeda.
Misalnya:
Person
β cara standar
Employee
β cara khusus employee
Athlete
β cara khusus athlete
Kita tetap menggunakan nama:
calculateAge()
sehingga interface/perilakunya konsisten.
24. protected juga bisa digunakan pada method
Bukan hanya property.
Misalnya:
class Person {
protected getBirthYear() {
return new Date(this.dateOfBirth).getFullYear();
}
}
Kemudian child bisa menggunakan:
class Employee extends Person {
calculateAge() {
const year = this.getBirthYear();
return 2024 - year;
}
}
Tetapi dari luar:
employee.getBirthYear();
β tidak boleh.
Karena method tersebut:
protected
25. Kenapa tidak dibuat public saja?
Pertanyaan bagus.
Misalnya kita punya:
public dateOfBirth: string;
Maka dari luar orang bisa melakukan:
employee.dateOfBirth = "01/01/2000";
Artinya siapa pun bisa mengubahnya.
Kalau kita tidak ingin itu terjadi, tetapi masih ingin child class menggunakannya, kita bisa menggunakan:
protected dateOfBirth: string;
Jadi:
protected
β
Parent bisa akses
Child bisa akses
Outside tidak bisa akses
Ini memberikan kontrol akses yang lebih baik.
26. private vs protected adalah poin terpenting
Bayangkan:
class Person {
private privateData: string;
protected protectedData: string;
}
Child:
class Employee extends Person {
test() {
this.privateData; // β
this.protectedData; // β
}
}
Dari luar:
const employee = new Employee(...);
employee.privateData; // β
employee.protectedData; // β
Jadi:
Person Employee Outside
---------------------------------------------------
private β
β β
protected β
β
β
public β
β
β
27. Hubungan private, protected, dan inheritance
Sekarang kita bisa melihat kenapa ketiganya dibuat.
public
Digunakan ketika sesuatu memang merupakan bagian dari API yang ingin kita expose.
employee.getSalary();
Silakan dipanggil dari luar.
private
Digunakan untuk detail internal yang hanya diperlukan oleh class tersebut.
private calculateBonus();
Child bahkan tidak perlu tahu bagaimana detailnya.
protected
Digunakan ketika detail tersebut masih internal, tetapi child class perlu menggunakannya.
protected dateOfBirth;
Parent dan child boleh menggunakannya, tetapi pengguna object dari luar tidak.
28. Satu hal yang sering membuat pemula salah paham
Jangan berpikir:
“
protectedberarti hanya child yang bisa mengakses.”
Salah.
protected bisa diakses oleh:
- class tempat property tersebut didefinisikan
- child/subclass
Jadi:
class Person {
protected dateOfBirth: string;
calculateAge() {
this.dateOfBirth; // β
}
}
dan:
class Employee extends Person {
test() {
this.dateOfBirth; // β
}
}
Tetapi:
const employee = new Employee(...);
employee.dateOfBirth; // β
29. Hubungan antara extends dan protected
Ingat:
class Employee extends Person
extends membuat hubungan parent-child.
Karena Employee adalah child:
Person
β
β extends
β
Employee
Employee mendapatkan akses ke member protected dari Person.
Tanpa inheritance:
class Employee {
// tidak otomatis punya akses
// ke protected member Person
}
Karena Employee bukan child dari Person.
30. Tentang kode 2024
Di transcript, lecture menggunakan:
return 2024 - ...
Ini hanya untuk contoh pembelajaran.
Dalam aplikasi nyata, kita biasanya tidak ingin hard-code:
2024
karena tahun akan berubah.
Lebih baik:
const currentYear = new Date().getFullYear();
sehingga pada 2026 otomatis mendapatkan:
2026
dan tahun berikutnya akan berubah otomatis.
Jadi konsep lecture-nya adalah overriding, bukan bahwa kita harus menghitung umur menggunakan angka 2024.
31. Satu detail penting tentang Date
Lecture juga menunjukkan bahwa format tanggal harus benar.
Misalnya:
new Date("08/30/1991")
digunakan untuk mendapatkan tanggal.
Kemudian:
.getFullYear()
mengambil tahun:
1991
Sehingga:
const birthYear =
new Date(this.dateOfBirth).getFullYear();
hasilnya:
1991
Lalu:
2024 - 1991
hasil:
33
Catatan kecil: format tanggal string seperti "08/30/1991" bisa bergantung pada lingkungan dan mudah ambigu. Untuk aplikasi nyata, format ISO seperti "1991-08-30" biasanya lebih aman.
32. Gambaran keseluruhan kode
Kalau digabung, kira-kira seperti ini:
class Person {
name: string;
gender: string;
protected dateOfBirth: string;
constructor(
name: string,
dateOfBirth: string,
gender: string
) {
this.name = name;
this.dateOfBirth = dateOfBirth;
this.gender = gender;
}
calculateAge() {
const currentYear = new Date().getFullYear();
const birthYear =
new Date(this.dateOfBirth).getFullYear();
console.log("calculate age of person called");
return currentYear - birthYear;
}
}
class Employee extends Person {
calculateAge() {
const currentYear = new Date().getFullYear();
const birthYear =
new Date(this.dateOfBirth).getFullYear();
console.log("calculate age of employee called");
return currentYear - birthYear;
}
}
Kemudian:
const person = new Person(
"John",
"1991-08-30",
"Male"
);
const employee = new Employee(
"Mary",
"1995-05-10",
"Female"
);
Kalau:
person.calculateAge();
yang dipanggil:
Person.calculateAge()
Sedangkan:
employee.calculateAge();
yang dipanggil:
Employee.calculateAge()
karena Employee melakukan overriding.
33. Mental model paling sederhana
Coba hafalkan tiga konsep ini:
private
“Cuma class saya yang boleh pakai.”
Person β
Employee β
Outside β
protected
“Saya dan anak-anak saya boleh pakai.”
Person β
Employee β
Outside β
public
“Semua boleh pakai.”
Person β
Employee β
Outside β
Kemudian:
overriding
“Parent punya method ini, tapi child ingin mengganti cara kerjanya.”
Person
calculateAge()
β
β override
β
Employee
calculateAge()
34. Ringkasan lecture
Jadi sebenarnya lecture ini mengajarkan hubungan yang sangat erat antara inheritance + access modifier + overriding.
Person
β
βββββββββββββββΌββββββββββββββ
β β β
public protected private
β β β
β β β
bisa diakses parent + hanya Person
dari mana saja child
β
β
Employee
β
β
bisa menggunakan
protected member
Dan untuk method:
Person
βββ calculateAge()
β
β override
β
Employee
βββ calculateAge()
Ketika:
new Employee().calculateAge();
yang digunakan adalah versi Employee.
π§ Inti yang harus kamu bawa ke lecture berikutnya
Kalau kamu hanya mengingat 4 kalimat, ingat ini:
- Inheritance β child mewarisi fitur dari parent.
- Overriding β child mengganti implementasi method parent dengan method bernama sama.
privateβ hanya bisa digunakan di class tempat dia didefinisikan.protectedβ bisa digunakan di class tersebut dan child classes, tetapi tidak dari luar.
Dan perbedaan aksesnya:
Parent Child Outside
public β
β
β
protected β
β
β
private β
β β
Jadi kalau muncul pertanyaan βKenapa Employee tidak bisa mengakses dateOfBirth ketika dateOfBirth private, tetapi bisa ketika protected?β, jawabannya adalah:
Karena
privatemembatasi akses hanya ke class pemiliknya (Person), sedangkanprotectedmemperluas akses ke class pemilik dan seluruh child class-nya, sepertiEmployee.