Seluruh class yang kita buat sejauh ini — Titik, RekeningBank, AkunBank — adalah value class: assignment menyalin, method pengubah wajib mengembalikan obj, dan perubahan yang tidak ditampung hilang diam-diam. MATLAB punya satu keluarga lagi dengan aturan main yang berbeda: handle class, yang assignment-nya membagi satu objek ke banyak nama. Pilihan keluarga ini bukan detail teknis kecil — memilih keluarga yang salah membuat kode dipenuhi r = r.setor(...) yang sebenarnya tidak perlu, atau sebaliknya membuat dua bagian program saling menginjak state yang sama tanpa sengaja. Chapter ini membedah kedua semantik sampai ke perilaku dasarnya. Cakupannya:
- semantik value: assignment menyalin, method wajib mengembalikan
obj - semantik handle:
classdef Nama < handle, assignment membagi referensi - copy-on-write — mengapa value class tidak se-mahal yang terlihat
- kapan memilih value (data sederhana) dan kapan handle (state yang dibagi)
Dua Semantik untuk Satu classdef #
Aturannya: class yang dideklarasikan polos (classdef TitikValue) mengikuti semantik value, sedangkan class yang mewarisi class bawaan handle (classdef TitikHandle < handle) mengikuti semantik handle. Mekanisme di balik layar: variabel value class menyimpan isi objek secara langsung, sehingga assignment membawa salinan; variabel handle class menyimpan referensi tak langsung — dokumentasi MATLAB menyebutnya “a handle is an object that indirectly references its data”. Tabel berikut merangkum seluruh perbedaan perilakunya:
| Aspek | Value class | Handle class |
|---|---|---|
| Deklarasi | classdef TitikValue | classdef TitikHandle < handle |
b = a | b menerima salinan penuh | b menunjuk objek yang sama |
Ubah b.x | a tidak berubah | a ikut berubah |
| Method pengubah | obj = metode(obj) + assignment | cukup metode(obj) |
| Dikirim ke fungsi | fungsi menerima salinan | fungsi menerima referensi |
| Contoh MATLAB | double, struct, class data seperti RekeningBank | graphics object, containers.Map |
Value Class: Assignment Menyalin #
Kita mulai dari class polos yang menyimpan koordinat titik. Berkas TitikValue.m:
classdef TitikValue
%TITIKVALUE Value class: titik 2D dengan semantik menyalin.
% t = TitikValue(x, y) membuat titik; setiap assignment menyalin
% seluruh isi objek sehingga dua variabel berdiri independen.
properties
x
y
end
methods
function obj = TitikValue(x, y)
% Constructor: koordinat y berdefault 0.
if nargin < 2
y = 0;
end
obj.x = x;
obj.y = y;
end
function obj = geser(obj, dx, dy)
% Value class: perubahan hanya melekat bila obj dikembalikan.
obj.x = obj.x + dx;
obj.y = obj.y + dy;
end
end
endUji paling telanjang dari semantik value adalah assignment diikuti modifikasi (bagian awal uji_semantik.m):
a = TitikValue(1, 2);
b = a; % b menerima salinan penuh dari a
b.x = 99; % ubah isi b saja
fprintf('VALUE : a.x = %g, b.x = %g\n', a.x, b.x);Output yang Dihasilkan:
VALUE : a.x = 1, b.x = 99Variabel a tetap memegang nilai 1 meskipun b.x sudah ditimpa 99. Konsekuensinya: method pengubah pada value class wajib mengembalikan obj, dan pemanggil wajib menampungnya kembali:
c = TitikValue(1, 2);
c.geser(10, 10); % tanpa menampung hasil: perubahan hilang
fprintf('VALUE : c.x setelah geser tanpa assignment = %g\n', c.x);
c = c.geser(10, 10); % cara yang benar: tampung kembali objeknya
fprintf('VALUE : c.x setelah c = c.geser(...) = %g\n', c.x);Output yang Dihasilkan:
VALUE : c.x setelah geser tanpa assignment = 1
VALUE : c.x setelah c = c.geser(...) = 11Mari kita bedah baris-baris kode di atas:
- Baris 1 (
classdef TitikValue): tanpa< handle, MATLAB membentuk class ini sebagai value class — aturan menyalin berlaku otomatis. - Baris 12-19 (
function obj = TitikValue(x, y)): constructor standar dengan defaulty = 0lewatnargin. - Baris 21-25 (
function obj = geser(obj, dx, dy)): kepala method menyatakan outputobj. MATLAB mengeksekusi method pada salinan, lalu mengembalikan salinan yang sudah digeser; tanpa assignment hasilnya dibuang. - Baris 2 dan 4 (
c.geser(...)vsc = c.geser(...)): hanya pemanggilan kedua yang menyimpan hasil.
Handle Class: Assignment Membagi Referensi #
Mengubah satu kata pada deklarasi membalik seluruh semantik. Berkas TitikHandle.m menyimpan titik yang sama, tetapi mewarisi handle:
classdef TitikHandle < handle
%TITIKHANDLE Handle class: titik 2D dengan semantik referensi.
% p = TitikHandle(x, y) membuat SATU objek; assignment q = p membuat
% q menunjuk objek yang sama sehingga perubahan lewat salah satunya
% terlihat oleh keduanya.
properties
x
y
end
methods
function obj = TitikHandle(x, y)
% Constructor: koordinat y berdefault 0.
if nargin < 2
y = 0;
end
obj.x = x;
obj.y = y;
end
function geser(obj, dx, dy)
% Handle class: perubahan langsung melekat pada objek asli.
obj.x = obj.x + dx;
obj.y = obj.y + dy;
end
end
endUji yang sama kini menghasilkan cerita yang berbeda:
p = TitikHandle(1, 2);
q = p; % q menunjuk objek yang sama dengan p
q.x = 99; % ubah lewat q ...
fprintf('HANDLE : p.x = %g, q.x = %g\n', p.x, q.x);
p.geser(10, 10); % tanpa assignment pun perubahan melekat
fprintf('HANDLE : p.x = %g, q.x = %g\n', p.x, q.x);Output yang Dihasilkan:
HANDLE : p.x = 99, q.x = 99
HANDLE : p.x = 109, q.x = 109Mari kita bedah baris-baris kode di atas:
- Baris 1 (
classdef TitikHandle < handle): mewarisi class bawaanhandle— sejak baris ini, assignment membagi referensi, bukan menyalin isi. - Baris 22-26 (
function geser(obj, dx, dy)): tidak ada variabel output — method mengubah objek asli secara langsung. Dokumentasi MATLAB menyebut pola ini: “the property set method does not return the object passed to the method, as is required by a value class”.
Dua nama untuk satu objek tergambar langsung di diagram berikut:
Diagram kiri menunjukkan dua kotak terpisah — memodifikasi salah satunya tidak menyentuh yang lain; diagram kanan menunjukkan dua panah menuju satu kotak yang sama.
Objek Lewat Fungsi: Salinan vs Referensi #
Semantik yang sama berlaku ketika objek dikirim sebagai argumen fungsi — function workspace (chapter Scope dan Workspace) menerima salinan value object, tetapi hanya pointer tak langsung untuk handle object. Berkas modifikasiDalam.m mengubah kedua argumennya di dalam function workspace:
function modifikasiDalam(v, h)
% modifikasiDalam Menerima satu value object dan satu handle object.
% Fungsi ini mengubah kedua argumen di dalam function workspace:
% perubahan pada v berhenti di salinan, perubahan pada h mengenai
% objek asli milik pemanggil.
v.x = 500;
h.x = 500;
endPemanggilnya di bagian akhir uji_semantik.m membuktikan arah masing-masing:
v = TitikValue(7, 8);
h = TitikHandle(7, 8);
modifikasiDalam(v, h); % keduanya diubah DI DALAM fungsi
fprintf('VALUE : v.x setelah fungsi = %g (tidak ikut berubah)\n', v.x);
fprintf('HANDLE : h.x setelah fungsi = %g (ikut berubah)\n', h.x);Output yang Dihasilkan:
VALUE : v.x setelah fungsi = 7 (tidak ikut berubah)
HANDLE : h.x setelah fungsi = 500 (ikut berubah)Handle class juga mewarisi method bawaan dari handle: isvalid() memeriksa apakah referensi masih hidup, delete() menghancurkan objek, copy() membuat salinan independen, dan == membandingkan identitas dua nama (bukan isi). Method bawaan ini tidak tersedia di GNU Octave 10, sehingga uji_semantik.m sengaja tidak memakainya.
Kapan Memilih Value atau Handle #
Pertanyaan pemilihnya satu kalimat: apakah dua salinan identik boleh dianggap dua objek berbeda? Titik koordinat, matriks, dan data sensor boleh disalin tanpa berubah makna — value class pas dan aman dikirim ke fungsi mana pun. Objek dengan identitas — koneksi, plot di figure, GUI, keranjang belanja bersama — memakai handle class agar semua pemegang melihat state yang sama.
| Kebutuhan | Keluarga yang tepat | Alasan |
|---|---|---|
| Data hitung-hitungan (titik, matriks, hasil pengukuran) | value | penyalinan aman, tidak ada efek samping |
| Objek GUI, plot, koneksi | handle | satu sumber state untuk banyak pengguna |
Method berantai obj.a().b() | handle | pemanggilan tanpa assignment tetap melekat |
| Data yang dikirim ke banyak fungsi pembantu | value | fungsi tidak bisa merusak data pemanggil |
| Objek dengan siklus hidup (open/close, connect) | handle | identitas objek penting, bisa di-delete() |
Dalam satu proyek kedua keluarga biasanya hadir bersama: model data sebagai value class, sementara komponen yang mengelola model (GUI, logger, koneksi) sebagai handle class yang memiliki value object tersebut lewat property — pola komposisi yang kita bahas tuntas di chapter Merancang Class.
Ringkasan #
Value class menyalin pada assignment dan pada pengiriman ke fungsi, sehingga method pengubah wajib mengembalikan obj dan pemanggil wajib menampungnya; handle class (< handle) membagi satu referensi ke banyak nama, sehingga perubahan dari satu nama langsung terlihat oleh semua nama dan method pengubah cukup ditulis tanpa output. Copy-on-write membuat semantik value tetap murah di mesin, dan pilihan keluarga ditentukan oleh kebutuhan identitas: data yang boleh disalin memakai value, state yang harus dibagi memakai handle. Berkas TitikValue.m, TitikHandle.m, modifikasiDalam.m, dan uji_semantik.m di bagian bawah halaman memuat seluruh demo yang sudah teruji.