Override di chapter Inheritance menunjukkan satu object memilih method milik class-nya sendiri. Kekuatan sesungguhnya muncul ketika banyak object dari banyak subclass dikumpulkan dan dipanggil lewat satu baris kode: loop yang sama menghitung luas persegi maupun lingkaran, fungsi yang sama menularkan suara kucing maupun anjing. Polymorphism — “banyak bentuk, satu antarmuka” — inilah pilar ketiga OOP yang membuat kode baru menempel tanpa mengedit kode lama: class baru cukup masuk kumpulan, dan seluruh loop lama langsung memahaminya. Cakupannya:

  • dynamic dispatch: bagaimana MATLAB memilih method saat runtime
  • abstract class sebagai kontrak: classdef (Abstract) dan methods (Abstract)
  • kumpulan objek campuran dan loop lintas subclass
  • polymorphism versus switch-case, serta konsep interface

Satu Antarmuka, Banyak Perilaku #

Aturannya: satu pemanggilan method yang sama (obj.suara()) menjalankan implementasi berbeda sesuai class dinamis masing-masing object. Mekanisme di balik layar disebut dynamic dispatch: setiap object membawa identitas class-nya, dan saat kandang{i}.bersuara() dieksekusi, interpreter mencari method bersuara dimulai dari class dinamis object itu — bukan dari tipe variabel penampungnya. Kita bangun hierarki kecil bertema hewan; berkas Hewan.m:

matlab
classdef (Abstract) Hewan
    %HEWAN Abstract class: cetak biru bersama untuk semua hewan.
    %   Versi MATLAB menambahkan blok methods (Abstract) dengan
    %   suara() — lihat penjelasan di chapter Polymorphism. Berkas ini
    %   memakai padanan portabel: method suara() konkret yang error
    %   bila subclass lupa meng-override.

    properties (SetAccess = protected)
        nama
    end

    methods
        function obj = Hewan(nama)
            obj.nama = nama;
        end

        function s = suara(obj)
            % Penjaga manual: gagal keras bila subclass tidak meng-override.
            error('Hewan:suara', ...
                'subclass %s wajib meng-override suara()', class(obj));
        end

        function bersuara(obj)
            % Algoritma umum: satu baris ini bekerja untuk semua subclass.
            fprintf('%s berkata: %s\n', obj.nama, obj.suara());
        end
    end
end

Method bersuara() di atas adalah algoritma umum yang tidak pernah ditulis ulang: satu baris fprintf memanggil suara(), dan hasilnya bergantung siapa pemiliknya. Subclass tinggal mengisi bagian yang berubah — berkas Kucing.m:

matlab
classdef Kucing < Hewan
    %KUCING Subclass konkret: satu-satunya kewajiban adalah suara().

    methods
        function obj = Kucing(nama)
            obj@Hewan(nama);
        end

        function s = suara(obj)
            s = 'meong';
        end
    end
end

Berkas Anjing.m serupa dengan s = 'guk guk'. Dua object, satu antarmuka (bagian pertama uji_polymorphism.m):

matlab
k = Kucing('Oyen');
a = Anjing('Bobi');
k.bersuara();
a.bersuara();

Output yang Dihasilkan:

text
Oyen berkata: meong
Bobi berkata: guk guk

Mari kita bedah baris-baris kode di atas:

  1. Baris 1 (classdef (Abstract) Hewan): atribut (Abstract) melarang Hewan diinstansiasi — class ini hanya cetak biru (pembuktian di bawah).
  2. Baris 17-21 (function s = suara(obj)): penjaga manual — bila subclass lupa meng-override, pemanggilan pertama langsung galat dengan pesan jelas.
  3. Baris 23-26 (function bersuara(obj)): algoritma umum polymorphism — method superclass memanggil method yang pasti di-override subclass, tanpa tahu implementasinya.

Abstract Class: Kontrak Tanpa Implementasi #

Bentuk idiomatik di MATLAB memakai dua atribut sekaligus: class ditandai (Abstract), dan method yang wajib diimplementasikan dideklarasikan dalam blok methods (Abstract) tanpa badan function:

matlab
classdef (Abstract) Hewan
    properties (SetAccess = protected)
        nama
    end
    methods
        function obj = Hewan(nama)
            obj.nama = nama;
        end
        function bersuara(obj)
            fprintf('%s berkata: %s\n', obj.nama, obj.suara());
        end
    end
    methods (Abstract)
        suara(obj)   % hanya tanda tangan; subclass wajib mengisi
    end
end

Dokumentasi MATLAB menegaskan dua aturan blok ini: “Do not use a function…end block to define an abstract method, use only the method signature”, dan subclass harus mengimplementasikan seluruh method abstract agar menjadi concrete class — subclass yang masih menyisakan satu method abstract ikut menjadi abstract. Tabel berikut memetakan dukungan fiturnya:

FiturMATLABGNU Octave 10
classdef (Abstract) (larangan instansiasi)didukungdidukung
methods (Abstract) (kontrak tanpa badan)didukungbelum didukung
Array objek campuran [kucing, anjing]didukungbelum stabil

