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:

AspekValue classHandle class
Deklarasiclassdef TitikValueclassdef TitikHandle < handle
b = ab menerima salinan penuhb menunjuk objek yang sama
Ubah b.xa tidak berubaha ikut berubah
Method pengubahobj = metode(obj) + assignmentcukup metode(obj)
Dikirim ke fungsifungsi menerima salinanfungsi menerima referensi
Contoh MATLABdouble, struct, class data seperti RekeningBankgraphics object, containers.Map

Value Class: Assignment Menyalin #

Kita mulai dari class polos yang menyimpan koordinat titik. Berkas TitikValue.m:

matlab
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
end

Uji paling telanjang dari semantik value adalah assignment diikuti modifikasi (bagian awal uji_semantik.m):

matlab
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:

text
VALUE  : a.x = 1, b.x = 99

Variabel 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:

matlab
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:

text
VALUE  : c.x setelah geser tanpa assignment = 1
VALUE  : c.x setelah c = c.geser(...)       = 11

Mari kita bedah baris-baris kode di atas:

  1. Baris 1 (classdef TitikValue): tanpa < handle, MATLAB membentuk class ini sebagai value class — aturan menyalin berlaku otomatis.
  2. Baris 12-19 (function obj = TitikValue(x, y)): constructor standar dengan default y = 0 lewat nargin.
  3. Baris 21-25 (function obj = geser(obj, dx, dy)): kepala method menyatakan output obj. MATLAB mengeksekusi method pada salinan, lalu mengembalikan salinan yang sudah digeser; tanpa assignment hasilnya dibuang.
  4. Baris 2 dan 4 (c.geser(...) vs c = 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:

matlab
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
end

Uji yang sama kini menghasilkan cerita yang berbeda:

matlab
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:

text
HANDLE : p.x = 99, q.x = 99
HANDLE : p.x = 109, q.x = 109

Mari kita bedah baris-baris kode di atas:

  1. Baris 1 (classdef TitikHandle < handle): mewarisi class bawaan handle — sejak baris ini, assignment membagi referensi, bukan menyalin isi.
  2. 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:

matlab
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;
end

Pemanggilnya di bagian akhir uji_semantik.m membuktikan arah masing-masing:

matlab
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:

text
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.

KebutuhanKeluarga yang tepatAlasan
Data hitung-hitungan (titik, matriks, hasil pengukuran)valuepenyalinan aman, tidak ada efek samping
Objek GUI, plot, koneksihandlesatu sumber state untuk banyak pengguna
Method berantai obj.a().b()handlepemanggilan tanpa assignment tetap melekat
Data yang dikirim ke banyak fungsi pembantuvaluefungsi tidak bisa merusak data pemanggil
Objek dengan siklus hidup (open/close, connect)handleidentitas 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.