Modul 4 PBO Package, Polymorphism, Overloading, Interface, Abstraction
Modul 4 PBO Package, Polymorphism, Overloading, Interface, Abstraction
0
13 Maret 2024
DISUSUN OLEH:
TAUFIQ RAMADHAN
SUTRISNO ADIT PRATAMA
DIAUDIT OLEH:
Ir. Galih Wasis Wicaksono, S.Kom, M.Cs.
TUJUAN
1. Mahasiswa dapat memahami multi file dengan package.
2. Mahasiswa dapat memahami konsep polymorphism.
3. Mahasiswa dapat memahami konsep abstraction.
4. Mahasiswa dapat memahami method overloading.
5. Mahasiswa dapat memahami abstract class & abstract method.
6. Mahasiswa dapat memahami interface.
TARGET MODUL
1. Mahasiswa dapat membuat dan mengimplementasikan multi file dengan package.
2. Mahasiswa dapat membuat dan mengimplementasikan polymorphism.
3. Mahasiswa dapat membuat dan mengimplementasikan overloading.
4. Mahasiswa dapat membuat dan mengimplementasikan abstract class dan abtract method.
5. Mahasiswa dapat membuat dan mengimplementasikan interface.
6. Mahasiswa dapat membuat dan mengimplementasikan relasi antar kelas.
PERSIAPAN
1. Java Development Kit.
2. Text Editor / IDE (Visual Studio Code, Netbeans, Intellij IDEA, atau yang lainnya).
KEYWORDS
● Package
● Polymorphism
● Overloading
● Interface
● Abstract class
● Abstract method
● Concrete class
● Concrete method
● Class relation
TEORI
● Package
Package adalah sebuah metode untuk mengelompokkan class dengan tujuan
menghindari konflik nama class (jika ada yang bernama sama) dan memudahkan
pengelolaan kode program, terutama pada aplikasi yang besar.
Dalam implementasinya, konsep ini serupa dengan pembuatan folder saat
menyimpan sebuah file. Meskipun setiap folder mungkin memiliki file dengan nama yang
sama, namun karena disimpan dalam folder yang berbeda, hal tersebut tidak menjadi
masalah.
Hal yang sama juga berlaku di dalam package Java, di mana kita dapat membuat
nama class yang identik selama berada di dalam package yang berbeda. Package dalam
bahasa pemrograman Java dibagi menjadi dua jenis:
1) Built-in package – package yang sudah disedikan oleh Java.
2) User-defined package – package yang kita definisikan sendiri.
▪ Built-in Package (package bawaan java)
Java memiliki cukup banyak package bawaan dan beberapa yang sudah pernah
kita pakai. Salah satu darinya adalah java.util yang berisikan Scanner class untuk
proses input user. Untuk daftar package yang ada di java bisa klik disini.
Untuk menggunakan package, tambah perintah import sebelum nama package di
awal kode program, seperti import java.util.Scanner. Berikut adalah contoh proses
import di dalam kode:
Kode di atas digunakan untuk mengimport Scanner class yang ada di package
java.util.
▪ User-defined package (package buatan kita sendiri)
Sesuai dengan namanya package ini akan kita buat sendiri. Mari kita coba untuk
membuat package sendiri dengan intellijIDEA.
Silahkan buka intellijIDEA dan buat proyek baru nama dan location directory
bebas sesuai dengan kebutuhan kalian. Klik bagian Advanced Settings, di sana terdapat
GroupId yang dimana ini adalah package default yang akan kita buat yaitu
org.example. Kalau kita ingin mengubah nama package langsung saja kita ubah dan
perlu diperhatikan untuk pembuatan package harus menggunakan tanda titik “.” untuk
pemisah, tidak bisa menggunakan spasi. Contoh di sini kita ubah menjadi com.main.
Setelah itu klik create, ketika kita lihat pada tab bagian kiri, kita akan melihat
seperti ini:
Untuk menambah file baru di dalam package file.lain, klik kanan pada package
yang bersangkutan lalu pilih New -> Java class, setelah itu input nama file yang akan
dibuat contoh kita buat class Tes, lalu tekan enter:
Untuk cara pakai class Tes yang sudah kita buat di dalam package file.lain, kita
coba untuk membuat sebuah method sederhana di dalam class Tes. Contohnya kita
buat sebuah method cekInfo() dengan return type String yang berisi seperti ini:
package com.file.lain;
Lalu tinggal kita buat sebuah object dari class Tes seperti berikut:
package com.main;
import com.file.lain.Tes;
Catatan tambahan untuk keywords import, ketika kita hanya ingin import 1
class saja contoh class Scanner maka kita bisa langsung menulis seperti ini import
java.util.Scanner;. Sedangkan jika kita ingin mengimport banyak class maka harus
menggunakan bintang “*” untuk mewakili semua class. Contoh kita ingin import semua
class yang terdapat pada package java.util, maka kita cukup ketikakkan code seperti
ini import java.util.*;
● Polymorphism
Polymorphism secara bahasa memiliki arti “banyak bentuk” atau “bermacam-
macam”. Dalam konsep pemrograman, polymorphism sebuah teknik menggunakan fungsi
atau atribut tertentu dari suatu parant class untuk diimplementasikan oleh child class baik
secara default ataupun dimodifikasi sesuai dengan kebutuhan pada masing-masing class.
Polymorphism terjadi ketika kita memiliki banyak class yang memiliki relasi satu sama
lain menggunakan inheritance. Jika sebelumnya kita sudah membuat sebuah class Hero
yang memiliki child class (extends) yaitu Superman, Deadpool, dan Spiderman, dalam
artinya class Hero memiliki banyak bentuk yaitu bisa menjadi superman, deadpool,
superman atau hero yang lain. Contoh lain ialah sebuah kata “hewan”, lalu muncul di
benak kita yaitu kucing, anjing, burung, buaya, dan lain-lain. Hal ini mengartikan banyak
bentuk yaitu hewan bisa berupa kucing, bisa juga berupa anjing, bisa berupa burung
ataupun buaya.
Contoh sederhana dari polymorphism adalah bagaimana seekor hewan bersuara. Kita
tahu bahwa setiap hewan pasti bersuara, baik secara jelas ataupun tidak, namun pada
intinya hewan pasti bersuara. Jika kita umpakan bahwa hewan bersuara sebagai method,
dan method ini akan kita implementasikan pada semua hewan. Kucing jika
mengimplementasikan method ini maka akan bersuara “Meow”, anjing
mengimplementasikan method ini akan bersuara “Gug gug”, dan sapi
mengimplementasikan method ini akan besuara “Mooo”. Perbedaan dalam implementasi
inilah yang menjadi salah satu contoh penerapan Polymorphism.
Terdapat beberapa tipe Polymorphism yaitu:
public Hero(){
// kosong
}
method seperti di atas maka kita bisa membuat instance object dari class Hero seperti
ini tanpa mengalami error:
@Override
public void melindungi(){
System.out.println(getName() + " melindungi masyarakat bumi dari serangan monster");
}
}
Pada kode di atas kita membuat method attack() sebanyak 3 dengan jumlah parameter
yang berbeda. Maka kita bisa memanggil method ini pada class main dengan cara
sebagai berikut:
public class Main {
public static void main(String[] args) {
// pembuatan object disertai dengan 2 argumen
Superman superman = new Superman("Sutrino adit", 33);
superman = new Hero(); // Type Hero dan constructor dari Hero juga (parent class)
superman.melindungi(); // yang kedua
}
}
Jika kita coba jalankan programnya maka akan output seperti berikut:
Penjelasan:
- Dari kode Main class, kita membuat sebuah objek superman dengan tipe data Hero,
tetapi refernsi class adalah Superman.
- Pada saat pemanggilan method melindungi() dipanggil yang pertama, method yang
dieksekusi adalah method melindungi() yang ada di dalam class Superman.
- Setelah itu objek superman dibuat referensinya ke Hero yaitu kode superman =
new Hero().
- Pada pemanggilan method melindungi yang kedua, method yang dieksekusi
adalah method melindungi() yang berada di class Hero.
Hal ini juga disebut sebagai Virtual Method Invocation, disebut virtual karena antara
method yang dikenali oleh compiler dan method yang dijalankan oleh JVM berbeda.
Saat compile time, compiler akan mengenali method melindungi() yang akan
dipanggila adalah method melindungi() yang ada di class Hero, karena objek bertipe
Hero. Tetapi saat dijalankan (runtime), maka yang dijalankan oleh JVM adalah method
melindungi() yang ada di class Superman. Tipe data sebelah kiri atau sebelum variabel
juga dapat berupa interface (materi ada di akhir modul). Secara kode akan tampak
seperti ini:
Interface namaObjek = new classYangDiimplement();
● Object Casting
Sebelum masuk ke object casting kita harus pelajari terlebih dahulu tentang type
casting di java, yaitu mengubah tipe data ke tipe data yang lain. Di java juga terdapat dua
macam tipe casting yaitu:
▪ Widening casting (otomatis) – menkonversi tipe data yang lebih kecil ke yang lebih
besar
byte -> short -> char -> int -> long -> float -> double
Contoh:
public class Main {
public static void main(String[] args) {
int myInt = 9;
double myDouble = myInt; // Otomatis dikonversi ke double dari int
System.out.println(myInt); // Outputs 9
System.out.println(myDouble); // Outputs 9.0
}
}
▪ Narrowing casting (manual) – menkonversi tipe data yang lebih besar ke yang lebih
kecil
double -> float -> long -> int -> char -> short -> byte
Contoh:
public class Main {
public static void main(String[] args) {
Pada kode di atas, kita mengumpulkan beberapa child class ke dalam satu variabel
yang sama dengan tipe data parent class. Data ke-1 berisi objek Spiderman, data ke-2
berisi objek Superman, data ke-3 berisi objek Deadpool yang ketiganya merupakan
turunan dari class Hero. Kemudian kita memanggil method melindungi() dengan
menggunakan looping foreach, hal ini tidak menimbulkan error karena semua objek yang
tersimpan di array Hero memiliki method melindungi().
Untuk menggunakan looping for biasa:
for (int i = 0; i < heros.length; i++){
heros[i].melindungi();
}
● Abstraction
Abstract adalah suatu ide yang bukan objek materi (tidak memiliki bentuk fisik), lawan
kata abstract adalah concrete. Dalam konteks PBO, abstraction adalah konsep yang
memungkinkan kita untuk menyembunyikan kompleksitas dari sebuah objek dan hanya
menampilkan fungsionalitas yang penting dalam sebuah interaksi.
● Abstract Class
Abstract class adalah kelas yang dideklarasikan dengan keyword abstract, dan
sifatnya tidak dapat dibuat menjadi suatu objek (tidak dapat diinstansiasi) karena
bentuknya memang belum jelas (abstract). Abstract class biasanya digunakan untuk
generalisasi objek yang sangat umum, misalnya Hewan, Kendaraan, Database, dan lain
sebagainya.
Abstract class berguna untuk diturunkan / diwarisi kelas lainnya menggunakan
keyword extends, penggunaan utamanya adalah untuk polimorfisme (Polymorphism)
yang sudah dipelajari di atas. Dalam suatu abstract class dapat berisi atribut (variabel),
abstract method maupun concrete method.
Analogi mengenai class abstract ialah seperti ini, ketika mendengar sebuah kata “hero”
tentu yang dipikirkan pertama kali adalah “hero apa yang dimaksud? assasin, marksmen,
mage, tank atau apa?” apapun itu, semuanya adalah hero. Kita tahu bahwa semua hero
pasti bisa attack, tapi bagaimana kalau “hero menyerang” hal ini akan menimbulkan
sebuah pertanyaan hero apa yang dimaksud. Inilah yang disebut sebagai abtraksi, kata
“hero” sendiri masih bersifat abstract. Untuk cara membuat sebuah class abstract, seperti
membuat sebuah class biasa:
Setelah class hero dibuat oleh intellijIDEA, bisa tambahkan kata kunci abstract
setelah modifier class, seperti berikut:
Ketika kita sudah membuat sebuah class abstract, maka class tersebut tidak bisa
dibuat sebuah instance objek. Eror berikut akan muncul ketika kita mencoba untuk
membuat sebuah instance objek dari sebuah class yang bersifat abtrak.
Sebuah class yang berbentuk abstrak hanya bisa kita pakai ketika memiliki sebuah
inheritance dari class tersebut, contoh kita buat sebuah class Assasin.java yang akan
menjadi child class dari Hero.
Maka sekarang kita bisa membuat sebuah objek dengan tipe Hero, tetapi
menggunakan reference dari Assasin.
Sebuah class abstract dibuat untuk mengumpulkan sebuah method umum atau
sebuah ide suatu class berperilaku. Sebagai contoh jika kita membuat sebuah class hero
Assasin, Mage, Tank dan secara umum hero-hero tersebut bisa menyerang, kembali ke
base, menggunakan item dengan cara menyerang dan menggunakan item yang berbeda-
beda, maka dari itu bisa dikumpulkan dalam satu class yang bernama Hero tetapi class
tersebut tidak bisa dipakai secara langsung melainkan dipakai melalui child class.
● Abstract Method
Abstract Method adalah method yang bersifat abstrak yang ditandai dengan
penambahan keyword abstract pada deklarasinya serta tidak memiliki implementasi
body / isi. Deklarasi abstract method langsung diakhiri tanda titik koma (;), tanpa tanda
kurung kurawal ({...}). Semua abstract method yang ada akan dipaksakan untuk ada di
kelas turunannya (harus di-override).
Abstract method dipakai ketika sebuah class memiliki method yang sama tetapi
perilakunya berbeda. Seperti hero assasin dan hero tank pasti bisa menyerang, tetapi cara
menyerang hero assasin dan hero tank berbeda. Maka dari itu diperlukan sebuah method
di parent class tetapi method itu diisi kosong yang akan disesuaikan dengan masing-
masing hero nantinya. Berikut adalah cara membuat sebuah abstract method:
}
}
Terbukti, akan muncul error “Cannot instantiate the type Hewan” dikarenakan kelas Hero
adalah abstract class.
Kita akan membuat kelas lain, Tank pada file Tank.java dan Marksman pada file
Marksman.java yang masing-masing akan meng-extends kelas Hero.
Perhatikan apa yang terjadi saat awal kita meng-extends class Hero, akan muncul error
merah pada kode yang dibuat:
Dengan error “The type Tank must implement the inherited abstract method
Hero.attack()”.
Apa yang terjadi? kelas Tank harus mengimplementasikan abstract method yang ada pada
abstract class Hero yaitu method attack. Mari kita coba perbaiki, caranya bisa diketik atau
secara otomatis di VS Code kalian bisa meng-klik Quick Fix (Ctrl+.) seperti di atas atau di
IDE lain cari kemudian klik add unimplemented method. IDE akan otomatis
megenerate.
Perhatikan anotasi @Override sebelum method attack, hal ini diperlukan karena class
Tank merupakan turunan dari class Hero yang juga memiliki method attack meskipun
method tersebut bersifat abstract.
Akan kita isi method attack di atas dengan skill yang dimiliki mage.
public class Tank extends Hero{
@Override
public void attack() {
System.out.println("Mage menyerang dengan menggunakan armor
shield!");
}
}
Lakukan yang sama pada kelas Marksman dengan skillnya.
public class Marksman extends Hero{
@Override
public void attack() {
System.out.println("Marksman menyerang dengan 5000 damage!");
}
}
Kemudian kita bisa membuat objek dari kelas Tank dan Marksman.
public class Main {
public static void main(String[] args) {
tank.attack();
marksman.attack();
}
}
Coba jalankan kode tersebut apa yang terjadi? Kalau benar, akan muncul output seperti
berikut sesuai urutan pemanggilan method pada objek.
Apa yang dapat kita simpulkan? Tank dan Marksman sama-sama Hero dan keduanya dapat
melakukan attack, tetapi tentu saja attack dari keduanya berbeda.
● Interface
Masih berkaitan dengan abstraction. Interface adalah satu cara untuk mencapai
abstraction secara menyeluruh (total abstraction). Namun, interface bukan class,
meskipun terlihat sama. Interface digunakan untuk mendefinisikan suatu sifat-sifat
(behaviours, berupa method) suatu class.
Persamaannya dengan abstract class adalah keduanya tidak dapat diinstansiasi menjadi
objek, lantas apa perbedaannya?
Bisa memililki method static dan final. Method tidak boleh bersifat static dan
final.
Access modifier perlu ditulis sendiri. Secara implisit semua method adalah
public abstract.
Bisa memiliki constants dan instance Hanya dapat memiliki constants karena
variables. secara implisit semua variable dalam
interface adalah public static
final.
Bisa membuat properti atau variabel Hanya bisa buat konstanta saja
Secara sederhana interface digunakan untuk memaksa sebuah class untuk memakai
sebuah method yang sebelumnya sudah ditentukan. Misalnya, burung adalah hewan dan
burung bisa terbang, pesawat juga bisa terbang, lantas apakah pesawat adalah hewan?
tentu bukan, keduanya memiliki sifat / behaviour sama-sama bisa terbang, kita dapat
membuat interface Flyable untuk kedua objek tersebut. Penggunaan interface tidak selalu
seperti di atas, selebihnya tentunya tergantung use-case.
Contoh pendeklarasian interface:
// bisa diisi dengan variabel
interface Flyable {
// secara default sudah public
void terbang();
}
Cara pembuatan sebuah interface sama dengan cara membuat class biasa, seperti berikut:
Dalam kasus ini kita akan membuat sebuah kemampuan untuk terbang pada class
Hewan dan juga class Pesawat. Karena kedua class tersebut tidak bisa berasal dari
parentclass yang sama, maka kita tidak bisa untuk membuat method abstract, yang bisa
kita lakukan adalah membuat sebuah Interface yang nantinya bisa digunakan untuk
memaksa class Burung dan class Pesawat harus mengimplementasikan sebuah method
untuk terbang.
Setelah kita membuat sebuah interface Flyable sebelumnya, kita bisa membuat sebuah
method yang dibutuhkan ke dalam interface. Dalam kasus ini kita membutuhkan method
terbang, maka bisa kita isi InterfaceI Flyable menjadi seperti berikut:
public interface Flyable {
void terbang();
}
Untuk cara memakai sebuah Interface yang sudah kita buat, bisa gunakan sebuah kata
kunci implements pada class yang dituju. Contohnya interface Flyable akan
diimplementasikan ke class Pesawat dan Burung, maka kode dari kedua class akan
menjadi seperti ini:
File Burung.java
File Pesawat.java
Ketika melakukan implements dari suatu Interface ke dalam sebuah class, akan langsung
muncul garis merah yang menandakan terjadi sebuah error dengan pesan “The type
Pesawat must implement the inherited abstract method Flyable.terbang()” yang artinya kita
melakukan sebuah implementasi dari sebuah interface tetapi kita tidak melakukan
override terhadap method yang ada di dalam Interface yang bersangkutan. Maka solusinya
kita bisa arahkan cursor ke kode yang error, lalu klik Quick fix.
Setelah pembahasan ini mungkin akan ada sebuah pertanyaan yang muncul yaitu “Apa
perbedaan spesifik antara interface dan sebuah class abstract dalam java?”. Jawabannya
ialah Interface digunakan ketika kita ingin mengimplementasikan sebuah method tertentu
yang digunakan dengan inheritance tidak memungkinkan karena berbeda parent class dan
juga Interface digunakan dalam sebuah kasus kita ingin melakukan extends lebih dari 1
parent class yang dimana sebuah extends dalam java hanya bisa satu parent, maka dari itu
dibuatlah sebuah Interface.
● Is-a relation & Operator instanceof
Di Java kita bisa melihat suatu objek adalah suatu instance dari class apa, dengan
operator instanceof yang akan mengembalikan nilai boolean. Menggunakan
potongan kode sebelumnya yaitu Hero, Marksman, dan Tank. Silahkan coba code berikut:
Bahkan sebelum kalian run IDE kalian akan menunjukkan kepada kalian bahwa kode
tersebut akan error. Jika tetap kalian run, compiler akan menampilkan error “Incompatible
conditional operand types Tank and Marksman”. Ini dikarenakan Tank meskipun sebuah
Hero tetapi ia bukanlah Marksman.
Maksud dari is-a adalah untuk mengecek apakah sebuah object merupakah inheritance
dari sebuah class tertentu. Pada kode di atas kita mengecek apakah tank inheritance dari
class Object, Hero, dan Tank. Ketika kode tersebut mengembalikan sebuah nilai true, itu
aritnya objek yang dibuat memiliki hubungan dengan class yang bersangkutan.
● Has-a relation
Dalam PBO, konsep "has-a" relation atau aggregasi (aggregation) mengacu pada
hubungan antara dua kelas, di mana suatu objek dari kelas A memiliki satu atau lebih objek
dari kelas B sebagai member atau atribut dari dirinya.
Misalnya, Kelas Praktikum memiliki (banyak) Mahasiswa. Jika digambarkan dalam
class diagram adalah sebagai berikut:
KelasPraktikum.java
public class KelasPraktikum {
String name;
Mahasiswa mahasiswa;
Main.java
public class Main {
public static void main(String[] args) {
Mahasiswa mahasiswa = new Mahasiswa("202210370311203", "Sutrisno Adit
Pratama");
KelasPraktikum kelasPraktikum = new KelasPraktikum("PBO C",
mahasiswa);
Output program:
● Relasi lain
Sebenarnya masih ada relasi lain dalam class diagram, dengan pengantar 2
relasi di atas, mungkin tanpa disadari saat Anda mengerjakan projek Java, Anda sudah
mengimplementasikan relasi yang lain. Untuk memahami teori relasi yang lain, silakan
Anda berselancar di internet.
CODELAB
Silahkan pull kode yang ada di github berikut di sini. Silahkan perbaiki kode tersebut
dengan ketentuan seperti ini:
- Kode pada file Main.java tidak perlu ada yang diubah ataupun diperbaiki
- Pada file Kendaraan.java silahkan buat method abstract bernama Stop() dan Brake()
- Di interface ShootAble dan FlyAble silahkan perbaiki kode interface dan method-nya,
seharusnya seperti apa
- Di dalam class Motor, harap teliti satu-satu method apa yang masih kurang dan harus ada?
- Pada file Pesawat.java silahkan perbaiki method yang seharusnya dilakukan override dari
parent
- Terakhir di Tank.java, silahkan perbaiki kode bagian apa yang kurang dan menyebabkan error
Jika sudah selesai dengan semua perbaikan berarti pengerjaan codelab sudah selesai
TUGAS
Melanjutkan tugas pada modul 3 sebelumnya, pada tugas modul 4 ini silahkan
kembangkan program menjadi dengan ketentuan berikut:
- buat package com.main dan taruh file LibrarySystem.java ke dalamnya
- buat package books yang dimana di dalamnya terdapat class Book, HistoryBook, StoryBook,
dan TextBook
- buat package data dan di dalamnya terdapat class Admin, Student, dan User
- terakhir buat package util dan di dalamnya buat sebuah interface iMenu.java
- Interface iMenu.java berisi sebuah method abstract menu() dan lakukan implements pada
class Student dan Admin. Sehingga admin dan student memiliki opsi menu di class masing-
masing dengan hasil override dari interface iMenu.
- Silahkan buat sebuah method yang melakukan overloading dan terapkan pada code yang
sedang dibuat, bebas method apa saja (opsional).
- Jika penyimpanan buku pada kode di tugas modul 2 menggunakan sebuah array
multidimensi, harap diganti dengan array satu dimensi dengan cara menggunakan teknik
polymorphism dengan tipe class Book, sehingga semua class HistoryBook, StoryBook, dan
TextBook bisa disimpan.
- Method displayBooks() pada class Student diganti menjadi choiceBook(), yang di mana
nanti method ini tidak hanya digunakan untuk menampilkan buku tetapi juga bisa memilih
buku yang ingin dipinjam.
Bentuk diagram class akan menjadi seperti berikut:
RUBRIK PENILAIAN
Codelab 20
Tugas 30
Tugas opsional 10
Pemahaman 40
TOTAL 100
Selamat Mengerjakan
Tetap Semangat