Lewati ke konten utama

OOP di Java: Kelas, Objek, Enkapsulasi, Pewarisan, dan Abstraksi

Pelajari Pemrograman Berorientasi Objek di Java dengan contoh praktis. Kuasai kelas, objek, pewarisan, enkapsulasi, dan kelas abstrak menggunakan sistem menu restoran.
Diperbarui 28 Sep 2026  · 15 mnt Baca

Jelajahi bersama AI

ChatGPTClaudePerplexity

Java secara konsisten menjadi salah satu dari tiga bahasa paling populer di dunia. Adopsinya di bidang seperti pengembangan perangkat lunak enterprise, aplikasi seluler Android, dan aplikasi web skala besar tidak tertandingi. Sistem tipe yang kuat, ekosistem yang luas, dan kemampuan “tulis sekali, jalankan di mana saja” menjadikannya sangat menarik untuk membangun sistem yang tangguh dan skalabel. Dalam artikel ini, kita akan mengeksplorasi bagaimana fitur pemrograman berorientasi objek Java memungkinkan pengembang memanfaatkan kemampuan ini secara efektif, sehingga mereka dapat membangun aplikasi yang mudah dipelihara dan dapat diskalakan melalui pengorganisasian dan pemakaian ulang kode yang tepat.

Catatan tentang Mengorganisir dan Menjalankan Kode Java

Sebelum kita mulai menulis kode, mari lakukan sedikit penyiapan.

Seperti halnya sintaksnya, Java memiliki aturan ketat tentang pengorganisasian kode.

Pertama, setiap kelas public harus berada di file tersendiri, dinamai persis seperti nama kelasnya tetapi dengan ekstensi .java. Jadi, jika saya ingin menulis kelas Laptop, nama filenya harus Laptop.java—peka huruf besar-kecil. Anda dapat memiliki kelas non-public dalam file yang sama, tetapi sebaiknya dipisah. Saya tahu kita sedikit melangkah ke depan—membahas pengorganisasian kelas bahkan sebelum menulisnya—tetapi memiliki gambaran kasar tentang di mana menempatkan sesuatu sejak awal adalah ide yang baik.

Semua proyek Java harus memiliki file Main.java dengan kelas Main. Di sinilah Anda menguji kelas-kelas Anda dengan membuat objek darinya.

Untuk menjalankan kode Java, kita akan menggunakan IntelliJ IDEA, IDE Java yang populer. Setelah memasang IntelliJ:

  1. Buat proyek Java baru (File > New > Project)
  2. Klik kanan folder src untuk membuat file Main.java dan tempelkan konten berikut:
public class Main {
   public static void main(String[] args) {
       // Create and tests objects here
      
   }
}

Setiap kali kita membahas kelas, kita menulis kode di file lain selain file Main.java. Namun jika kita membahas pembuatan dan pengujian objek, kita beralih ke Main.java.

Untuk menjalankan program, Anda dapat mengeklik tombol putar hijau di sebelah metode main:

Cuplikan layar jendela editor di IntelliJ IDEA untuk Java

Keluaran akan ditampilkan di jendela alat Run di bagian bawah.

Jika Anda benar-benar baru di Java, silakan lihat kursus Introduction to Java kami, yang membahas dasar-dasar tipe data Java dan alur kontrol sebelum melanjutkan.

Jika tidak, mari kita langsung masuk.

Kelas dan Objek di Java

Jadi, sebenarnya apa itu kelas?

Kelas adalah konstruksi pemrograman di Java untuk merepresentasikan konsep dunia nyata. Misalnya, perhatikan kelas MenuItem ini (buat sebuah file untuk menulis kelas ini di IDE Anda):

public class MenuItem {
   public String name;
   public double price;
}

Kelas memberi kita cetak biru atau templat untuk merepresentasikan berbagai item menu di restoran. Dengan mengubah dua atribut kelas, name, dan price, kita dapat membuat tak terhitung banyaknya objek menu seperti burger atau salad.

