Tutorial OOP Lanjutan

Trait

Materi ini memiliki 1 buah lampiran. Namun Anda tidak dapat mengakses lampiran karena belum terdaftar di kursus ini. Klik disini untuk mendaftar.

Di dalam dunia pemograman berbasis objek, kita dibatasi pada saat hendak melakukan Inheritance, dimana kita hanya boleh memilih satu kelas induk. Bagaimana kalau kita ingin memecah method dan property-nya menjadi beberapa kelas, yang kemudian ingin kita gabungkan kembali menjadi satu buah kelas anak?

Nah, di bahasa pemograman PHP, solusinya adalah Trait. Trait ini mirip dengan class, dimana kita bisa menyimpan property, method dan juga konstanta di dalam Trait. Setelah itu Trait bisa kita wariskan menjadi kelas anak baru. Namun disini kita tidak dibatasi hanya boleh 1 Trait induk. Jadi di satu kelas anak yang sama, kita boleh menggunakan banyak Trait sekaligus.

Biasanya Trait digunakan untuk menyimpan fungsi-fungsi umum, yang biasanya digunakan ulang di banyak class. Sebagai contoh adalah fungsi untuk menulis log.

Berikut adalah contoh kode Trait. Untuk membuat Trait, kita menggunakan kada kunci trait diikuti oleh nama Trait-nya. Pada PHP, kita menggunakan naming convention dimana untuk setiap trait mesti kita akhiri dengan kata trait. Kemudian kita buka kurung kurawal dan di dalamnya kita bisa menambahkan property, method maupun konstanta. Sebagai contoh disini hanya ada 1 method dengan nama log.

Kemudian di dalam kelas, kita bisa menambahkan kata kunci use diikuti oleh nama Trait, untuk menambahkan semua property, method dan konstanta ke dalam kelas. Perhatikan bahwa pada kelas tidak ada method log, namun karena kita telah menambahkan LoggerTrait, maka kita bisa menggunakan method log seolah-olah method tersebut ada di dalam kelas.

Agar lebih jelas kita coba praktek ya. Kita buka Visual Studio Code. Kita mulai dari proyek kosong ya. Disini masih belum ada file untuk kode sama sekali. Namun kita memiliki 2 buah folder, yaitu folder class untuk menampung kelas-kelas yang akan kita buat. Dan ada folder Trait untuk menampung semua Trait.

Pertama kita buka folder Trait dahulu ya. Kita buat file baru dengan nama LoggerTrait.php. Kita tulis tag pembuka PHP. Lalu kita buat Trait pertama kita. Untuk membuat Trait kita gunakan kata kunci trait diikuti oleh namanya, yaitu LoggerTrait.

Di dalamnya kita buat satu buah method dengan nama log, parameter $message dan mengembalikan void. Isinya sederhana saja ya. Kita ketik echo untuk tampilkan pesan di layar, yaitu "[Log]: $message\n".

Kita simpan dan kita coba jalankan dulu kodenya ya. Pada terminal kita ketik php kemudian nama foldernya trait dan garis miring nama file LoggerTrait.php. Tidak ada error ya. Berarti kita bisa lanjutkan ke kode berikutnya.

Kita buat file baru di dalam folder class. Kita beri nama User. Di dalamnya, kita buka tag PHP. Lalu kita buat kelas User. Kita gunakan fitur Promotion untuk membuat property ya. Kita buat public function __construct, dengan parameter private string $name. Dan methodnya hanya ada blok tanpa isi ya.

Kemudian kita tambahkan method setter dengan nama setName dan parameter $value, mengembalikan void. Di dalamnya kita simpan nilai $value ke dalam property $name.

Sampai disini kita simpan dan coba jalankan dahulu. Kita ketik php class\User.php. Tidak ada error ya.

Selanjutnya kita ingin menambahkan semua method milik LoggerTrait ke dalam kelas User. Kalau kita menggunakan inheritance, kita tinggal turunkan kelas User dari Logger ya. Namun berhubung disini kita menggunakan Trait, maka sintaksnya agak berbeda.

Pertama kita panggil dahulu require_once untuk menambahkan kode trait ke file User.php. Kita mesti sebutkan nama foldernya dahulu ya, yaitu 'trait' kemudian diikuti oleh garis miring dan nama file traitnya yaitu LoggerTrait.php.

Nah, untuk menggunakan trait di dalam class, kita menggunakan kata kunci use. Namun kata kunci use ini kita tuliskan di dalam blok ya. Jadinya berbeda dari kata kunci extends atau implements yang biasanya dituliskan langsung setelah nama kelasnya. Di dalam blok, kita tambahkan kata use diikuti oleh nama trait-nya yaitu LoggerTrait.

Berhubung kita sudah menambahkan LoggerTrait ke dalam kelas, maka kita bisa menggunakan semua method dan property-nya. Sebagai contoh disini hanya ada satu method log ya. Namun method ini bisa kita panggil dari mana saja di dalam kelas kita. Misalkan pada saat mengubah nama, kita ingin menuliskan perubahannya di dalam log. Jadi di setelah kita mengubah property $name, kita tambahkan kode $this->log("Set Name to $value").

