Constructor dan validasi dari dua chapter sebelumnya hanya bermakna jika satu pintu masuk tertutup: property saldo yang diberi SetAccess = private tidak bisa lagi ditulis dari luar class, sehingga aturan “saldo >= 0” benar-benar terjaga — bukan sekadar diharapkan. Access control adalah mekanisme MATLAB untuk memilih siapa yang boleh membaca, menulis, dan memanggil setiap bagian class. Pada chapter ini kita mengunci class AkunBank dan memastikan invariant-nya bertahan terhadap upaya perusakan dari luar. Cakupan materi:

  • atribut GetAccess dan SetAccess pada property
  • properti read-only dan properti Hidden
  • atribut Access pada method
  • konsep singkat protected dan hubungannya dengan inheritance

Mengapa Membatasi Akses #

Kita menulis method setor() dan tarik() yang memvalidasi setiap perubahan saldo — tetapi selama property saldo masih bisa ditulis langsung (a.saldo = 1e9), semua validasi itu bisa dilewati. Aturannya: ubah data hanya lewat pintu yang memeriksa. Mekanisme di balik layar: setiap operasi a.saldo = x dijalankan MATLAB sebagai subsasgn — dan sebelum menulis nilai, MATLAB memeriksa atribut SetAccess property tersebut terhadap konteks pemanggil (di dalam definisi class atau di luarnya). Pelanggaran dihentikan dengan galat sebelum nilai tersentuh:

matlab
>> a = AkunBank('Budi', 500000);
>> a.saldo = 100000000;
text
Setting the 'saldo' property of the 'AkunBank' class is not allowed.

Pesan tersebut khas MATLAB: pesan galat akses dihasilkan interpreter, menyebut property dan class yang dilindungi — bukan berasal dari kode kita.

GetAccess dan SetAccess #

Atribut ditempel pada blok properties dalam kurung. Nilai default semuanya public — perilaku yang kita nikmati sejauh ini:

KombinasiBaca dari luarTulis dari luarKhasiat
(tanpa atribut)bolehbolehdata terbuka
SetAccess = privatebolehditolakread-only dari luar, method bebas menulis
GetAccess = privateditolak(tergantung Set)data internal, diakses lewat method
GetAccess = private, SetAccess = privateditolakditolaksepenuhnya internal
matlab
properties (SetAccess = private)
    saldo = 0
    jumlahTransaksi = 0
end

Diagram berikut memetakan siapa boleh apa pada class AkunBank — kode luar hanya bisa membaca saldo dan memanggil method publik; segala penulisan harus lewat method yang berada di dalam class:

Untuk pembacaan yang dibatasi, pesan galatnya sebangun — Getting the 'pin' property of the 'AkunBank' class is not allowed. — sehingga data internal seperti PIN atau cache tetap tak terlihat dari luar sambil tetap bisa dipakai oleh method class.

Properti Read-Only #

Kombinasi paling sering dipakai adalah SetAccess = private dengan GetAccess tetap publik: property menjadi read-only bagi dunia luar. Nilainya masih bisa ditulis — oleh constructor dan method class mana pun — karena pembatasan hanya berlaku terhadap kode di luar definisi class. Pola lengkapnya tiga lapis: constructor mengisi nilai awal, method pengubah (yang memvalidasi) memperbaruinya, kode luar hanya membaca. Hasilnya, invariant dijaga tanpa membuat data mustahil dilihat — laporan dan debugging tetap bisa membaca a.saldo kapan saja.

Hidden: Menyembunyikan dari Tampilan #

Atribut Hidden = true menyembunyikan property dari tampilan object (dan tab-completion Command Window), tanpa mengubah hak aksesnya sedikit pun:

matlab
properties (Hidden = true)
    catatan = ''
end

Property catatan di atas tetap bisa dibaca dan ditulis dari luar class — Hidden murni urusan kebersihan tampilan, agar object besar tidak membanjiri layar dengan data teknis seperti cache atau counter internal.

Akses pada Method #

Method juga punya atribut akses lewat Access pada blok methods. Method dengan Access = private hanya bisa dipanggil dari method lain class yang sama — class AkunBank memakainya untuk catat(), pencatat riwayat transaksi yang tidak ada urusan dengan pihak luar:

matlab
methods (Access = private)
    function obj = catat(obj, teks)
        if isempty(obj.catatan)
            obj.catatan = teks;
        else
            obj.catatan = [obj.catatan '; ' teks];
        end
    end
end

Mekanisme penegakkannya sama dengan property: MATLAB memeriksa konteks pemanggil sebelum menjalankan method. Nilai Access lain: protected — method (atau property) hanya boleh diakses class itu sendiri dan subclass-nya. Atribut ini menjadi kunci inheritance: class RekeningPremium < RekeningBank boleh memanggil method protected milik induknya, sedangkan kode luar tetap ditolak. Kita bedah tuntas pada Chapter Inheritance.

Contoh Lengkap: AkunBank #

Class AkunBank menggabungkan seluruh atribut: saldo read-only dari luar, catatan tersembunyi, dan catat() privat:

