Object-Oriented PHP:

Abstract Class dan Abstract Method

Episode 12 Diperbarui: 7+ menit

Abstract class adalah class yang mengandung minimal satu buah abstract method, yaitu method yang hanya berupa nama method dan argumennya (jika ada) dan diawali dengan keyword abstract.

Ketika sebuah class dibuat dengan cara menurunkan atau class inheritance dari abstract class maka semua method yang didefinisikan sebagai abstract oleh parent class harus diimplementasikan ulang oleh class tersebut yang sebagai child class atau class turunan dari abstract class.

Sebagai contoh kita akan membuat banyak level akses User dalam sebuah website berita, ada yang sebagai Admin, Editor dan Reporter. Dalam kasus tersebut yang pertama kita buat adalah membuat parent class atau class induk yang diberi nama User. Class User tersebut nantinya akan diturunkan kepada class Admin, Editor dan Reporter. Pada setiap child class kita tentukan harus ada method yang sama yang harus dimiliki, misal method showName(). Jadi setiap class turunan harus memiliki method showName(). Untuk memaksakan kehendak tersebut maka dalam parent class (abstract class) dibuatlah abstract method showName().

Materi mengenai abstract class dan abstract method ini akan sedikit susah dimengerti bagi sebagian orang ketika tidak disertai contoh.

Berikut aturan-aturan disertai contoh agar lebih mudah memahami:

1. Cara pembuatan abstract class dan abstract method

Cara membuatnya yaitu harus didahului dengan keyword abstract sebelum class dan method.

<?php
// diawali keyword abstract
abstract class User
{
    // diawali keyword abstract
    abstract protected function showName();
}

2. Abstract class tidak bisa dijadikan object

<?php
abstract class User
{
    //
}

// membuat object dari abstract class
$thisUser = new User();

Jika kode program di atas tetap dijalankan maka akan keluar PHP Fatal error: Uncaught Error: Cannot instantiate abstract class ... karena ini adalah abstract class yang tujuannya sebagai base class atau class acuan bukan untuk digunakan sebagai object.

3. Jika dalam sebuah class terdapat abstract method maka class tersebut harus menjadi abstract class.

<?php
// bukan abstract class
class User
{
    // tapi ini abstract method
    abstract protected function showName();
}

Jika kode program di atas tetap dijalankan maka akan keluar PHP Fatal error: Class User contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (User::showName) ... karena class User bukan abstract class tetapi memiliki abstract method, ini tidak diperbolehkan.

4. Abstract method hanya boleh signature

Artinya abstract method tidak boleh memiliki body, yaitu hanya berupa deklarasi saja dan tidak memiliki isi.

<?php
abstract class User
{
    // abstract method memiliki body, ditandai
    // dengan disertai {}
    // ini yang salah
    abstract protected function showName(){
        //
    }

    // ini yang benar
    abstract protected function showGreeting();
}

Jika kode program di atas tetap dijalankan maka akan keluar PHP Fatal error: Abstract function User::showName() cannot contain body ... karena abstract method tidak boleh memiliki body.

5. Semua class turunan harus mengimplementasikan semua abstract method dari parent class

<?php
abstract class User
{
    abstract protected function showName();
    abstract protected function showGreeting($greeting);

    // regular method
    public class showBio(){
        retudn "this is a Bio";
    }
}

class Admin extends User
{
    public function showName(){
        return "Bagus";
    }

    // tidak ada showGreeting($greeting)
}

Jika kode program di atas tetap dijalankan maka akan keluar PHP Fatal error: Class Admin contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (User::showGreeting) ... karena tidak semua abstract method dari parent class diimplementasikan, yaitu showGreeting($greeting) tidak ada dalam class Admin.

Ingat ya, hanya abstract method, sedangkan untuk regular method tidak harus diturunkan.

6. Semua method turunan dari abstract method harus didefinisikan dengan tingkat visibilitas yang sama atau lebih rendah

<?php
abstract class User
{
    // public
    abstract public function showName();
}

class Admin extends User
{
    // protected
    protected function showName(){
        return "Bagus";
    }
}

Jika kode program di atas tetap dijalankan maka akan keluar PHP Fatal error: Access level to Admin::showName() must be public (as in class User) ... karena showName() dalam child class memiliki akses level (tingkat visibilitas) lebih tinggi dari pada showName() yang berada dalam parent class. Urutan tingkatan akses level dari tinggi ke rendah adalah 1. private, 2. protected 3. public.