Kita coba jalankan. Tidak ada error ya.

Lalu kita buat file baru pada folder utama dengan nama main.php. Kita buka tag PHP. Lalu kita require_once file 'class/User.php'. Kemudian kita instantiate kelas User dengan argument 'Skysen'. Dan kemudian kita panggil method setName untuk mengganti namanya, misalkan menjadi 'Nama Baru'.

Kita coba jalankan. Sekarang kita mendapatkan hasil '[Log]: Set Name to Nama Baru'. Ini adalah hasil dari pemanggilan method log yang berada di dalam LoggerTrait. Artinya kita sudah berhasil membuat sebuah trait dan menggunakannya di dalam kelas User.

Biasanya trait digunakan untuk fungsi-fungsi yang bersifat umum dan dapat digunakan ulang pada kelas-kelas lainnya. Contohnya adalah fungsi untuk mencatat log seperti pada contoh ini. Nantinya kalau kita membuat kelas lain seperti Product, Sales, Delivery ataupun kelas lainnya, kita bisa dengan mudah menggunakan use untuk menambahkan method log ke semua kelas.

Kita lanjutkan materi kita. Tadi sempat disebutkan bahwa kita bisa menggunakan lebih dari satu Trait di dalam kelas yang sama. Sebagai contoh disini kita buka kembali file LoggerTrait.php dan kita akan copy paste kode trait ini menjadi beberapa Trait.

Apabila teman-teman sedang mengerjakan proyek, sebaiknya setiap Trait ditaruh dalam file terpisah ya. Tujuannya adalah agar nantinya kita lebih mudah pada saat hendak mencari kode trait. Berhubung trait di dalam contoh ini hanya sederhana, maka semua trait saya gabung menjadi satu file.

Kita copy paste kode Trait sebanyak 2 kali. Kemudian kita ubah menjadi jenis logger lain ya. Yang kedua adalah WarningLoggerTrait, yang nama method-nya adalah warning. Dan tulisan di dalam method juga warning. Sedangkan Trait yang ketiga bernama NoticeLoggerTrait, dengan method bernama notice dan tulisan di dalamnya juga Notice.

Kita buka kembali file User.php. Disini kita hendak menggunakan langsung ketiga Trait dalam kelas User. Caranya gampang ya. Pada saat kita memanggil use, kita bisa langsung sebutkan ketiga nama trait dipisahkan dengan tanda koma. Kemudian di dalam method setName, kita bisa menggunakan method log, warning maupun notice. Sebagai contoh kita coba method warning ya. Kita coba jalankan kembali main.php dan sekarang tulisannya sudah berubah menjadi Warning.

Tadi sempat kita bahas kalau kita juga bisa melakukan Inheritance pada Trait, dan disini kita tidak dibatasi hanya boleh menggunakan satu induk. Kita bisa menurunkan Trait dari banyak induk sekaligus. Dan Trait anak akan mewarisi semua property, method dan konstanta milik semua induknya.

Sebagai contoh, tadi kita sudah punya LoggerTrait, WarningLoggerTrait dan NoticeLoggerTrait ya. Kita bisa membuat satu trait turunan dengan nama AllLoggerTrait, langsung dari ketiga trait ini. Caranya adalah kita tinggal gunakan kata kunci use dan sebutkan ketiga nama trait induknya dengan dipisahkan oleh tanda titik koma.

Kita coba praktek ya. Kita buka kembali file LoggerTrait.php. Di bagian paling bawah kita tambahkan trait baru dengan nama AllLoggerTrait. Isinya kita lakukan inheritance dari ketiga trait lainnya ya. Kita ketik

use LoggerTrait, WarningLoggerTrait, NoticeLoggerTrait;

Kita buka kembali file User.php. Nah, daripada kita mesti use tiga buah trait, kita tinggal langsung use AllLoggerTrait saja. Dan kita sudah bisa langsung mengakses seluruh property, method maupun konstanta dari ketiga trait tadi. Untuk memperlihatkan bahwa kita punya semua method-nya, pada method setName, kita panggil ketiga methodnya ya. Yaitu log, warning dan notice.

Kita coba jalankan main.php. Dan sekarang kita mendapatkan hasil baik dari method log, warning maupun notice.

Kita sudah mencoba untuk menggunakan beberapa Trait dalam kelas yang sama. Kebetulan nama method pada Trait kita semuanya berbeda ya. Namun dalam prakteknya, nantinya bisa saja ada beberapa method yang menggunakan nama yang sama sehingga terjadi conflict.

Untuk mengatasi hal ini, ada 2 buah solusi. Solusi pertama adalah dengan menggunakan kata kunci insteadof, maka kita memilih salah satu method untuk digunakan sedangkan method yang satunya lagi akan diabaikan. Solusi kedua adalah dengan menggunakan kata kunci as, disini kita bisa mengganti nama method menjadi alias sehingga nantinya bisa kita panggil dengan menggunakan alias tersebut.