Jadi, untuk membuat kelas di Java, Anda memulai baris yang menjelaskan tingkat akses kelas (private, public, atau protected) diikuti oleh nama kelas. Segera setelah kurung kurawal, Anda uraikan atribut-atribut kelas Anda.

Namun bagaimana kita membuat objek yang termasuk dalam kelas ini? Java memungkinkannya melalui metode konstruktor:

public class MenuItem {
   public String name;
   public double price;
  
   // Constructor
   public MenuItem(String name, double price) {
       this.name = name;
       this.price = price;
   }
}

Konstruktor adalah metode khusus yang dipanggil ketika kita membuat objek baru dari sebuah kelas. Konstruktor menginisialisasi atribut objek dengan nilai yang kita berikan. Pada contoh di atas, konstruktor menerima parameter name dan price lalu menetapkannya ke field objek menggunakan kata kunci ‘this’ untuk merujuk pada instance objek di masa mendatang.

Sintaks konstruktor berbeda dari metode kelas lainnya karena tidak mengharuskan Anda menentukan tipe pengembalian. Selain itu, konstruktor harus memiliki nama yang sama dengan kelas, dan sebaiknya memiliki jumlah atribut yang sama dengan yang Anda deklarasikan setelah definisi kelas. Di atas, konstruktor membuat dua atribut karena kita mendeklarasikan dua setelah definisi kelas: name dan price.

Setelah Anda menulis kelas dan konstruktornya, Anda dapat membuat instance (objek) di metode main Anda:

public class Main {
   public static void main(String[] args) {
       // Create objects here
       MenuItem burger = new MenuItem("Burger", 3.5);
       MenuItem salad = new MenuItem("Salad", 2.5);
       System.out.println(burger.name + ", " + burger.price);
   }
}

Keluaran:

Burger, 3.5

Di atas, kita membuat dua objek MenuItem ke dalam variabel burger dan salad. Sesuai ketentuan di Java, tipe variabel harus dideklarasikan, yaitu MenuItem. Lalu, untuk membuat instance dari kelas kita, tuliskan kata kunci new diikuti dengan pemanggilan metode konstruktor.

Selain konstruktor, Anda dapat membuat metode biasa yang memberi perilaku pada kelas Anda. Misalnya, di bawah ini, kita menambahkan metode untuk menghitung total harga setelah pajak:

public class MenuItem {
   public String name;
   public double price;
  
   // Constructor
   public MenuItem(String name, double price) {
       this.name = name;
       this.price = price;
   }
  
   // Method to calculate price after tax
   public double getPriceAfterTax() {
       double taxRate = 0.08; // 8% tax rate
       return price + (price * taxRate);
   }
}

Sekarang kita dapat menghitung total harga termasuk pajak:

public class Main {
   public static void main(String[] args) {
       MenuItem burger = new MenuItem("Burger", 3.5);
       System.out.println("Price after tax: $" + burger.getPriceAfterTax());
   }
}

Keluaran:

Price after tax: $3.78

Enkapsulasi

Tujuan kelas adalah menyediakan cetak biru untuk membuat objek. Objek-objek ini kemudian akan digunakan oleh skrip atau program lain. Misalnya, objek MenuItem kita dapat digunakan oleh antarmuka pengguna yang menampilkan nama, harga, dan gambarnya di layar.

Untuk alasan ini, kita harus merancang kelas sedemikian rupa sehingga instance-nya hanya dapat digunakan sesuai yang kita maksudkan. Saat ini, kelas MenuItem kita sangat dasar dan rawan kesalahan. Seseorang mungkin membuat objek dengan atribut yang tidak masuk akal, seperti pai apel berharga negatif atau sandwich bernilai jutaan dolar:

// Inside Main.java
MenuItem applePie = new MenuItem("Apple Pie", -5.99);  // Negative price!
MenuItem sandwich = new MenuItem("Sandwich", 1000000); // Unreasonably expensive

System.out.println("Apple pie price: $" + applePie.price);
System.out.println("Sandwich price: $" + sandwich.price);