Kedua perlindungan itu terlihat bekerja (bagian skrip uji):

matlab
try
    h = Hewan('Misteri');
catch
    fprintf('Hewan(''Misteri'') ditolak: class Abstract tidak bisa dibuat\n');
end

Output yang Dihasilkan:

text
Hewan('Misteri') ditolak: class Abstract tidak bisa dibuat

Sedangkan Ikan.m — subclass yang sengaja tidak mengimplementasikan suara() — lolos dibuat namun tertangkap penjaga saat dipakai:

matlab
ikan = Ikan('Nemo');
try
    ikan.bersuara();
catch err
    fprintf('Ikan tertangkap penjaga: %s\n', err.message);
end

Output yang Dihasilkan:

text
Ikan tertangkap penjaga: subclass Ikan wajib meng-override suara()

Kumpulan Objek Campuran dan Loop Polymorphic #

Di sinilah polymorphism terbayar: satu kumpulan berisi object dari class berbeda, satu loop, nol if. Di MATLAB, penggabungan [k, a, Kucing('Milo')] menghasilkan array ber-class superclass bersama; di GNU Octave 10 penggabungan classdef masih terbatas, jadi skrip uji memakai cell array — bekerja identik di kedua engine:

matlab
kandang = {k, a, Kucing('Milo')};
fprintf('--- isi kandang ---\n');
for i = 1:numel(kandang)
    kandang{i}.bersuara();   % dispatch mengikuti class masing-masing elemen
end

Output yang Dihasilkan:

text
--- isi kandang ---
Oyen berkata: meong
Bobi berkata: guk guk
Milo berkata: meong

Satu baris kandang{i}.bersuara() menghasilkan tiga perilaku — dispatch terjadi per elemen:

Diagram tersebut menegaskan letak keputusan: bukan di loop (yang buta terhadap jenis hewan), melainkan di identitas class masing-masing elemen saat method dipanggil.

Polymorphism vs switch-case #

Cara prosedural yang biasa muncul: percabangkan berdasarkan nama class, lalu tulis rumusnya satu per satu:

matlab
switch class(bentuk)          % pola yang harus dirawat terus-menerus
    case 'Persegi',   l = bentuk.sisi^2;
    case 'Lingkaran', l = pi * bentuk.jari^2;
    otherwise,        error('class tak dikenal');
end

Setiap class baru (Segitiga, Trapesium) memaksa kita menyunting switch ini di seluruh program — kode lama ikut tersentuh. Polymorphism membalik arahnya: class baru membawa implementasinya sendiri, kode pemanggil tidak berubah. Pemroses luas campuran tinggal tiga baris (memakai hierarki Bentuk dari chapter Inheritance):

matlab
daftar = {Persegi(4), Lingkaran(7), Persegi(2)};
total = 0;
for i = 1:numel(daftar)
    total = total + daftar{i}.luas();
end
fprintf('total luas campuran : %g\n', total);

Output yang Dihasilkan:

text
total luas campuran : 173.938
Aspekswitch/if pada classPolymorphism
Menambah class barusunting semua percabangancukup buat subclass + override
Lupa satu kasusjatuh ke otherwise (kalau ada)method bawaan/penjaga yang menjawab
Pemetaan perilakuterpisah dari datamenempel di class pemiliknya
Skalamemburuk seiring jumlah classtetap datar

Interface: Abstract Class Murni #

Interface di MATLAB bukan sintaks terpisah, melainkan abstract class yang seluruh anggotanya abstract — kontrak nama-nama method tanpa satu baris implementasi pun. Dokumentasi MATLAB mendefinisikannya sebagai “an abstract class describing functionality that is common to a group of classes, but that requires unique implementations within each class”. Contoh kontrak perbandingan:

matlab
classdef (Abstract) Comparable
    % Comparable Interface murni: kontrak tanpa implementasi apa pun.
    methods (Abstract)
        apakahLebihBesar(obj, lain)
    end
end

Class apa pun yang mewarisi Comparable lalu mengimplementasikan apakahLebihBesar() dapat diproses oleh fungsi pengurutan generik yang hanya mengenal kontrak itu — pola yang sama dipakai sort() internal MATLAB untuk berbagai tipe.

Ringkasan #

Polymorphism bekerja karena dynamic dispatch memilih method berdasarkan class dinamis object, bukan variabel penampungnya: loop kandang{i}.bersuara() menjalankan tiga perilaku berbeda dari satu baris kode. Abstract class menegakkan kontraknya — (Abstract) menolak instansiasi, methods (Abstract) mendeklarasikan method wajib (MATLAB; GNU Octave 10 memakai padanan penjaga error() pada berkas yang kita kirim) — dan interface hanyalah abstract class tanpa implementasi. Ketimbang switch pada nama class yang harus disunting tiap ada class baru, polymorphism membuat kode pemroses tertutup terhadap perubahan: total luas campuran dihitung tanpa satu percabangan pun. Berkas Hewan.m, Kucing.m, Anjing.m, Ikan.m, salinan Bentuk.m/Persegi.m/Lingkaran.m, dan uji_polymorphism.m di bagian bawah halaman memuat seluruh demo yang sudah teruji.