Berikut adalah contoh kode dari Trait Conflict. Misalkan kita memiliki LoggerTrait dan DbLoggerTrait yang sama-sama memiliki method log. Pada saat kita menggunakan kata kunci use, kita tambahkan kurung kurawal. Lalu kita tulis LoggerTrait::log insteadof DbLoggerTrait. Artinya kita menggunakan method log miliki LoggerTrait.

Selanjutnya kita bisa menambahkan DbLoggerTrait::log as dbLog untuk mengganti nama method log menjadi dbLog. Nantinya kita tetap bisa menggunakan method log milik DbLoggerTrait, dengan cara menggunakan nama aliasnya yaitu dbLog.

Kita coba praktek. Kita buka kembali file LoggerTrait. Kita akan menambahkan LoggerTrait baru dengan nama DbLoggerTrait, yang rencanakan digunakan untuk menuliskan log ke database. Kodenya kita copy paste saja dari LoggerTrait ya. Kita ganti namanya menjadi DbLoggerTrait. Kemudian kita tambahkan property yang biasanya digunakan untuk koneksi ke database, yaitu public string $hostName = 'localhost', public string $userName = 'root' dan public string $password = 'root'.

Di dalam method log kita tambahkan komentar // TODO buka koneksi ke database. Untuk saat ini kita masih belum pernah membahas database ya. Jadi kode untuk membuka koneksi ke databasenya kita anggap sebagai TODO. Artinya nanti kalau kita sudah mengerti mengenai database, maka kita akan kembali ke kode ini untuk menambahkan kode untuk membuka koneksi ke database-nya. Untuk sementara kita tetap gunakan echo dahulu, namun kita ganti kata Log menjadi DbLog.

Kita buka User.php. Disini kita ganti use menjadi DbLoggerTrait. Jadi kita hanya menggunakan satu trait saja. Pada visual studio code langsung mengeluarkan 2 error ya, yaitu untuk method warning dan notice. Kita hapus kedua method tersebut karena tidak ada di dalam DbLoggerTrait. Kita coba jalankan maka kita mendapatkan hasil [DbLog].

Nah pada DbLoggerTrait ini terdapat 3 buah property ya. Kita coba var_dump($user). Dan pada object terdapat ketiga property dari DbLoggerTrait tadi ya, $hostName, $userName dan $password. Jadi dari contoh ini kita bisa melihat ya, kalau kita bisa menambah property pada trait. Lalu property tersebut dapat kita akses pada object yang menggunakan trait yang bersangkutan. Kita komentari dahulu var_dump($user).

Selanjutnya kita tambahkan LoggerTrait pada use. Sekarang kelas User menggunakan 2 trait sekaligus yaitu DbLoggerTrait dan LoggerTrait. Pada saat dijalankan, sekarang terjadi fatal error. Hal ini disebabkan karena kedua Trait menggunakan nama method yang sama, yaitu log.

Ada 2 buah solusi untuk masalah ini. Yang pertama adalah kita menggunakan kata kunci insteadof untuk memilih salah satu dari method. Sebagai contoh, setelah kata kunci use kita buka kurung kurawal. Lalu di dalamnya kita sebut nama trait yang hendak digunakan, misalkan DbLoggerTrait. Diikuti oleh dua buah tanda titik dua dan nama methodnya yaitu log. Kita tulis insteadof dan nama Trait yang diabaikan, yaitu LoggerTrait.

Kalau kita jalankan, sekarang sudah tidak error dan kita menggunakan method dari DbLoggerTrait. Namun kelemahannya adalah kita tidak bisa menggunakan method log milik LoggerTrait.

Sebaliknya kalau kita ganti menjadi LoggerTrait::log insteadof DbLoggerTrait. Maka sekarang yang bisa digunakan hanya method log milik LoggerTrait. Sedangkan method log milik DbLoggerTrait tidak bisa digunakan sama sekali.

Nah, kalau kita ingin menggunakan kedua method, maka kita menggunakan solusi kedua, yaitu as. Kita mengganti nama method DbLoggerTrait menjadi alias, sehingga bisa kita gunakan dengan cara memanggil alias tersebut. Cara menggunakannya adalah pertama kita sebutkan nama Traitnya, yaitu DbLoggerTrait, diikuti oleh dua buah tanda titik dua dan nama method log. Kita tulis kata kunci as diikuti oleh nama aliasnya, misalkan dbLog. Maka sekarang kita bisa memanggil method-nya menggunakan nama alias dbLog.

Sebagai contoh, pada method setName kita tambahkan kode baru yang memanggil $this->dbLog. Kita jalankan. Sekarang kita bisa memakai method log baik dari LoggerTrait maupun dari DbLoggerTrait.

2 Jam 41 Menit

Dengan menggunakan fasilitas tanya jawab, maka Anda bisa bertanya dan akan dijawab langsung oleh instruktur kursus.

Anda belum terdaftar pada kursus ini sehingga tidak bisa mengajukan pertanyaan.