Jadi, langkah pertama setelah menulis sebuah kelas adalah melindungi atributnya dengan membatasi bagaimana atribut tersebut dibuat dan diakses. Untuk mulai, kita ingin hanya mengizinkan nilai positif untuk price dan menetapkan nilai maksimum untuk menghindari menampilkan item yang sangat mahal secara tidak sengaja.

Java memungkinkan kita mencapai ini dengan menggunakan metode setter:

public class MenuItem {
   private String name;
   private double price;
   private static final double MAX_PRICE = 100.0;
  
   public MenuItem(String name, double price) {
       this.name = name;
       setPrice(price);
   }
  
   public void setPrice(double price) {
       if (price < 0) {
           throw new IllegalArgumentException("Price cannot be negative");
       }
       if (price > MAX_PRICE) {
           throw new IllegalArgumentException("Price cannot exceed $" + MAX_PRICE);
       }
       this.price = price;
   }
  
}

Mari kita telaah apa yang baru pada blok kode di atas:

1. Kita menjadikan atribut private dengan menambahkan kata kunci private. Ini berarti atribut hanya dapat diakses di dalam kelas MenuItem. Enkapsulasi dimulai dari langkah krusial ini.

2. Kita menambahkan konstanta baru MAX_PRICE yang bersifat:

  • private (hanya dapat diakses dalam kelas)
  • static (dibagikan di seluruh instance)
  • final (tidak dapat diubah setelah inisialisasi)
  • ditetapkan $100.0 sebagai harga maksimum yang wajar

3. Kita menambahkan metode setPrice() yang:

  • Menerima parameter harga
  • Memvalidasi bahwa harga tidak negatif
  • Memvalidasi bahwa harga tidak melebihi MAX_PRICE
  • Melempar IllegalArgumentException dengan pesan deskriptif jika validasi gagal
  • Hanya menetapkan harga jika semua validasi lolos

4. Kita memodifikasi konstruktor untuk menggunakan setPrice() alih-alih langsung menetapkan harga. Ini memastikan validasi harga terjadi saat pembuatan objek.

Kita baru saja menerapkan salah satu pilar inti desain OOP yang baik — enkapsulasi. Paradigma ini menegakkan penyembunyian data dan akses terkontrol ke atribut objek, memastikan detail implementasi internal terlindungi dari campur tangan eksternal dan hanya dapat diubah melalui antarmuka yang terdefinisi dengan baik.

Mari kita pertegas dengan menerapkan enkapsulasi pada atribut name. Bayangkan kita memiliki kedai kopi yang hanya menyajikan latte, cappuccino, espresso, americano, dan mocha.

Jadi, nama item menu kita hanya bisa salah satu dari daftar ini. Berikut cara kita menegakkannya dalam kode:

// Rest of the class here
...
private static final String[] VALID_NAMES = {"latte", "cappuccino", "espresso", "americano", "mocha"};
private String name;
public void setName(String name) {
   String lowercaseName = name.toLowerCase();
   for (String validName : VALID_NAMES) {
       if (validName.equals(lowercaseName)) {
           this.name = name;
           return;
       }
   }
   throw new IllegalArgumentException("Invalid drink name. Must be one of: " + String.join(", ", VALID_NAMES));
}

Kode di atas menerapkan validasi nama untuk item menu di kedai kopi. Mari kita uraikan:

1. Pertama, didefinisikan array private static final VALID_NAMES yang berisi satu-satunya nama minuman yang diizinkan: latte, cappuccino, espresso, americano, dan mocha. Array ini bersifat:

  • private: hanya dapat diakses dalam kelas
  • static: dibagikan di seluruh instance
  • final: tidak dapat diubah setelah inisialisasi

2. Dideklarasikan field String name privat untuk menyimpan nama minuman

