Pemrograman Berorientasi Objek (PBO) merupakan pondasi penting dalam pengembangan perangkat lunak modern. Bagi siswa kelas 12 yang mendalami ilmu komputer, pemahaman yang kuat terhadap konsep-konsep PBO sangat krusial untuk menghadapi berbagai tantangan di dunia pemrograman. Semester 1 kelas 12 biasanya menjadi titik krusial dalam penguatan konsep-konsep dasar PBO seperti encapsulation, inheritance, dan polymorphism, serta penerapannya dalam bahasa pemrograman seperti Java atau C++.
Artikel ini akan menyajikan serangkaian contoh soal PBO kelas 12 semester 1 yang mencakup berbagai topik fundamental, lengkap dengan pembahasan mendalam dan jawaban yang terstruktur. Tujuannya adalah untuk membantu siswa tidak hanya menghafal solusi, tetapi juga memahami logika di balik setiap soal, sehingga mampu mengaplikasikannya dalam skenario yang berbeda.

Sebelum menyelami contoh soal, mari kita ingat kembali mengapa PBO begitu penting:
Berikut adalah beberapa contoh soal yang mewakili materi PBO kelas 12 semester 1, beserta penjelasan rinci untuk setiap soal.
>
Soal 1: Konsep Encapsulation dan Constructor
Sebuah kelas Buku dirancang untuk merepresentasikan sebuah buku. Kelas ini memiliki atribut judul (String) dan penulis (String). Buatlah kelas Buku dengan menerapkan konsep encapsulation, di mana atribut judul dan penulis bersifat private. Sediakan constructor untuk menginisialisasi kedua atribut tersebut, serta metode getter untuk mengakses nilainya.
Jawaban dan Pembahasan:
Dalam PBO, encapsulation adalah teknik membungkus data (atribut) dan metode yang beroperasi pada data tersebut ke dalam satu unit tunggal, yaitu kelas. Atribut yang bersifat private berarti hanya dapat diakses dari dalam kelas itu sendiri. Untuk mengakses atau memodifikasi data ini dari luar kelas, kita perlu menyediakan metode publik yang disebut getter (untuk mengakses) dan setter (untuk memodifikasi, meskipun dalam soal ini hanya diminta getter).
Constructor adalah metode khusus yang dipanggil saat sebuah objek dari kelas dibuat. Constructor biasanya digunakan untuk menginisialisasi nilai awal atribut objek. Nama constructor harus sama persis dengan nama kelasnya dan tidak memiliki nilai kembalian (bahkan void).
Berikut adalah implementasi kelas Buku:
public class Buku
private String judul;
private String penulis;
// Constructor untuk menginisialisasi judul dan penulis
public Buku(String judul, String penulis)
this.judul = judul; // 'this.judul' merujuk pada atribut kelas, 'judul' merujuk pada parameter constructor
this.penulis = penulis; // 'this.penulis' merujuk pada atribut kelas, 'penulis' merujuk pada parameter constructor
// Getter untuk atribut judul
public String getJudul()
return judul;
// Getter untuk atribut penulis
public String getPenulis()
return penulis;
// Contoh penggunaan kelas Buku dalam main method (opsional, untuk demonstrasi)
public static void main(String args)
Buku buku1 = new Buku("Laskar Pelangi", "Andrea Hirata");
Buku buku2 = new Buku("Bumi Manusia", "Pramoedya Ananta Toer");
System.out.println(" " + buku1.getJudul() + ", Penulis: " + buku1.getPenulis());
System.out.println(" " + buku2.getJudul() + ", Penulis: " + buku2.getPenulis());
Penjelasan Kode:
private String judul; dan private String penulis;: Mendeklarasikan atribut judul dan penulis sebagai private. Ini memastikan bahwa kedua atribut ini tidak dapat diakses secara langsung dari luar kelas Buku.public Buku(String judul, String penulis): Ini adalah constructor kelas Buku. Ketika kita membuat objek Buku menggunakan new Buku("Judul Buku", "Nama Penulis"), constructor ini akan dieksekusi.this.judul = judul; dan this.penulis = penulis;: Di dalam constructor, this digunakan untuk membedakan antara atribut kelas (this.judul) dan parameter constructor (judul). Ini menginisialisasi atribut judul dan penulis objek dengan nilai yang diberikan saat objek dibuat.public String getJudul() dan public String getPenulis(): Ini adalah metode getter. Metode ini bersifat publik, sehingga dapat dipanggil dari luar kelas Buku. Mereka mengembalikan nilai dari atribut judul dan penulis masing-masing.main method: Bagian ini menunjukkan cara membuat objek Buku dan menggunakan metode getter untuk menampilkan informasi buku.>
Soal 2: Konsep Inheritance dan Superclass/Subclass
Buatlah sebuah kelas Kendaraan sebagai superclass dengan atribut merk (String) dan metode tampilkanInfo() yang mencetak informasi dasar kendaraan. Kemudian, buatlah kelas Mobil yang mewarisi dari kelas Kendaraan. Kelas Mobil memiliki atribut tambahan jumlahPintu (int) dan meng-override metode tampilkanInfo() untuk menyertakan informasi jumlah pintu.
Jawaban dan Pembahasan:
Inheritance (pewarisan) adalah salah satu pilar PBO yang memungkinkan sebuah kelas (subclass/kelas turunan) untuk mewarisi atribut dan metode dari kelas lain (superclass/kelas induk). Ini mendorong penggunaan kembali kode dan menciptakan hierarki kelas. Kata kunci extends digunakan dalam Java untuk menyatakan hubungan pewarisan.
Overriding metode terjadi ketika subclass menyediakan implementasi spesifik untuk metode yang sudah didefinisikan di superclass-nya. Metode yang di-override harus memiliki nama, tipe kembalian, dan parameter yang sama dengan metode di superclass. Kata kunci super digunakan untuk memanggil metode atau konstruktor dari superclass.
Berikut adalah implementasi kelas Kendaraan dan Mobil:
Kelas Superclass: Kendaraan.java
public class Kendaraan
protected String merk; // Menggunakan 'protected' agar bisa diakses subclass
public Kendaraan(String merk)
this.merk = merk;
public void tampilkanInfo()
System.out.println("Merk Kendaraan: " + merk);
Kelas Subclass: Mobil.java
public class Mobil extends Kendaraan // 'extends Kendaraan' menunjukkan pewarisan
private int jumlahPintu;
public Mobil(String merk, int jumlahPintu)
super(merk); // Memanggil constructor superclass (Kendaraan)
this.jumlahPintu = jumlahPintu;
// Override metode tampilkanInfo dari superclass
@Override // Anotasi opsional tapi direkomendasikan untuk menandakan overriding
public void tampilkanInfo()
super.tampilkanInfo(); // Memanggil metode tampilkanInfo() dari superclass
System.out.println("Jumlah Pintu: " + jumlahPintu);
// Contoh penggunaan dalam main method (opsional, untuk demonstrasi)
public static void main(String args)
Mobil mobil1 = new Mobil("Toyota Avanza", 4);
mobil1.tampilkanInfo();
System.out.println("n---");
// Contoh dengan superclass yang juga bisa diinstansiasi (jika diperlukan)
Kendaraan kendaraanUmum = new Kendaraan("Sepeda Motor");
kendaraanUmum.tampilkanInfo();
Penjelasan Kode:
protected String merk;: Atribut merk dideklarasikan sebagai protected. Ini berarti atribut ini dapat diakses oleh kelas Mobil (subclass) tetapi tidak oleh kelas lain di luar package.public Kendaraan(String merk): Constructor untuk kelas Kendaraan.public void tampilkanInfo() di Kendaraan: Metode dasar untuk menampilkan informasi kendaraan.public class Mobil extends Kendaraan: Mendefinisikan kelas Mobil sebagai subclass dari Kendaraan.private int jumlahPintu;: Atribut spesifik untuk kelas Mobil.super(merk);: Di dalam constructor Mobil, super(merk) memanggil constructor dari superclass (Kendaraan) dan meneruskan nilai merk ke sana. Ini adalah langkah penting untuk memastikan bahwa atribut yang diwarisi juga diinisialisasi.@Override public void tampilkanInfo(): Mendefinisikan ulang metode tampilkanInfo() di kelas Mobil.super.tampilkanInfo();: Di dalam metode tampilkanInfo() yang di-override, baris ini memanggil implementasi tampilkanInfo() dari superclass (Kendaraan) terlebih dahulu. Ini memastikan bahwa informasi merk tetap ditampilkan.System.out.println("Jumlah Pintu: " + jumlahPintu);: Menambahkan informasi spesifik Mobil ke output.>
Soal 3: Konsep Polymorphism (Compile-time dan Run-time)
Jelaskan perbedaan antara polymorphism compile-time (overloading) dan polymorphism run-time (overriding) dengan contoh kode sederhana menggunakan bahasa pemrograman yang Anda kuasai (misalnya Java).
Jawaban dan Pembahasan:
Polymorphism (banyak bentuk) adalah kemampuan untuk memperlakukan objek dari kelas yang berbeda dengan cara yang sama. Ini adalah salah satu pilar PBO yang paling kuat. Dalam PBO, polymorphism terbagi menjadi dua jenis utama:
Polymorphism Compile-time (Static Polymorphism / Method Overloading):
Polymorphism Run-time (Dynamic Polymorphism / Method Overriding):
Contoh Kode (Java):
Kelas Kalkulator (untuk Polymorphism Compile-time / Overloading):
public class Kalkulator
// Metode overloading: nama sama, parameter berbeda
public int tambah(int a, int b)
System.out.println("Memanggil tambah(int, int)");
return a + b;
public double tambah(double a, double b)
System.out.println("Memanggil tambah(double, double)");
return a + b;
public String tambah(String s1, String s2)
System.out.println("Memanggil tambah(String, String)");
return s1 + s2;
public static void main(String args)
Kalkulator calc = new Kalkulator();
// Kompiler akan memilih metode tambah yang sesuai
int hasilInt = calc.tambah(5, 10); // Memanggil tambah(int, int)
double hasilDouble = calc.tambah(5.5, 10.2); // Memanggil tambah(double, double)
String hasilString = calc.tambah("Halo ", "Dunia"); // Memanggil tambah(String, String)
System.out.println("Hasil int: " + hasilInt);
System.out.println("Hasil double: " + hasilDouble);
System.out.println("Hasil string: " + hasilString);
Kelas Hewan dan Anjing (untuk Polymorphism Run-time / Overriding):
// Superclass
class Hewan
public void bersuara()
System.out.println("Hewan mengeluarkan suara");
// Subclass
class Anjing extends Hewan
@Override
public void bersuara()
System.out.println("Anjing menggonggong: Guk Guk!");
// Subclass lain
class Kucing extends Hewan
@Override
public void bersuara()
System.out.println("Kucing mengeong: Meow!");
// Kelas utama untuk demonstrasi
public class DemoPolymorphism
public static void main(String args)
Hewan hewan1; // Deklarasi variabel superclass
hewan1 = new Anjing(); // Menugaskan objek Anjing ke variabel Hewan
hewan1.bersuara(); // Memanggil metode bersuara() dari objek Anjing
hewan1 = new Kucing(); // Menugaskan objek Kucing ke variabel Hewan
hewan1.bersuara(); // Memanggil metode bersuara() dari objek Kucing
// Contoh lain dengan array objek
Hewan daftarHewan = new Hewan;
daftarHewan = new Anjing();
daftarHewan = new Kucing();
System.out.println("n--- Melalui array ---");
for (Hewan h : daftarHewan)
h.bersuara(); // Determinasinya pada saat run-time
Penjelasan Kode:
Kalkulator, ada tiga metode tambah. Kompiler mengenali mana yang harus dipanggil berdasarkan tipe dan jumlah argumen yang diberikan pada pemanggilan calc.tambah(...).Hewan memiliki metode bersuara().Anjing dan Kucing meng-override metode bersuara() untuk memberikan implementasi spesifik.DemoPolymorphism, variabel hewan1 bertipe Hewan. Namun, ketika kita menugaskan objek Anjing atau Kucing ke dalamnya, metode bersuara() yang dipanggil adalah metode yang ada di objek sebenarnya (objek Anjing atau Kucing). Inilah yang disebut dynamic method dispatch.for pada array daftarHewan juga menunjukkan *run-time polymorphism; setiap elemen array akan memanggil versibersuara()` dari kelas objek yang sebenarnya.>
Soal 4: Penggunaan Abstract Class dan Abstract Method
Buatlah sebuah abstract class bernama Bentuk dengan satu abstract method bernama hitungLuas(). Kemudian, buatlah dua kelas turunan, yaitu Persegi dan Lingkaran, yang mengimplementasikan abstract method hitungLuas() untuk menghitung luas bangun masing-masing.
Jawaban dan Pembahasan:
Abstract class adalah kelas yang tidak dapat diinstansiasi secara langsung. Mereka biasanya digunakan sebagai blueprint untuk kelas-kelas turunan. Abstract method adalah metode yang dideklarasikan tanpa implementasi di dalam abstract class. Kelas turunan yang mewarisi abstract class wajib mengimplementasikan semua abstract method yang diwarisi, kecuali kelas turunan itu sendiri juga dijadikan abstract.
Penggunaan abstract class dan abstract method sangat berguna ketika kita ingin mendefinisikan sebuah antarmuka umum untuk sekumpulan kelas terkait, tetapi tidak dapat memberikan implementasi default yang bermakna untuk metode tertentu.
Abstract Class: Bentuk.java
// Abstract class
public abstract class Bentuk
// Abstract method: tidak ada implementasi, hanya deklarasi
public abstract double hitungLuas();
// Metode non-abstract (opsional)
public void deskripsi()
System.out.println("Ini adalah sebuah bentuk.");
Kelas Turunan: Persegi.java
public class Persegi extends Bentuk
private double sisi;
public Persegi(double sisi)
this.sisi = sisi;
// Implementasi abstract method hitungLuas()
@Override
public double hitungLuas()
return sisi * sisi;
// Contoh penggunaan dalam main method (opsional, untuk demonstrasi)
public static void main(String args)
Persegi persegi1 = new Persegi(5.0);
System.out.println("Luas Persegi: " + persegi1.hitungLuas());
persegi1.deskripsi(); // Memanggil metode non-abstract dari abstract class
Kelas Turunan: Lingkaran.java
public class Lingkaran extends Bentuk
private double radius;
private static final double PI = 3.14159; // Konstanta PI
public Lingkaran(double radius)
this.radius = radius;
// Implementasi abstract method hitungLuas()
@Override
public double hitungLuas()
return PI * radius * radius;
// Contoh penggunaan dalam main method (opsional, untuk demonstrasi)
public static void main(String args)
Lingkaran lingkaran1 = new Lingkaran(7.0);
System.out.println("Luas Lingkaran: " + lingkaran1.hitungLuas());
lingkaran1.deskripsi(); // Memanggil metode non-abstract dari abstract class
Demo Polimorfisme dengan Abstract Class (Opsional):
public class DemoBentuk
public static void main(String args)
// Tidak bisa membuat objek langsung dari abstract class:
// Bentuk bentukUmum = new Bentuk(); // Ini akan error!
// Namun, bisa menggunakan abstract class sebagai tipe referensi
Bentuk persegi = new Persegi(4.0);
Bentuk lingkaran = new Lingkaran(3.0);
System.out.println("Luas bentuk 1: " + persegi.hitungLuas());
System.out.println("Luas bentuk 2: " + lingkaran.hitungLuas());
// Memanggil metode non-abstract
persegi.deskripsi();
lingkaran.deskripsi();
Penjelasan Kode:
public abstract class Bentuk: Mendeklarasikan Bentuk sebagai abstract class.public abstract double hitungLuas();: Mendeklarasikan hitungLuas() sebagai abstract method. Tidak ada kurung kurawal atau badan metode.public void deskripsi(): Ini adalah metode biasa (non-abstract) yang bisa memiliki implementasi di dalam abstract class.public class Persegi extends Bentuk dan public class Lingkaran extends Bentuk: Kedua kelas ini mewarisi dari Bentuk.@Override public double hitungLuas(): Kedua kelas turunan ini wajib mengimplementasikan metode hitungLuas() dengan logika perhitungan luas masing-masing. Jika tidak, mereka harus dideklarasikan sebagai abstract class.DemoBentuk: Menunjukkan bagaimana abstract class dapat digunakan sebagai tipe referensi untuk objek dari kelas turunannya, dan bagaimana polymorphism bekerja di sini.>
Memahami konsep-konsep inti PBO seperti encapsulation, inheritance, polymorphism, serta penggunaan abstract class dan interface adalah kunci keberhasilan dalam mata pelajaran ini. Contoh soal di atas mencakup beberapa topik fundamental yang sering muncul dalam ujian atau tugas.
Penting untuk diingat bahwa setiap soal adalah representasi dari sebuah konsep. Oleh karena itu, saat mempelajari, fokuslah pada mengapa solusi tersebut bekerja, bukan hanya apa solusinya. Latihan secara konsisten dengan berbagai variasi soal akan memperdalam pemahaman Anda dan membekali Anda untuk menghadapi tantangan pemrograman yang lebih kompleks di masa depan. Selamat belajar!
>