
Foto oleh Pixabay via Pexels
Object-Oriented Programming (OOP) adalah paradigma pemrograman yang mengorganisasikan kode ke dalam unit-unit bernama object, masing-masing menggabungkan data (property) dan perilaku (method) yang saling terkait dalam satu kesatuan yang disebut class.
Class berfungsi sebagai cetak biru (blueprint) untuk membuat object, mendefinisikan properti apa saja yang dimiliki dan apa saja yang bisa dilakukan object tersebut. Satu class bisa dipakai untuk membuat banyak object dengan nilai properti yang berbeda-beda, namun berbagi struktur dan perilaku yang sama.
Artikel ini membahas cara mendefinisikan class, membuat object darinya, serta konsep access modifier yang mengatur sejauh mana bagian dalam class bisa diakses dari luar, sebagai fondasi sebelum mempelajari pilar OOP lain seperti inheritance dan polymorphism.
Mendefinisikan Class dan Property
Class Mahasiswa dengan tiga property
Membuat Object dari Class
Dua object independen dibuat dari class yang sama
Method untuk Mendefinisikan Perilaku Object
Method mendefinisikan perilaku yang bisa dipanggil object
Access Modifier public dan private
Private menyembunyikan detail internal dari akses luar
Access Modifier pada Class: Public, Private, Protected, dan Internal
Access modifier menentukan batas visibilitas anggota class
Access modifier adalah kata kunci yang menentukan sejauh mana suatu member class (field, property, method) dapat diakses dari luar class tersebut. Public berarti dapat diakses dari mana saja tanpa batasan, sedangkan private, yang juga merupakan default jika tidak dituliskan modifier apapun, hanya dapat diakses dari dalam class yang sama, seperti field gajiPokok pada contoh di atas yang hanya bisa dibaca melalui method LihatGaji().
Protected memperbolehkan akses dari dalam class itu sendiri maupun dari class turunannya (inheritance), sehingga cocok digunakan untuk data yang perlu dibagikan ke subclass tetapi tetap disembunyikan dari kode eksternal. Sementara itu, internal membatasi akses hanya pada lingkup assembly yang sama, artinya kode pada project atau library lain yang mereferensikan assembly tersebut tidak bisa mengakses member internal meskipun class-nya bersifat public.
Penerapan access modifier yang tepat merupakan bagian inti dari prinsip encapsulation dalam OOP, karena tujuannya adalah membatasi akses langsung ke data internal sebuah object dan memaksa interaksi dilakukan melalui method atau property yang telah disediakan, sehingga validasi dan logika bisnis tetap terjaga konsistensinya di satu tempat.
Static Class dan Static Member untuk Logika yang Tidak Bergantung pada Instance
Static class hanya berisi static member dan tidak bisa diinstansiasi
Static class adalah class yang ditandai kata kunci static dan hanya boleh berisi member yang juga bersifat static, sehingga class tersebut tidak dapat diinstansiasi menggunakan kata kunci new sama sekali. Class seperti KalkulatorPajak pada contoh di atas cocok dipakai untuk mengelompokkan logika yang sifatnya stateless, artinya tidak bergantung pada data yang berbeda-beda antar instance, melainkan selalu menghasilkan output yang sama untuk input yang sama seperti perhitungan PPN berdasarkan tarif tetap.
Static member, baik field, property, maupun method, dimiliki bersama oleh seluruh instance dari suatu class, bukan dimiliki secara terpisah oleh masing-masing objek. Artinya, jika sebuah class biasa (bukan static) memiliki static field, maka perubahan nilai field tersebut melalui satu instance akan terlihat juga ketika diakses melalui instance lain dari class yang sama, karena static field disimpan satu kali saja di memori selama aplikasi berjalan, bukan per objek yang dibuat.
Class utility seperti Math dan Console pada .NET Base Class Library merupakan contoh nyata static class yang dipakai sehari-hari, karena method seperti Math.Sqrt atau Console.WriteLine tidak memerlukan state apapun dari suatu object tertentu untuk dapat berfungsi. Kesalahan umum pemula adalah memaksakan static class untuk menyimpan data yang semestinya berbeda-beda per transaksi atau per pengguna, yang justru dapat menimbulkan bug serius pada aplikasi yang diakses banyak pengguna secara bersamaan. Konstanta yang dideklarasikan dengan const, seperti TarifPpn di atas, juga bersifat implisit static dan nilainya ditentukan pada saat kompilasi sehingga tidak bisa diubah lagi sepanjang aplikasi berjalan, berbeda dengan static readonly yang nilainya masih bisa ditentukan sekali saat runtime melalui static constructor.
Object Initializer dan Collection Initializer untuk Inisialisasi Ringkas
Object initializer memungkinkan pengisian property sebuah object langsung di dalam kurung kurawal setelah pemanggilan constructor, tanpa harus membuat constructor khusus yang menerima semua parameter satu per satu seperti pada pendekatan lama. Cara ini membuat kode lebih ringkas terutama untuk class dengan banyak property opsional yang tidak selalu perlu diisi semuanya pada setiap pemakaian, serta membuat urutan pengisian nilai lebih fleksibel karena setiap property dipanggil dengan namanya langsung, bukan berdasarkan posisi parameter.
Collection initializer menerapkan konsep serupa untuk koleksi seperti List atau Dictionary, mengizinkan beberapa elemen dimasukkan sekaligus saat deklarasi tanpa memanggil method Add() berulang kali baris demi baris. Gabungan keduanya sering dipakai bersama saat membuat data uji, data konfigurasi awal, atau data seed yang strukturnya sudah diketahui sejak awal penulisan kode, sehingga seluruh data awal bisa dilihat dalam satu blok kode yang ringkas dan mudah dipahami tanpa harus menelusuri banyak baris terpisah.
Kesalahan Umum yang Sering Terjadi
Membuat Semua Property dan Field Bersifat Public
Menjadikan seluruh data pada class bisa diakses dan diubah bebas dari luar menghilangkan manfaat encapsulation, membuka risiko data berada dalam kondisi yang tidak valid karena diubah tanpa melalui validasi yang semestinya.
Bingung Antara Class dan Object
Class adalah cetakan atau definisi, sementara object adalah instance nyata yang dibuat dari cetakan tersebut; menyamakan keduanya bisa membuat developer pemula bingung saat harus membuat banyak object dari satu class yang sama.
Menaruh Terlalu Banyak Tanggung Jawab dalam Satu Class
Class yang menangani terlalu banyak hal sekaligus (melanggar Single Responsibility Principle) menjadi sulit dipahami, diuji, dan dipelihara seiring bertambahnya fitur yang harus ditambahkan ke dalamnya.
Kapan Pendekatan Ini Tidak Cocok Dipakai
Auto-property dengan get-set publik memberikan kemudahan dan kecepatan penulisan kode, cocok untuk data sederhana seperti DTO (Data Transfer Object) yang memang tidak membutuhkan validasi khusus.
Property dengan backing field privat dan logika validasi di dalam setter memberikan kontrol lebih ketat terhadap integritas data, namun membutuhkan lebih banyak kode untuk diimplementasikan, sehingga pilihan antara keduanya bergantung pada seberapa kritikal validasi data tersebut bagi aplikasi.
Ringkasan
Class dan object adalah fondasi OOP di C#, dengan class berperan sebagai cetakan dan object sebagai instance nyata yang dibuat darinya. Gunakan access modifier dengan bijak untuk menerapkan encapsulation, menyembunyikan detail implementasi yang tidak perlu diketahui kode luar, sebagai dasar sebelum mempelajari inheritance dan polymorphism pada artikel berikutnya.
Seri Belajar C# Fundamental:
← Sebelumnya: Operasi Penyeleksian Kondisi (IF) dan Proses Perulangan (Loop) (sudah ada)
→ Selanjutnya: Array dan List di C#