matlab
classdef AkunBank
    %AKUNBANK Akun yang saldonya dijaga invariant oleh class.
    properties (SetAccess = private)
        saldo = 0
        jumlahTransaksi = 0
    end
    properties
        pemilik = 'Tanpa Nama'
    end
    properties (Hidden = true)
        catatan = ''
    end
    methods
        function obj = AkunBank(pemilik, saldoAwal)
            if nargin < 2
                saldoAwal = 0;
            end
            if nargin < 1
                pemilik = 'Tanpa Nama';
            end
            if ~ischar(pemilik) || isempty(strtrim(pemilik))
                error('AkunBank:pemilikTidakValid', ...
                    'pemilik harus teks non-kosong.');
            end
            if ~isscalar(saldoAwal) || ~isnumeric(saldoAwal) || ...
                    saldoAwal < 0
                error('AkunBank:saldoTidakValid', ...
                    'saldo awal harus skalar >= 0.');
            end
            obj.pemilik = pemilik;
            obj.saldo = saldoAwal;        % sah: di dalam class
            obj = obj.catat(sprintf('dibuka saldo %g', saldoAwal));
        end
        function obj = setor(obj, jumlah)
            if ~isscalar(jumlah) || ~isnumeric(jumlah) || jumlah <= 0
                error('AkunBank:jumlahTidakValid', ...
                    'jumlah setor harus skalar positif.');
            end
            obj.saldo = obj.saldo + jumlah;
            obj.jumlahTransaksi = obj.jumlahTransaksi + 1;
            obj = obj.catat(sprintf('setor %g', jumlah));
        end
        function obj = tarik(obj, jumlah)
            if ~isscalar(jumlah) || ~isnumeric(jumlah) || jumlah <= 0
                error('AkunBank:jumlahTidakValid', ...
                    'jumlah tarik harus skalar positif.');
            end
            if jumlah > obj.saldo
                error('AkunBank:saldoKurang', ...
                    'saldo %g tidak cukup untuk tarik %g.', ...
                    obj.saldo, jumlah);
            end
            obj.saldo = obj.saldo - jumlah;
            obj.jumlahTransaksi = obj.jumlahTransaksi + 1;
            obj = obj.catat(sprintf('tarik %g', jumlah));
        end
        function tampilkanInfo(obj)
            fprintf('%s | saldo Rp%.2f | transaksi %d\n', ...
                obj.pemilik, obj.saldo, obj.jumlahTransaksi);
        end
        function c = riwayat(obj)
            c = obj.catatan;   % jendela baca untuk data internal
        end
    end
    methods (Access = private)
        function obj = catat(obj, teks)
            if isempty(obj.catatan)
                obj.catatan = teks;
            else
                obj.catatan = [obj.catatan '; ' teks];
            end
        end
    end
end

Mari kita bedah baris-baris kode di atas:

  1. Baris 3-6 (properties (SetAccess = private)): saldo dan jumlahTransaksi hanya bisa ditulis dari dalam class — constructor dan method masih bebas, kode luar ditolak.
  2. Baris 31 (obj.saldo = saldoAwal;): constructor mengisi saldo awal yang sudah divalidasi — penulisan sah karena berada di dalam definisi class.
  3. Baris 34-42 (setor): satu-satunya pintu menambah saldo: validasi jumlah, perubahan saldo, penambahan counter, lalu pencatatan riwayat.
  4. Baris 61-63 (riwayat): jendela baca untuk catatan — data internal disajikan lewat method publik, bukan dibuka langsung.
  5. Baris 65-73 (methods (Access = private)): catat() hanya bisa dipanggil oleh method class ini; pemanggilan a.catat(...) dari luar ditolak MATLAB.

Skrip uji_AkunBank.m mencoba menyerang invariant dari luar class:

matlab
% uji_AkunBank.m - menguji access control pada class AkunBank
a = AkunBank('Budi', 500000);

a = a.setor(250000);
a = a.tarik(200000);
a.tampilkanInfo();

fprintf('riwayat : %s\n', a.riwayat());

% GetAccess default public: membaca saldo dari luar diizinkan
fprintf('baca saldo dari luar : Rp%.2f\n', a.saldo);

% SetAccess private: menulis saldo dari luar ditolak
try
    a.saldo = 100000000;
    fprintf('PERINGATAN: perubahan saldo dari luar lolos!\n');
catch
    fprintf('tulis saldo dari luar ditolak (SetAccess private).\n');
end

% method Access private tidak bisa dipanggil dari luar
try
    a.catat('entri palsu');
    fprintf('PERINGATAN: method private terpanggil!\n');
catch
    fprintf('panggil catat() dari luar ditolak (Access private).\n');
end

a.tampilkanInfo();   % saldo tidak berubah oleh upaya di atas

Output yang Dihasilkan:

text
Budi | saldo Rp550000.00 | transaksi 2
riwayat : dibuka saldo 500000; setor 250000; tarik 200000
baca saldo dari luar : Rp550000.00
tulis saldo dari luar ditolak (SetAccess private).
panggil catat() dari luar ditolak (Access private).
Budi | saldo Rp550000.00 | transaksi 2

Skrip uji memakai try/catch tanpa mengambil err.message — pesan galat akses dihasilkan interpreter sehingga teksnya bergantung versi, dan skrip cukup mencatat ringkasan satu baris. Dua baris tampilkanInfo() di awal dan akhir membuktikan hasil terpenting: segala upaya menulis saldo dari luar tidak mengubah satu rupiah pun.

Ringkasan #

Access control menutup pintu yang dilewati validasi: SetAccess = private menjadikan property read-only dari luar (constructor dan method tetap menulis sah), GetAccess = private menyembunyikan data internal dari pembacaan, Hidden hanya menyembunyikan dari tampilan, dan Access = private pada blok methods membatasi pemanggilan ke dalam class. Pelanggaran dihentikan interpreter dengan galat seperti Setting the 'saldo' property of the 'AkunBank' class is not allowed. — bukan oleh kode kita. Kombinasinya menjadikan invariant (“saldo >= 0”) mustahil dilanggar dari luar class. Berkas AkunBank.m dan uji_AkunBank.m di bagian bawah halaman memuat implementasi lengkap yang sudah teruji.