3. Metode setName() menerapkan logika validasi:

  • Menerima parameter String name
  • Mengonversinya ke huruf kecil agar perbandingan tidak peka huruf besar-kecil
  • Melakukan iterasi pada array VALID_NAMES
  • Jika ada kecocokan, menetapkan name dan keluar
  • Jika tidak ada kecocokan, melempar IllegalArgumentException dengan pesan deskriptif yang mencantumkan semua opsi valid

Berikut kelas lengkap sejauh ini:

public class MenuItem {
   private String name;
   private double price;

   private static final String[] VALID_NAMES = {"latte", "cappuccino", "espresso", "americano", "mocha"};

   private static final double MAX_PRICE = 100.0;

   public MenuItem(String name, double price) {
       setName(name);
       setPrice(price);
   }

   public void setName(String name) {
       String lowercaseName = name.toLowerCase();
       for (String validName : VALID_NAMES) {
           if (validName.equals(lowercaseName)) {
               this.name = name;
               return;
           }
       }
       throw new IllegalArgumentException("Invalid drink name. Must be one of: " + String.join(", ", VALID_NAMES));
   }

   public void setPrice(double price) {
       if (price < 0) {
           throw new IllegalArgumentException("Price cannot be negative");
       }
       if (price > MAX_PRICE) {
           throw new IllegalArgumentException("Price cannot exceed $" + MAX_PRICE);
       }
       this.price = price;
   }
}

Setelah kita melindungi cara atribut dibuat, kita juga ingin melindungi cara atribut diakses. Ini dilakukan dengan menggunakan metode getter:

public class MenuItem {
   // Rest of the code here
   ...
   public String getName() {
       return name;
   }
   public double getPrice() {
       return price;
   }
}

Metode getter menyediakan akses terkontrol ke atribut privat dari sebuah kelas. Metode ini menyelesaikan masalah akses atribut langsung yang dapat menyebabkan modifikasi yang tidak diinginkan dan merusak enkapsulasi.

Sebagai contoh, tanpa getter, kita mungkin mengakses atribut secara langsung:

MenuItem item = new MenuItem("Latte", 4.99);
String name = item.name; // Direct access to attribute
item.name = "INVALID"; // Can modify directly, bypassing validation

Dengan getter, kita menegakkan akses yang benar:

MenuItem item = new MenuItem("Latte", 4.99);
String name = item.getName(); // Controlled access through getter
// item.name = "INVALID"; // Not allowed - must use setName() which validates

Enkapsulasi ini:

  1. Melindungi integritas data dengan mencegah modifikasi yang tidak valid
  2. Memungkinkan kita mengubah implementasi internal tanpa memengaruhi kode yang menggunakan kelas
  3. Menyediakan satu titik akses yang dapat menyertakan logika tambahan bila diperlukan
  4. Membuat kode lebih mudah dipelihara dan lebih kecil kemungkinannya menimbulkan bug

Pewarisan

Kelas kita mulai terlihat baik tetapi masih ada cukup banyak masalah. Misalnya, untuk restoran besar yang menyajikan banyak jenis hidangan dan minuman, kelas ini tidak cukup fleksibel.

Jika kita ingin menambahkan berbagai jenis makanan, kita akan menghadapi beberapa tantangan. Beberapa hidangan bisa disiapkan untuk dibawa pulang, sementara yang lain perlu dikonsumsi segera. Item menu mungkin memiliki harga dan diskon yang bervariasi. Hidangan mungkin memerlukan pelacakan suhu atau penyimpanan khusus. Minuman bisa panas atau dingin dengan bahan yang dapat disesuaikan. Item mungkin memerlukan informasi alergen dan opsi porsi. Sistem saat ini tidak menangani kebutuhan yang beragam ini.

Pewarisan memberikan solusi elegan untuk semua masalah ini. Pewarisan memungkinkan kita membuat versi khusus dari item menu dengan mendefinisikan kelas dasar MenuItem dengan atribut umum lalu membuat kelas turunan yang mewarisi dasar-dasar ini sambil menambahkan fitur unik.

