Class RekeningBank dan AkunBank kita berdiri sendiri: satu class, satu berkas, satu tanggung jawab. Begitu domain data membesar, pola itu berubah menjadi duplikasi — Persegi, Lingkaran, dan Segitiga sama-sama punya nama, warna, dan method luas(), dan menulis ulang ketiganya di tiga berkas berarti setiap perbaikan harus ditempel tiga kali. Inheritance menjawabnya: satu class induk (superclass) menyimpan anggota bersama, class anak (subclass) mewarisi anggota itu lalu menambah atau mendefinisikan ulang bagian miliknya. Chapter ini membangun hierarki Bentuk → Persegi/Lingkaran dari nol sambil menguji tiga hal: pemanggilan constructor induk, override, dan penyerahan akses protected di sepanjang rantai. Cakupannya:
classdef Anak < Indukdan hubungan is-a- constructor subclass dengan
obj@Induk(...) - override method dan memanggil versi superclass
metode@Induk(obj) - nasib
privatevsprotecteddi rantai inheritance
Hierarki dengan < Induk #
Aturannya: baris classdef Anak < Induk menyatakan bahwa Anak mewarisi seluruh properties dan methods non-private milik Induk. Mekanisme di balik layar: setiap object Persegi dibangun berlapis — MATLAB menyusun bagian Bentuk (berisi nama, warna) lebih dulu, lalu menambahkan bagian Persegi (berisi sisi); satu object, dua lapis. Karena itu setiap Persegi adalah Bentuk — relasi is-a — dan boleh dipakai di mana pun kode meminta Bentuk (modal untuk chapter Polymorphism).
Superclass kita sengaja minimal. Berkas Bentuk.m:
classdef Bentuk
%BENTUK Superclass: induk bersama untuk hierarki bangun datar.
% Bentuk menyimpan identitas umum (nama, warna) dan method
% luas()/deskripsi() sebagai perilaku bawaan yang bisa dioverride.
properties (SetAccess = protected)
nama
warna
end
methods
function obj = Bentuk(nama, warna)
% Constructor superclass: warna berdefault 'hitam'.
if nargin < 2
warna = 'hitam';
end
obj.nama = nama;
obj.warna = warna;
end
function l = luas(obj)
% Superclass tidak tahu rumus apa pun: kembalikan 0.
l = 0;
end
function deskripsi(obj)
% Perilaku bawaan; subclass boleh mendefinisikan ulang.
fprintf('Bentuk generik bernama %s\n', obj.nama);
end
end
endStruktur hierarkinya tergambar di diagram berikut:
Diagram tersebut dibaca dari atas ke bawah: Persegi dan Lingkaran masing-masing menambahkan satu property dan mendefinisikan ulang sebagian perilaku warisan; segala hal yang tidak mereka sentuh — nama, warna, deskripsi() — tetap datang dari Bentuk.
Constructor Subclass: obj@Induk(...) #
Constructor tidak diwarisi secara otomatis. Method Bentuk() butuh argumen nama, sehingga constructor Persegi wajib memanggilnya secara eksplisit dengan sintaks obj@Bentuk(argumen). Berkas Persegi.m:
classdef Persegi < Bentuk
%PERSEGI Subclass dari Bentuk: mewarisi nama & warna, menambah
% properti sisi, lalu meng-override luas() dan deskripsi().
properties
sisi
end
methods
function obj = Persegi(sisi)
obj@Bentuk('Persegi', 'merah'); % inisialisasi bagian superclass
obj.sisi = sisi;
end
function l = luas(obj)
l = obj.sisi^2; % override: rumus persegi
end
function deskripsi(obj)
deskripsi@Bentuk(obj); % panggil versi superclass dulu
fprintf(' sisi = %g, luas = %g\n', obj.sisi, obj.luas());
end
function obj = catatWarna(obj, warnaBaru)
% Menulis properti protected milik superclass: boleh dari subclass.
obj.warna = warnaBaru;
end
end
endMari kita bedah baris-baris kode di atas:
- Baris 1 (
classdef Persegi < Bentuk): mendeklarasikanPersegisebagai subclass — sejak sini seluruh anggota non-privateBentukmelekat padaPersegi. - Baris 5-7 (
properties ... sisi): property baru milik subclass;namadanwarnatidak perlu dideklarasikan ulang karena sudah diwarisi. - Baris 10-13 (
function obj = Persegi(sisi)): barisobj@Bentuk('Persegi', 'merah')menjalankan constructor superclass untuk mengisi lapisBentuksebelum lapisPersegimenambahkansisi. - Baris 15-17 (
luas): override — definisi ulang method warisan (bedah di bawah). - Baris 24-27 (
catatWarna): method subclass yang menulisobj.warna— sah karenawarnaber-SetAccess = protecteddan penulis berada di dalam subclass (pembuktian di bagian akhir).
Bagian pertama uji_inheritance.m membuktikan bahwa anggota warisan benar-benar hadir pada object subclass:
p = Persegi(4);
l = Lingkaran(7);
fprintf('p.nama : %s (diwarisi dari Bentuk)\n', p.nama);
fprintf('p.warna : %s (diisi constructor superclass)\n', p.warna);
fprintf('class(p) : %s\n', class(p));
fprintf('isa(p, ''Bentuk'') : %d\n', isa(p, 'Bentuk'));Output yang Dihasilkan:
p.nama : Persegi (diwarisi dari Bentuk)
p.warna : merah (diisi constructor superclass)
class(p) : Persegi
isa(p, 'Bentuk') : 1Override: Mendefinisikan Ulang Method Warisan #
Aturan override: subclass cukup mendefinisikan method bernama sama dengan method warisan — tanpa kata kunci tambahan. Mekanismenya: saat pemanggil menulis p.luas(), MATLAB membaca class dinamis object (Persegi), mencari luas mulai dari class itu, dan menemukan versi Persegi lebih dulu; versi Bentuk hanya terpakai untuk object yang class dinamisnya memang Bentuk. Kelas Lingkaran melakukan hal yang sama dengan rumus berbeda (berkas Lingkaran.m):
classdef Lingkaran < Bentuk
%LINGKARAN Subclass dari Bentuk: menambah jari-jari dan
% meng-override luas(); deskripsi() diwarisi apa adanya.
properties
jari
end
methods
function obj = Lingkaran(jari)
obj@Bentuk('Lingkaran', 'biru');
obj.jari = jari;
end
function l = luas(obj)
l = pi * obj.jari^2; % override: rumus lingkaran
end
end
endSatu nama method, tiga hasil — sesuai class yang memanggil:
fprintf('luas Persegi(4) : %g\n', p.luas());
fprintf('luas Lingkaran(7) : %g\n', l.luas());
b = Bentuk('Awan');
fprintf('luas Bentuk : %g (versi superclass)\n', b.luas());Output yang Dihasilkan:
luas Persegi(4) : 16
luas Lingkaran(7) : 153.938
luas Bentuk : 0 (versi superclass)Kadang subclass ingin memperluas perilaku induk, bukan menggantinya. Sintaks metode@Induk(obj) memanggil versi superclass dari dalam method yang dioverride — deskripsi() milik Persegi memakainya di baris deskripsi@Bentuk(obj);:
p.deskripsi(); % versi Persegi, yang membuka dengan versi Bentuk
l.deskripsi(); % tidak dioverride: versi Bentuk yang diwarisiOutput yang Dihasilkan:
Bentuk generik bernama Persegi
sisi = 4, luas = 16
Bentuk generik bernama LingkaranBaris pertama lahir dari deskripsi@Bentuk(obj) di dalam override; baris kedua menegaskan bahwa Lingkaran — yang tidak mendefinisikan deskripsi — tetap menjalankan versi warisan.
protected Sepanjang Rantai Inheritance #
Chapter Access Control menjanjikan bahwa protected menjadi kunci inheritance; inilah pembuktiannya. Property nama dan warna di Bentuk beratribut SetAccess = protected: kode luar ditolak interpreter, sedangkan catatWarna() milik Persegi — yang berada satu rantai inheritance — lolos menulis:
try
p.nama = 'Segitiga';
catch
fprintf('p.nama = ... dari luar : DITOLAK (SetAccess protected)\n');
end
p = p.catatWarna('hijau');
fprintf('catatWarna(''hijau'') : p.warna kini %s\n', p.warna);Output yang Dihasilkan:
p.nama = ... dari luar : DITOLAK (SetAccess protected)
catatWarna('hijau') : p.warna kini hijauRangkuman nasib setiap level akses di rantai inheritance:
| Akses anggota di superclass | Dilihat subclass | Ditulis/dipanggil subclass | Kode luar |
|---|---|---|---|
public (default) | ya | ya | ya |
protected | ya | ya | tidak |
private | tidak | tidak | tidak |
Ringkasan #
Inheritance menyusun object berlapis: classdef Anak < Induk mewarisi seluruh anggota non-private, constructor superclass dipanggil eksplisit dengan obj@Induk(...), dan method warisan bisa didefinisikan ulang di subclass tanpa kata kunci tambahan — sementara metode@Induk(obj) mengambil versi lama dari dalam override. Akses protected menjadi jembatan yang tepat: tertutup bagi kode luar, terbuka bagi sepanjang rantai subclass, dan private memutus rantai sama sekali. Relasi is-a yang terbangun (isa(p, 'Bentuk') bernilai 1) menjadi fondasi chapter berikutnya, Polymorphism, tempat kumpulan object campuran memanggil satu method dan mendapat perilaku yang berbeda-beda. Berkas Bentuk.m, Persegi.m, Lingkaran.m, dan uji_inheritance.m di bagian bawah halaman memuat seluruh hierarki yang sudah teruji.