Pengertian Pemrograman Berorientasi Objek Pemrograman berorientasi objek atau dalam bahasa inggris disebut Object Oriented Programming (OOP) adalah paradigma atau teknik pemrograman di mana semua hal dalam program dimodelkan seperti objek dalam dunia nyata. Objek di dunia nyata memiliki ciri atau attribut dan juga aksi atau kelakuan (behaviour). Kita misalkan
sebuah mobil. Mobil memiliki ciri punya ban, stang, kursi, pedal gas, rem, dan lain sebagainya. Ada juga ciri warna, atau tahun keluaran berapa. Selain punya ciri, mobil juga punya aksi atau sesuatu yang bisa dilakukan olehnya. Misalnya, ketika pedal diinjak apa yang terjadi. Ketika di rem apa yang terjadi, dan lain sebagainya. Program juga demikian. Semua unit dalam program bisa dianggap sebagai objek. Objek besar dibangun dari objek – objek yang lebih kecil. Objek yang satu berinteraksi
dengan objek yang lain, sehingga semua menjadi sebuah kesatuan yang utuh. Python dari awal dibuat sudah mengadopsi OOP. Selain itu Python juga bisa menggunakan paradigma pemrograman lama yaitu pemrograman terstruktur. Oleh karena itu, Python disebut bersifat hibrid. Istilah – Istilah Dalam OOP Sebelum mempelajari lebih jauh tentang OOP, ada baiknya kita harus mengetahui istilah – istilah dalam OOP, yaitu sebagai berikut: Pembuatan Kelas Kita mendefinisikan sebuah kelas
dengan menggunakan kata kunci class diikuti oleh nama kelas tersebut. Berikut adalah sintaks pembuatan kelas di Python. Kelas memiliki docstring atau string dokumentasi yang bersifat opsional artinya bisa ada atau tidak. Docstring bisa diakses menggunakan format ClassName.__doc__ class_body terdiri dari semua pernyataan berupa attribut, fungsi, dan data dari kelas Contoh Kelas Berikut adalah contoh kelas yang sederhana: Variabel
jumlah_karyawan adalah variabel kelas yang dibagi ke semua instance/objek dari kelas ini. Variabel ini bisa diakses dari dalam atau luar kelas dengan menggunakan notasi titik, Karyawan.jumlah_karyawan. Metode __init__() adalah metode konstruktor, yaitu metode khusus yang digunakan Python untuk menginisialisasi pembuatan objek dari kelas tersebut. Fungsi – fungsi di dalam kelas (disebut metode) pendefinisiannya sama dengan fungsi pada umumnya. Hanya saja, harus ada argumen pertama bernama
self. Pada saat pemanggilan fungsi, argumen ini otomatis ditambahkan oleh Python. Anda tidak perlu menambahkannya pada saat memanggil fungsi. Instansiasi Objek Untuk membuat objek dari sebuah kelas, kita bisa memanggil nama kelas dengan argumen sesuai dengan fungsi __init__() pada saat kita mendefinisikannya.
Mengakses Attribut Objek
Kita bisa mengakses atribut objek dengan menggunakan operator titik. Variabel kelas bisa diakses dengan menggunakan nama kelasnya.
karyawan1.tampilkan_profil() karyawan2.tampilkan_profil() print("Total karyawan :", Karyawan.jumlah_karyawan)Sekarang, mari kita gabungkan semua contoh di atas.
class Karyawan: '''Dasar kelas untuk semua karyawan''' jumlah_karyawan = 0 def __init__(self, nama, gaji): self.nama = nama self.gaji = gaji Karyawan.jumlah_karyawan += 1 def tampilkan_jumlah(self): print("Total karyawan:", Karyawan.jumlah_karyawan) def tampilkan_profil(self): print("Nama :", self.nama) print("Gaji :", self.gaji) # Membuat objek pertama dari kelas Karyawan karyawan1 = Karyawan("Sarah", 1000000) # Membuat objek kedua dari kelas Karyawan karyawan2 = Karyawan("Budi", 2000000) karyawan1.tampilkan_profil() karyawan2.tampilkan_profil() print("Total karyawan :", Karyawan.jumlah_karyawan)
Pada saat program di atas dijalankan, outputnya adalah seperti berikut:
Nama : Sarah Gaji : 1000000 Nama : Budi Gaji : 2000000 Total karyawan : 2Menambah, Menghapus, dan Mengubah Atribut Objek
Kita bisa menambah, menghapus, dan mengubah atribut objek seperti berikut:
karyawan1.gaji = 1500000 karyawan1.nama = 'Ratna' del karyawan1.gajiCara yang lebih elegan untuk memodifikasi atribut adalah dengan menggunakan fungsi – fungsi berikut:
- getattr(obj, name[, default]) – Mengakses atribut objek
- hasattr(obj, name) – Memeriksa apakah objek memiliki atribut tertentu atau tidak
- setattr(obj, name, value) – Mengatur nilai atribut. Jika atribut tidak ada, maka atribut tersebut akan dibuatkan
- delattr(obj, name) – Menghapus atribut dari objek
Atribut Kelas Built-in
Setiap kelas di Python memiliki atribut built-in (bawaan) yang bisa diakses menggunakan operator titik. Attribut-attribut tersebut adalah sebagai berikut:
- __dict__ – dictionary yang berisi namespace dari kelas
- __doc__ – mengakses string dokumentasi (docstring) dari kelas
- __name__ – nama kelas
- __module__ – nama modul tempat kelas didefinisikan. Nilai attribut ini di mode interaktif adalah “__main__“.
- __bases__ – dasar dari kelas, bila kelas tidak merupakan turunan dari kelas lain, maka induknya dalah kelas object.
class Karyawan: '''Dasar kelas untuk semua karyawan''' jumlah_karyawan = 0 def __init__(self, nama, gaji): self.nama = nama self.gaji = gaji Karyawan.jumlah_karyawan += 1 def tampilkan_jumlah(self): print("Total karyawan:", Karyawan.jumlah_karyawan) def tampilkan_profil(self): print("Nama :", self.nama) print("Gaji :", self.gaji) # Membuat objek pertama dari kelas Karyawan karyawan1 = Karyawan("Sarah", 1000000) # Membuat objek kedua dari kelas Karyawan karyawan2 = Karyawan("Budi", 2000000) print("Karyawan.__doc__:", Karyawan.__doc__) print("Karyawan.__name__:", Karyawan.__name__) print("Karyawan.__module__:", Karyawan.__module__) print("Karyawan.__dict__:", Karyawan.__dict__) print("Karyawan.__bases__:", Karyawan.__bases__)
Output dari program di atas adalah:
Karyawan.__doc__: Dasar kelas untuk semua karyawan Karyawan.__name__: Karyawan Karyawan.__module__: __main__ Karyawan.__dict__: {'tampilkan_jumlah': , '__module__': '__main__', '__doc__': 'Dasar kelas untuk semua karyawan', 'jumlah_karyawan': 2, '__weakref__': <attribute '__weakref__' of 'Karyawan' objects>, 'tampilkan_profil': , '__dict__': <attribute '__dict__' of 'Karyawan' objects>, '__init__': } Karyawan.__bases__: (<class 'object'>,)Penghancuran Objek (Pengumpulan Sampah/Garbage Collection)
Python menghapus objek yang sudah tidak terpakai secara otomatis untuk menghemat memori. Proses ini disebut dengan pengumpulan sampah (garbage collection).
Kolektor sampah Python terus berjalan pada saat program dieksekusi dan dipicu pada saat tidak ada lagi referensi/variabel yang merujuk ke objek.
Jumlah referensi terhadap objek bertambah pada saat ada variabel yang merujuk ke objek tersebut. Sebaliknya referensi terhadap objek berkurang ketika variabel terhapus dengan menggunakan del, atau saat terjadi penugasan ulang, atau saat referensi keluar dari scope-nya.
Pada saat referensi terhadap objek sudah nol, maka Python akan otomatis menghapus objek tersebut. Perhatikan contoh berikut:
a = 30 # Menciptakan objek <30> b = a # menambah jumlah referensi ke objek <30> c = [b] # menambah jumlah referensi ke objek <30> del a # mengurangi jumlah referensi ke objek <30> b = 100 # mengurangi jumlah referensi ke objek <30> c[0] = -1 # mengurangi jumlah referensi ke objek <30>Pada contoh di atas, objek 30 pada akhirnya akan dihapus karena sudah tidak ada variabel yang merujuk ke objek tersebut.
Python melakukan penghapusan objek secara otomatis tanpa ada pemberitahuan. Kita bisa menggunakan sebuah metode khusus yaitu metode __del__() yang disebut destruktor, yang akan dipanggil apabila sebuah objek akan dihapuskan oleh python.
Berikut adalah contoh penggunaan destruktor __del__().
class Point: def __init__( self, x=0, y=0): self.x = x self.y = y def __del__(self): class_name = self.__class__.__name__ print (class_name, "dihancurkan") pt1 = Point() pt2 = pt1 pt3 = pt1 print (id(pt1), id(pt2), id(pt3)); # ,menampilkan id objek del pt1 del pt2 del pt3
Output dari kode di atas adalah seperti berikut:
140154852984592 140154852984592 140154852984592 Point dihancurkanPewarisan (Inheritansi) Kelas
Kita bisa menurunkan karakteristik sebuah kelas ke kelas baru, dibandingkan dengan membuat kelas baru dari awal. Turunannya disebut kelas anak (child class) dan yang mewariskannya disebut kelas induk (parent class).
Kelas anak mewarisi atribut dari kelas induk, dan kita bisa menggunakan atribut tersebut seolah atribut itu didefinisikan juga di dalam kelas anak. Kelas anak juga bisa menimpa (override) data dan metode dari induknya dengan data dan metodenya sendiri.
Satu kelas anak bisa mewarisi karakteristik dari satu atau beberapa kelas induk.
Sintaks
Pewarisan memiliki sintaks sebagai berikut:
class SubClassName (ParentClass1[, ParentClass2, ...]): """docstring""" class_bodyContoh
class Induk: # mendefinisikan kelas Induk parent_attr = 100 def __init__(self): print ("Memanggil konstruktor induk") def parent_method(self): print ('Memanggil metode induk') def set_attr(self, attr): Induk.parent_attr = attr def get_attr(self): print ("Attribut induk :", Induk.parent_attr) class Anak(Induk): # mendefinisikan kelas Anak def __init__(self): print ("Memanggil konstruktor Anak") def child_method(self): print ('Memanggil metode Anak') c = Anak() # instansiasi kelas Anak c.child_method() # Anak memanggil metodenya c.parent_method() # memanggil metode Induk c.set_attr(200) # kembali memanggil metode Induk c.get_attr() # kembali memanggil metode Induk
Output dari kode di atas adalah seperti berikut:
Memanggil konstruktor Anak Memanggil metode Anak Memanggil metode induk Attribut induk: 200Dengan cara yang sama, kita bisa membuat mewariskan beberapa induk ke satu anak seperti berikut:
class A: # mendefinisikan kelas A ..... class B: # mendefinisikan kelas B ..... class C(A, B): # mendefinisikan turunan dari kelas A dan B .....Kita bisa menggunakan fungsi issubclass() atau isinstance() untuk memeriksa relasi antara dua kelas atau objek.
- Fungsi issubclass(sub, sup) mengembalikan True jika sub merupakan anak dari sup
- Fungsi isinstance(obj, Class) mengembalikan True jika obj adalah instance dari kelas Class atau subkelas dari Class.
Metode Overriding
Kita bisa mengabaikan fungsi dari kelas induk di dalam kelas anak. Alasan untuk melakukan overriding adalah karena kita memodifikasi atau mengubah metode yang sudah diturunkan dari kelas induk di dalam kelas anak. Perhatikan contoh berikut:
class Induk: def my_method(self): print("Memanggil metode induk") class Anak(Induk): def my_method(self): print("Memanggil metode anak") c = Anak() c.my_method()
Hasil keluaran dari kode di atas adalah:
Memanggil metode anakPerhatikan pada contoh di atas bagaimana kita mengabaikan metode yang dari induk dan mendefinisikan sendiri metode dengan nama yang sama di kelas anak. Dan yang dijalankan adalah metode yang ada di kelas anak.
Overloading Metode
Tabel berikut menunjukkan beberapa fungsi umum yang sering di-override di dalam kelas:
No | Metode, Deskripsi, dan Contoh |
1 | __init__(self[, args…]) Fungsi: Konstruktor (argumen bersifat opsional) Contoh pemanggilan: obj = className(args) |
2 | __del__(self) Fungsi: Destruktor, menghapus sebuah objek Contoh pemanggilan: del obj |
3 | __repr__(self) Fungsi: Representasi string yang bisa dievaluasi Contoh pemanggilan: repr(obj) |
4 | __str__(self) Fungsi: Representasi string yang bisa dicetak Contoh pemanggilan: str(obj) |
5 | __cmp__(self, x) Fungsi: Membandingkan objek Contoh pemanggilan: cmp(obj, x) |
Overloading Operator
Misalkan kita membuat sebuah kelas Vector untuk menunjukkan vektor dua dimensi. Apa yang terjadi bila kita menggunakan tanda + untuk menjumlahkan keduanya?
Kita bisa mendefinisikan metode __add__ dalam kelas kita untuk melakukan penjumlahan vektor dan kemudian operator + akan berfungsi sesuai kehendak kita. Perhatikan contoh berikut:
class Vector: def __init__(self, a, b): self.a = a self.b = b def __str__(self): return 'Vector (%d, %d)' % (self.a, self.b) def __add__(self, other): return Vector(self.a + other.a, self.b + other.b) v1 = Vector(5, 10) v2 = Vector(4, -2) print(v1 + v2)
Saat program di atas dieksekusi, hasilnya akan muncul seperti berikut:
Vector(9, 8)Menyembunyikan Data (Data Hiding)
Sebuah atribut objek bisa dibuat terlihat ataupun tersembunyi dari luar kelas. Caranya di Python adalah dengan memberi nama atribut dengan di awali tanda underscore dua kali. Dengan begitu, atribut tersebut tidak akan dapat tampak dari luar kelas.
Contoh
class Counter: __secret_count = 0 def count(self): self.__secret_count += 1 print(self.__secret_count) counter = Counter() counter.count() counter.count() print(counter.__secret_count)Bila kode di atas dijalankan maka keluarannya akan menampilkan hasil seperti berikut:
1 2 Traceback(most recent call last): File "test.py", line 12, in <module> Attribut Error: Counter instance has no attribute '__secret_count'Python melindungi attribut tersebut dengan mengubah namanya. Kita bisa mengakses atribut seperti itu dengan format object._className__attrName seperti berikut:
print(counter._Counter__secret_count)Output dari program di atas adalah seperti berikut:
1 2 3