Sebagai contoh, kita bisa memiliki kelas Drink untuk minuman dengan opsi suhu, kelas Food untuk item yang perlu segera dikonsumsi, dan kelas Dessert untuk item dengan kebutuhan penyimpanan khusus — semuanya mewarisi fungsionalitas inti item menu.

Memperluas kelas

Mari implementasikan ide-ide tersebut dimulai dengan Drink:

public class Drink extends MenuItem {
   private boolean isCold;
  
   public Drink(String name, double price, boolean isCold) {
       this.name = name;
       this.price = price;
       this.isCold = isCold;
   }
  
   public boolean getIsCold() {
       return isCold;
   }
  
   public void setIsCold(boolean isCold) {
       this.isCold = isCold;
   }
}

Untuk mendefinisikan kelas anak yang mewarisi dari induk, kita menggunakan kata kunci extends setelah nama kelas anak diikuti kelas induk. Setelah definisi kelas, kita mendefinisikan atribut baru apa pun yang dimiliki anak ini dan mengimplementasikan konstruktornya.

Namun perhatikan bagaimana kita harus mengulang inisialisasi name dan price bersama dengan isCold. Itu tidak ideal karena kelas induk mungkin memiliki ratusan atribut. Selain itu, kode di atas akan menghasilkan error saat Anda mengompilasinya karena itu bukan cara yang benar untuk menginisialisasi atribut kelas induk. Cara yang benar adalah menggunakan kata kunci super:

public class Drink extends MenuItem {
   private boolean isCold;
  
   public Drink(String name, double price, boolean isCold) {
       super(name, price);
       this.isCold = isCold;
   }
  
   public boolean getIsCold() {
       return isCold;
   }
  
   public void setIsCold(boolean isCold) {
       this.isCold = isCold;
   }
}

Kata kunci super digunakan untuk memanggil konstruktor kelas induk. Dalam hal ini, super(name, price) memanggil konstruktor MenuItem untuk menginisialisasi atribut tersebut, menghindari duplikasi kode. Kita hanya perlu menginisialisasi atribut baru isCold yang spesifik untuk kelas Drink.

Kata kunci ini sangat fleksibel karena Anda dapat menggunakannya untuk merujuk pada kelas induk di bagian mana pun dari kelas anak. Misalnya, untuk memanggil metode induk, Anda gunakan super.methodName() sementara super.attributeName untuk atribut.

Method overriding

Sekarang, anggaplah kita ingin menambahkan metode baru ke kelas-kelas kita untuk menghitung total harga setelah pajak. Karena item menu yang berbeda mungkin memiliki tarif pajak yang berbeda (misalnya, makanan siap saji vs. minuman kemasan), kita dapat menggunakan method overriding untuk menerapkan perhitungan pajak khusus di setiap kelas turunan sambil mempertahankan nama metode yang sama di kelas induk.

Berikut tampilannya:

public class MenuItem {
   // Rest of the MenuItem class
  
   public double calculateTotalPrice() {
       // Default tax rate of 10%
       return price * 1.10;
   }
}
public class Food extends MenuItem {
   private boolean isVegetarian;
  
   public Food(String name, double price, boolean isVegetarian) {
       super(name, price);
       this.isVegetarian = isVegetarian;
   }
  
   @Override
   public double calculateTotalPrice() {
       // Food has 15% tax
       return super.getPrice() * 1.15;
   }
}
public class Drink extends MenuItem {
   private boolean isCold;
  
   public Drink(String name, double price, boolean isCold) {
       super(name, price);
       this.isCold = isCold;
   }
  
   @Override
   public double calculateTotalPrice() {
       // Drinks have 8% tax
       return super.getPrice() * 1.08;
   }
}

Dalam contoh ini, method overriding memungkinkan setiap subclass menyediakan implementasi sendiri untuk calculateTotalPrice():

Kelas dasar MenuItem mendefinisikan perhitungan pajak default sebesar 10%.

Ketika kelas Food dan Drink memperluas MenuItem, mereka override metode ini untuk menerapkan tarif pajak masing-masing:

  • Item makanan memiliki tarif pajak lebih tinggi yaitu 15%
  • Minuman memiliki tarif pajak lebih rendah yaitu 8%

Anotasi @Override digunakan untuk secara eksplisit menunjukkan bahwa metode ini menimpa metode kelas induk. Ini membantu menangkap kesalahan jika tanda tangan metode tidak cocok dengan kelas induk.

Setiap subclass masih dapat mengakses harga kelas induk menggunakan super.getPrice(), menunjukkan bagaimana metode yang dioverride dapat memanfaatkan fungsionalitas kelas induk sambil menambahkan perilaku mereka sendiri.

Singkatnya, method overriding adalah bagian integral dari pewarisan yang memungkinkan subclass menyediakan implementasi metode mereka sendiri yang didefinisikan di kelas induk, sehingga memungkinkan perilaku yang lebih spesifik sambil mempertahankan tanda tangan metode yang sama.

Kelas Abstrak

Hierarki kelas MenuItem kita berfungsi, tetapi ada masalah: haruskah siapa pun dapat membuat objek MenuItem biasa? Bagaimanapun, di restoran kita, setiap item menu adalah Food atau Drink—tidak ada yang namanya “item menu generik.”

Kita dapat mencegah hal ini dengan menjadikan MenuItem sebagai kelas abstrak. Kelas abstrak hanya menyediakan cetak biru dasar—kelas ini hanya dapat digunakan sebagai kelas induk untuk pewarisan, bukan diinstansiasi langsung.

Untuk membuat MenuItem menjadi abstrak, kita tambahkan kata kunci abstract setelah modifier aksesnya:

public abstract class MenuItem {
   private String name;
   private double price;
  
   public MenuItem(String name, double price) {
       setName(name);
       setPrice(price);
   }
  
   // Existing getters/setters remain the same
  
   // Make this method abstract - every subclass MUST implement it
   public abstract double calculateTotalPrice();
}

Kelas abstrak juga dapat memiliki metode abstrak seperti calculateTotalPrice() di atas. Metode abstrak ini berfungsi sebagai kontrak yang memaksa subclass untuk menyediakan implementasinya. Dengan kata lain, metode abstrak apa pun dalam kelas abstrak harus diimplementasikan oleh kelas anak.

Jadi, mari kita tulis ulang Food dan Drink dengan perubahan ini dalam pikiran:

public class Food extends MenuItem {
   private boolean isVegetarian;
  
   public Food(String name, double price, boolean isVegetarian) {
       super(name, price);
       this.isVegetarian = isVegetarian;
   }
  
   @Override
   public double calculateTotalPrice() {
       return getPrice() * 1.15;  // 15% tax
   }
}
public class Drink extends MenuItem {
   private boolean hasCaffeine;
  
   public Drink(String name, double price, boolean hasCaffeine) {
       super(name, price);
       this.hasCaffeine = hasCaffeine;
   }
  
   @Override
   public double calculateTotalPrice() {
       return getPrice() * 1.10;  // 10% tax
   }
}

Melalui implementasi sistem menu ini, kita telah melihat bagaimana abstraksi dan pewarisan bekerja bersama untuk menciptakan kode yang fleksibel dan mudah dipelihara yang dapat dengan mudah beradaptasi dengan berbagai kebutuhan bisnis.

Kesimpulan

Hari ini, kita telah melihat sekilas tentang kemampuan Java sebagai bahasa pemrograman berorientasi objek. Kita telah membahas dasar-dasar kelas, objek, dan beberapa pilar utama OOP: enkapsulasi, pewarisan, dan abstraksi melalui sistem menu restoran.

Untuk membuat sistem ini siap produksi, Anda masih memiliki banyak hal untuk dipelajari, seperti interface (bagian dari abstraksi), polimorfisme, dan pola desain OOP. Untuk mempelajari lebih lanjut tentang konsep-konsep ini, lihat kursus Introduction to OOP in Java kami.

Jika Anda ingin menguji pengetahuan Java Anda, coba jawab beberapa pertanyaan dalam artikel Java Interview Questions kami.

FAQ OOP di Java

Apa prasyarat untuk mengikuti tutorial OOP Java ini?

Anda sebaiknya memiliki pengetahuan dasar pemrograman Java, termasuk tipe data, variabel, alur kontrol (if/else, loop), dan sintaks dasar. Kursus Introduction to Java kami membahas dasar-dasar ini jika Anda perlu penyegaran.

Mengapa menggunakan sistem menu restoran untuk menjelaskan konsep OOP?

Sistem menu restoran adalah contoh intuitif yang menunjukkan penerapan prinsip OOP di dunia nyata. Contoh ini secara alami memperlihatkan pewarisan (berbagai jenis item menu), enkapsulasi (melindungi nilai harga dan nama), dan interface (program loyalitas, kontrol suhu). Kebanyakan orang memahami cara kerja restoran, sehingga konsepnya lebih mudah dipahami.

Apa perbedaan antara kelas abstrak dan interface di Java?

  • Sebuah kelas hanya dapat memperluas satu kelas abstrak tetapi dapat mengimplementasikan banyak interface.
  • Kelas abstrak dapat memiliki field dan konstruktor; interface tidak dapat.
  • Kelas abstrak dapat memiliki metode abstrak dan konkret; secara tradisional interface hanya memiliki metode abstrak (sebelum Java 8).
  • Kelas abstrak menyediakan implementasi dasar, sementara interface mendefinisikan kontrak.

Bexruz (Bex) Tuychiev's photo
Author
Bexruz (Bex) Tuychiev
LinkedIn

Saya adalah kreator konten data science dengan pengalaman lebih dari 2 tahun dan salah satu dengan jumlah pengikut terbesar di Medium. Saya suka menulis artikel mendalam tentang AI dan ML dengan sedikit gaya sarkastik—karena harus ada sesuatu untuk membuatnya tidak terlalu membosankan. Saya telah menghasilkan lebih dari 130 artikel dan satu kursus di DataCamp, dengan satu lagi sedang dalam proses. Konten saya telah dilihat oleh lebih dari 5 juta pasang mata, dan 20 ribu di antaranya menjadi pengikut di Medium dan LinkedIn. 

Topik
Java

Kursus Java Teratas

Kursus

Pengantar Java

4 jam
41.1K
Pelajari Java dari dasar dengan kursus ramah pemula ini, menguasai konsep dan keterampilan pemrograman yang esensial.
Lihat DetailRight Arrow
Mulai Kursus
Lihat SelengkapnyaRight Arrow
Terkait

blogs

40 Pertanyaan Wawancara DBMS Teratas di 2026

Kuasai pertanyaan wawancara basis data, dari konsep SQL dasar hingga skenario desain sistem tingkat lanjut. Panduan mendalam ini mencakup semua yang Anda perlukan untuk sukses di wawancara DBMS dan meraih peran berikutnya.
Dario Radečić's photo

Dario Radečić

15 mnt

blogs

Tutorial Korelasi di R

Dapatkan pengenalan dasar-dasar korelasi di R: pelajari lebih lanjut tentang koefisien korelasi, matriks korelasi, plotting korelasi, dan sebagainya.
David Woods's photo

David Woods

13 mnt

blogs

Spaghetti Plot dan Jalur Badai

Temukan alasan mengapa Anda sebaiknya (tidak) menggunakan spaghetti plot untuk menyampaikan ketidakpastian jalur prediksi badai serta dampaknya terhadap interpretasi.
Hugo Bowne-Anderson's photo

Hugo Bowne-Anderson

13 mnt

blogs

12 Alternatif ChatGPT Terbaik yang Bisa Anda Coba pada 2026

Artikel ini menyajikan daftar alternatif ChatGPT yang akan meningkatkan produktivitas Anda.
Javier Canales Luna's photo

Javier Canales Luna

14 mnt

Lihat SelengkapnyaLihat Selengkapnya