7. Abstract class boleh memiliki property dan method regular

<?php
// abstract class
abstract class User
{
    // regular property
    protected $address = 'Semarang';

    // abstract method
    abstract protected function showName();
    abstract public function showGreeting($greeting);
    
    // regular method
    public function showBio(){
        return "Hi, my name is " . $this->showName() . " from " . $this->address;
    }
}

8. Abstract class boleh memiliki static method

<?php
// abstract class
abstract class User
{
    // abstract method
    abstract protected function showName();
    
    // static method
    public static function showHi(){
        return "Hi, this is static method";
    }
}

// panggil static method dari abstract class
echo User::showHi();

9. Semua method turunan dari abstract method harus mengikuti signature

Misal dalam signature disertai required argument maka method dalam child class harus memiliki required argument tersebut, contoh:

<?php
abstract class User
{
    abstract protected function showName();
    
    // memiliki argumen $greeting
    abstract public function showGreeting($greeting);
}

class Admin extends User
{
    public function showName(){
        return "Bagus";
    }

    // tidak memiliki argumen $greeting
    public function showGreeting(){
        return "My name is " . $this->showName();
    }
}

Jika kode program di atas tetap dijalankan maka akan keluar PHP Fatal error: Declaration of Admin::showGreeting() must be compatible with User::showGreeting($greeting) ... karena showGreeting() dalam child class tidak memiliki argument sebagaimana showGreeting() dalam parent class.

Tetapi method dalam child class boleh memberikan opsional argument yang tidak ada dalam signature, contoh:

<?php
abstract class User
{
    abstract protected function showName();
    
    // memiliki required argument: $greeting
    abstract public function showGreeting($greeting);
}

class Admin extends User
{
    public function showName(){
        return "Bagus";
    }

    // memiliki required argument: $greeting
    // dan opsional argument: $address
    public function showGreeting($greeting, $address = 'Banjar'){
        return $greeting . ", my name is " . $this->showName() . " from " . $address;
    }
}

$class = new Admin;

// output: Good morning, my name is Bagus from Banjar
echo $class->showGreeting("Good morning");

Demikian aturan-aturan dalam abstract class dan abstract method.

Perhatikan contoh di bawah ini, setiap class yang diturunkan dari class User harus memiliki method showName() dan showGreeting() karena kedua method tersebut merupakan abstract method, sedangkan untuk method showBio() hanya bersifat opsional artinya tidak harus dimiliki oleh child class karena bukan abstract method.

<?php
abstract class User
{
    abstract protected function showName();
    
    // memiliki required argument: $greeting
    abstract public function showGreeting($greeting);

    // regular method
    public function showBio(){
        echo "This is my Bio <br/>";
        echo "My name is " . $this->showName();
    }
}

class Admin extends User
{
    public function showName(){
        return "Bagus Admin";
    }

    public function showGreeting($greeting, $address = 'Banjar'){
        return $greeting . ", my name is " . $this->showName() . " from " . $address;
    }
}

class Editor extends User
{
    public function showName(){
        return "Andre Editor";
    }

    public function showGreeting($greeting, $address = 'Banjar'){
        return $greeting . ", my name is " . $this->showName() . " from " . $address;
    }

    // bukan berasal dari abstract method
    public function showBio(){
        echo "This is Bio from " . $this->showName();
    }
}

class Reporter extends User
{
    public function showName(){
        return "Bambang Reporter";
    }

    public function showGreeting($greeting, $address = 'Banjar'){
        return $greeting . ", my name is " . $this->showName() . " from " . $address;
    }
}

$admin = new Admin;
$editor = new Editor;
$reporter = new Reporter;

echo $admin->showGreeting("Good morning", "Bandung") . "<br/>";
echo $admin->showBio() . "<br/><br/>";

echo $editor->showGreeting("Good night", "Jayapura") . "<br/>";
echo $editor->showBio() . "<br/><br/>";

echo $reporter->showGreeting("Good evening", "Maluku") . "<br/>";
echo $reporter->showBio();

outputnya:
Good morning, my name is Bagus Admin from Bandung
This is my Bio
My name is Bagus Admin

Good night, my name is Andre Editor from Jayapura
This is Bio from Andre Edito

Good evening, my name is Bambang Reporter from Maluku,
This is my Bio
My name is Bambang Reporter

Bagaimana, mudahkan? jika belum faham coba baca berulang-ulang atau tanyakan di komentar :blush: