Dasar-Dasar Pewarisan Python
Pewarisan adalah salah satu pilar dasar pemrograman berorientasi objek (OOP) yang memungkinkan satu kelas (disebut kelas anak) menurunkan atribut dan metode dari kelas lain (disebut kelas induk). Fitur ini penting untuk penggunaan ulang kode dan menyederhanakan pemeliharaan, sehingga lebih mudah membangun program yang skalabel dan efisien.
Mendefinisikan kelas induk dan anak
Sebelum melangkah lebih jauh, mari kita jelajahi hubungan antara kelas induk dan kelas anak.
Kelas induk
Mari mulai dengan kelas induk. Kelas induk adalah kelas dasar tempat kelas anak diturunkan. Kelas ini membungkus atribut dan metode bersama.
Dengan Python, berikut cara kita mendefinisikan kelas induk:
class ParentClass:
def __init__(self, attributes):
# Initialize attributes
pass
def method(self):
# Define behavior
pass
Kelas anak
Sebuah kelas anak mewarisi atribut dan metode dari kelas induk. Ini memungkinkannya menggunakan fungsionalitas yang didefinisikan di kelas induk. Kode berikut menunjukkan bagaimana kelas anak mewarisi atribut dan metode dari kelas induk:
class ChildClass(ParentClass):
def additional_method(self):
# Define new behavior
pass
Sintaks sederhana ini memungkinkan kelas anak memanfaatkan dan memperluas fungsionalitas yang didefinisikan di kelas induk.
Membuat kelas induk dan kelas anak
Mari kita buat contoh praktis dengan kelas Person sebagai induk dan kelas Student sebagai anak.
Membuat kelas induk
Kelas Person berisi atribut bersama dan sebuah metode untuk menampilkan informasi:
# Defining the Parent Class
class Person:
def __init__(self, name, id):
self.name = name
self.id = id
def display_info(self):
return f"Name: {self.name}, ID: {self.id}"
Membuat kelas anak
Kelas Student mewarisi dari Person dan menambahkan metode baru study.
# Defining the Child Class
class Student(Person):
def study(self):
return f"{self.name} is studying."
Mari kita uji kelas induk dan anak.
# Creating and Testing Instances
student = Student("Samuel", 102)
print(student.display_info())
print(student.study())
Name: Samuel, ID: 102
Samuel is studying.
Berikut yang terjadi:
-
Kelas
Studentmenggunakan metode__init__dariPersonuntuk menginisialisasinamedanid. -
Metode
studybersifat unik untuk kelasStudent, memperluas fungsionalitasnya. -
Metode
display_infodiwariskan langsung dariPerson.
Jenis-Jenis Pewarisan di Python
Pewarisan di Python memungkinkan kelas mewarisi atribut dan perilaku dari kelas lain, mendorong penggunaan ulang kode dan desain yang bersih, seperti yang telah kita bahas sebelumnya. Pada bagian ini, kita akan membahas berbagai jenis pewarisan Python, termasuk pewarisan tunggal, berganda, hierarkis, dan hibrida sebagai kategori terpisah.
Pewarisan tunggal
Pewarisan tunggal terjadi ketika sebuah kelas anak mewarisi dari satu kelas induk, memungkinkannya memperluas fungsionalitas induk. Ini berguna ketika suatu tipe objek berbagi sifat umum dengan kategori yang lebih luas tetapi juga memerlukan atribut atau perilaku tambahan.
Contoh yang mulai kita bahas sebelumnya adalah pewarisan tunggal, tetapi sekarang mari lihat lebih dekat: Dalam sistem manajemen sekolah, semua individu, termasuk siswa, guru, dan staf, berbagi beberapa detail umum seperti name dan ID. Namun, siswa juga memiliki catatan akademik seperti nilai dan mata kuliah yang diambil. Dengan pewarisan tunggal, kita dapat membuat kelas Person untuk atribut bersama dan memperluasnya dengan kelas Student untuk detail akademik.

Pewarisan tunggal. Gambar oleh Penulis
Berikut contoh yang baik dari skenario di atas:
class Person:
"""Represents a general person with basic details."""
def __init__(self, name, id):
self.name = name
self.id = id
def get_details(self):
return f"Name: {self.name}, ID: {self.id}"
class Student(Person):
"""Represents a student, extending the Person class to include academic details."""
def __init__(self, name, id, grade, courses):
super().__init__(name, id)
self.grade = grade
self.courses = courses
def get_details(self):
return f"Name: {self.name}, ID: {self.id}, Grade: {self.grade}, Courses: {', '.join(self.courses)}"
# Example usage in a school system
student = Student("Samuel", 5678, "B+", ["Math", "Physics", "Computer Science"])
print(student.get_details())
Name: Samuel, ID: 5678, Grade: B+, Courses: Math, Physics, Computer Science
Kelas Student mewarisi metode get_details() dari Person tetapi memperluasnya untuk menyertakan grade dan courses. Ini adalah contoh bagus bagaimana pewarisan tunggal mendorong apa yang dikenal sebagai kode modular.
Pewarisan berganda
Pewarisan berganda, mirip pohon keluarga dalam beberapa hal, memungkinkan kelas anak mewarisi dari lebih dari satu kelas induk, menggabungkan atribut dan perilaku dari masing-masing. Ini dapat menimbulkan potensi konflik, yang diselesaikan Python menggunakan method resolution order (MRO).

Pewarisan berganda. Gambar oleh Penulis
Perhatikan berikut:
class Person:
def get_details(self):
return "Details of a person."
class Athlete:
def get_skill(self):
return "Athletic skills."
class Student(Person, Athlete):
pass
# Example usage
student = Student()
print(student.get_details())
print(student.get_skill())
Details of a person.
Athletic skills.
Kita melihat bahwa kelas Student mewarisi atribut dan metode dari Person dan Athlete. Tanpa upaya tambahan, kelas Student memiliki akses ke metode get_details() dari kelas induk Person dan metode get_skill() dari kelas induk Athlete. Kita secara efektif menggabungkan fungsionalitas dari beberapa sumber.
Namun, mewarisi dari beberapa kelas dapat menimbulkan konflik. Bagaimana jika kedua kelas induk mendefinisikan metode atau atribut dengan nama yang sama? Saya menyebutkan sesuatu tentang method resolution order sebelumnya, tetapi sekarang mari saya jelaskan sedikit lagi. Method resolution order menentukan urutan pencarian metode dan atribut pada kelas. MRO mengikuti pendekatan depth-first, dari kiri ke kanan.
Anda dapat melihat MRO dari suatu kelas menggunakan atribut __mro__ atau metode mro():
print(Student.__mro__)
(<class '__main__.Student'>, <class '__main__.Person'>, <class '__main__.Athlete'>, <class 'object'>)
Pewarisan bertingkat, hierarkis, dan hibrida
Python juga mendukung struktur pewarisan yang lebih kompleks. Saya akan menunjukkan ide-ide yang lebih kompleks ini menggunakan contoh yang sama.
Pewarisan bertingkat
Pewarisan bertingkat terjadi ketika kelas anak mewarisi dari kelas anak lainnya, dan kelas anak tersebut mewarisi dari kelas induk. Ini membentuk rantai pewarisan.

Pewarisan bertingkat. Gambar oleh Penulis
Berikut contoh yang baik:
class Person:
def __init__(self, name, id):
self.name = name
self.id = id
def get_details(self):
return f"Name: {self.name}, ID: {self.id}"
class Student(Person):
def __init__(self, name, id, grade):
super().__init__(name, id)
self.grade = grade
def get_details(self):
return f"Name: {self.name}, ID: {self.id}, Grade: {self.grade}"
class GraduateStudent(Student):
def __init__(self, name, id, grade, thesis_title):
super().__init__(name, id, grade)
self.thesis_title = thesis_title
def get_details(self):
return f"Name: {self.name}, ID: {self.id}, Grade: {self.grade}, Thesis: {self.thesis_title}"
# Example usage
grad_student = GraduateStudent("Charlie", 91011, "A", "AI in Healthcare")
print(grad_student.get_details())
Name: Charlie, ID: 91011, Grade: A, Thesis: AI in Healthcare
Di sini, setiap kelas dalam rantai menambahkan sesuatu yang baru: Person mengelola nama dan ID, Student menyertakan nilai, dan GraduateStudent memperkenalkan tesis. Berkat super().__init__(), kita menggunakan kembali logika inisialisasi tanpa menduplikasi kode. Ini efisien, rapi, dan memastikan setiap level dari “tangga pewarisan”, begitu saya menyebutnya, berfungsi.
Pewarisan hierarkis
Dalam pewarisan hierarkis, beberapa kelas anak mewarisi dari satu kelas induk, memungkinkan perilaku bersama di seluruh subkelas dengan atribut unik.

Pewarisan hierarkis. Gambar oleh Penulis
Mari kita lihat contoh yang baik bersama-sama:
class Person:
def __init__(self, name, id):
self.name = name
self.id = id
def get_details(self):
return f"Name: {self.name}, ID: {self.id}"
class Student(Person):
def __init__(self, name, id, grade):
super().__init__(name, id)
self.grade = grade
def get_details(self):
return f"Name: {self.name}, ID: {self.id}, Grade: {self.grade}"
class Teacher(Person):
def __init__(self, name, id, subject):
super().__init__(name, id)
self.subject = subject
def get_details(self):
return f"Name: {self.name}, ID: {self.id}, Subject: {self.subject}"
# Example usage
student = Student("Samuel", 5678, "B+")
teacher = Teacher("Dr. Smith", 1234, "Math")
print(student.get_details())
print(teacher.get_details())
Name: Samuel, ID: 5678, Grade: B+
Dr. Smith, ID: 1234, Subject: Math
Di sini, kelas Person menjadi fondasi, menyediakan atribut dan metode umum (name, id, dan get_details). Kelas Student dan Teacher kemudian memperluas fungsionalitas ini dengan menambahkan properti uniknya (grade dan subject) serta menyesuaikan metode get_details untuk mencerminkan konteks spesifiknya.
Dengan pendekatan ini, fungsionalitas bersama tetap di satu tempat (kelas Person), sementara perilaku khusus dikemas rapi dalam subkelas.
Pewarisan hibrida
Pewarisan hibrida menggabungkan beberapa jenis pewarisan, seperti bertingkat atau berganda, untuk memodelkan hubungan yang lebih kompleks.

Pewarisan hibrida. Gambar oleh Penulis
Mari kita lihat contoh yang menunjukkan kompleksitas pewarisan hibrida.
# Base class
class Person:
def __init__(self, name, id):
self.name = name
self.id = id
def get_details(self):
return f"Name: {self.name}, ID: {self.id}"
# Intermediate class inheriting from the base class
class Employee(Person):
def __init__(self, name, id, position):
super().__init__(name, id)
self.position = position
def get_position(self):
return f"Position: {self.position}"
# Another independent base class
class Athlete:
def __init__(self, sport):
self.sport = sport
def get_sport(self):
return f"Sport: {self.sport}"
# Derived class combining Employee and Athlete
class Student(Employee, Athlete):
def __init__(self, name, id, position, grade, sport):
Employee.__init__(self, name, id, position)
Athlete.__init__(self, sport)
self.grade = grade
def get_grade(self):
return f"Grade: {self.grade}"
# Example usage
student = Student("Samuel", 1234, "Intern", "A", "Soccer")
print(student.get_details()) # From Person
print(student.get_position()) # From Employee
print(student.get_grade()) # From Student
print(student.get_sport()) # From Athlete
Name: Samuel, ID: 1234
Position: Intern
Grade: A
Sport: Soccer
Dalam contoh ini, kelas Student menunjukkan pewarisan hibrida dengan mewarisi atribut dan metode dari Employee (yang sendiri mewarisi dari Person) dan Athlete. Ini menggabungkan pewarisan hierarkis (di mana Employee mewarisi dari Person) dan pewarisan berganda (di mana Student mewarisi dari Employee dan Athlete sekaligus).
Manfaat Pewarisan di Python
Sekarang, saatnya melihat kelebihan dan kekurangannya:
Manfaat pewarisan
-
Dapat digunakan ulang: Dengan pewarisan, Anda dapat menulis kode sekali di kelas induk dan menggunakannya kembali di kelas anak. Menggunakan contoh, baik
FullTimeEmployeemaupunContractordapat mewarisi metodeget_details()dari kelas indukEmployee. -
Kesederhanaan: Pewarisan memodelkan hubungan dengan jelas. Contoh yang baik adalah kelas
FullTimeEmployeeyang “adalah” tipe dari kelas indukEmployee. -
Skalabilitas: Anda juga dapat menambahkan fitur atau kelas anak baru tanpa memengaruhi kode yang ada. Misalnya, kita dapat dengan mudah menambahkan kelas
Internsebagai kelas anak.
Potensi keterbatasan pewarisan
-
Kompleksitas: Ini tidak mengejutkan, tetapi terlalu banyak tingkat pewarisan dapat membuat kode sulit diikuti. Misalnya, jika
Employeememiliki terlalu banyak kelas anak sepertiManager,Engineer,Intern, dan lain-lain, ini bisa menjadi membingungkan. -
Ketergantungan: Perubahan pada kelas induk dapat secara tak sengaja memengaruhi semua subkelas. Jika Anda memodifikasi
Employeemisalnya, hal itu bisa merusakFullTimeEmployeeatauContractor. -
Penyalahgunaan: Menggunakan pewarisan saat bukan pendekatan terbaik dapat memperumit desain. Anda tidak ingin membuat solusi di mana
Carmewarisi dariBoathanya untuk menggunakan kembalimove(). Hubungannya tidak masuk akal.
Teknik Pewarisan Python Lanjutan
Sekarang kita telah membahas dasar-dasarnya, mari lihat beberapa teknik lanjutan. Teknik-teknik seperti penimpaan metode, super(), abstract base classes, dan polimorfisme, meningkatkan fleksibilitas kode dan memungkinkan pola desain yang lebih canggih.
Menimpa metode di Python
Penimpaan metode memungkinkan kelas anak menyediakan implementasi spesifik untuk metode yang sudah didefinisikan di kelas induknya. Ini berguna ketika perilaku yang diwariskan tidak sepenuhnya memenuhi kebutuhan kelas anak.
class Person:
def __init__(self, name, id):
self.name = name
self.id = id
def get_details(self):
return f"Name: {self.name}, ID: {self.id}"
class Student(Person):
def __init__(self, name, id, grade):
super().__init__(name, id)
self.grade = grade
# Overriding the get_details method
def get_details(self):
return f"Name: {self.name}, ID: {self.id}, Grade: {self.grade}"
# Example usage
student = Student("Samuel", 1234, "A")
print(student.get_details())
Name: Samuel, ID: 1234, Grade: A
Di sini, kelas Student menimpa metode get_details() dari kelas Person untuk memberikan implementasi spesifiknya sendiri. Ini memungkinkan kelas anak memiliki perilakunya sendiri sambil tetap menggunakan nama metode yang sama.
Jadi mengapa kita menimpa? Kita menimpa karena ingin menyesuaikan perilaku yang diwariskan dan juga karena kita ingin menyesuaikan fungsionalitas metode induk dengan kebutuhan unik kelas anak.
Menggunakan super() untuk inisialisasi induk
Fungsi super() digunakan untuk memanggil metode di kelas induk dari kelas anak. Ini sangat berguna ketika Anda ingin memperluas atau memodifikasi fungsionalitas metode kelas induk, seperti metode konstruktor __Init__().
Jadi mengapa kita menggunakan fungsi super()? Kita menggunakan fungsi super karena kita ingin memanggil dan menginisialisasi konstruktor kelas induk dan juga karena kita ingin menghindari penyebutan kelas induk secara eksplisit. Ini membantu, terutama dalam kasus pewarisan berganda.
class Person:
def __init__(self, name, id):
self.name = name
self.id = id
class Student(Person):
def __init__(self, name, id, grade):
# Using super() to initialize the parent class
super().__init__(name, id)
self.grade = grade
# Example usage
student = Student("Samuel", 5678, "B+")
print(student.name)
print(student.id)
print(student.grade)
Samuel
5678
B+
Di sini, kelas Student menggunakan super().__init__(name, id) untuk memanggil metode __init__ dari kelas induk Person, sehingga tidak perlu mengulang kode untuk menginisialisasi atribut name dan id. Kelas anak kemudian memperkenalkan atribut grade, yang khusus untuk kelas Student.
Abstract base classes (ABC)
Abstract base class (ABC) adalah kelas yang tidak dapat langsung digunakan untuk membuat objek. Kelas ini dimaksudkan untuk mendefinisikan serangkaian metode umum yang harus diimplementasikan kelas lain. Jadi ABC berguna ketika Anda ingin memastikan metode tertentu selalu ada di kelas anak.
from abc import ABC, abstractmethod
class Person(ABC):
@abstractmethod
def get_details(self):
pass
class Student(Person):
def __init__(self, name, id, grade):
self.name = name
self.id = id
self.grade = grade
def get_details(self):
return f"Name: {self.name}, ID: {self.id}, Grade: {self.grade}"
# Example usage
student = Student("Hamilton", 7890, "A-")
print(student.get_details())
Name: Hamilton, ID: 7890, Grade: A-
Kelas Person di sini adalah kelas abstrak yang mengharuskan kelas anak mana pun untuk mengimplementasikan metode get_details(). Metode ini kemudian diimplementasikan oleh kelas anak, yaitu Student.
Polimorfisme
Polimorfisme berarti banyak bentuk. Dalam Python, ini memungkinkan kelas berbeda menggunakan nama metode yang sama, tetapi masing-masing dapat mengimplementasikan metode itu dengan cara berbeda.
Polimorfisme membantu kita menulis kode yang dapat bekerja dengan objek dari kelas berbeda, meskipun kelas-kelas tersebut memiliki perilaku yang berbeda:
class Person:
def get_details(self):
return "Details of a person."
class Student(Person):
def get_details(self):
return "Details of a student."
class Teacher(Person):
def get_details(self):
return "Details of a teacher."
# Example usage
def print_details(person):
print(person.get_details())
student = Student()
teacher = Teacher()
print_details(student)
print_details(teacher)
Details of a student.
Details of a teacher.
Dalam contoh ini, fungsi print_details() dapat menerima objek apa pun bertipe Person, tetapi akan memanggil metode get_details() yang sesuai berdasarkan apakah objek tersebut adalah Student atau Teacher.
Kesalahan Umum dan Praktik Terbaik
Meskipun pewarisan kuat, mudah untuk menyalahgunakannya. Saya akan berbagi beberapa gagasan agar Anda dapat memaksimalkan konsep-konsep ini.
Menghindari kejutan saat metode ditimpa
Ketika kelas anak menimpa metode dari induknya, perilakunya bisa berubah.
Misalnya, jika kelas induk Employee memiliki metode calculate_pay(), dan kelas anak Manager menimpanya tanpa mempertimbangkan semua skenario, hasil perhitungan gaji bisa menjadi tidak tepat.
Praktik terbaik dalam kasus ini adalah selalu menguji metode yang ditimpa secara menyeluruh dan mendokumentasikan perilakunya.
Memilih antara pewarisan dan komposisi
Saya tahu artikel ini tentang pewarisan, tetapi ini tidak selalu menjadi pendekatan yang tepat. Terkadang, komposisi, yaitu membangun kelas dengan menggabungkan objek alih-alih memperluasnya, mungkin lebih cocok dengan yang Anda kerjakan.
Untuk merangkum perbedaannya secara paling dasar, pikirkan bahwa:
-
Pewarisan mengacu pada hubungan “adalah”. Misalnya, seorang
Manageradalah seorangEmployee. -
Komposisi mengacu pada hubungan “memiliki”. Misalnya, sebuah
Carmemiliki sebuahEngine.
Jadi, bagaimana Anda tahu kapan komposisi adalah pendekatan terbaik untuk digunakan? Gunakan komposisi ketika hubungannya tidak sepenuhnya hierarkis dan/atau ketika Anda ingin mengurangi keterikatan erat antar kelas.
Atau, kita juga bisa mengatakan bahwa, sementara pewarisan memodelkan hubungan, komposisi berfokus pada fungsionalitas. Untuk membantu, pertimbangkan ini:
-
Gunakan pewarisan ketika objek secara alami bersifat hierarkis. Misalnya,
Animal > Bird > Parrot. -
Gunakan komposisi ketika objek berbagi fungsionalitas tetapi tidak saling terkait. Misalnya, sebuah
PrinterdanScannersama-sama menggunakanDeviceManager.
Hindari rantai pewarisan yang dalam
Rantai pewarisan yang dalam (banyak tingkat hubungan induk-anak) dapat membuat kode Anda sulit dibaca dan dipelihara. Ini menjadi masalah karena perubahan pada kelas induk dapat secara tak sengaja memengaruhi banyak kelas anak. Selain itu, proses debugging menjadi kompleks karena perilaku tersebar di banyak tingkat.
Praktik terbaik dalam kasus ini adalah menjaga hierarki tetap dangkal. Juga, pertimbangkan menggunakan komposisi (seperti yang saya sebutkan sebelumnya) atau memecah rantai menjadi hierarki terpisah jika Anda merasa rantainya menjadi terlalu dalam.
Kesimpulan
Pewarisan adalah pilar utama pemrograman berorientasi objek yang memungkinkan pengembang seperti Anda membuat kode yang dapat digunakan kembali, modular, dan skalabel. Jika Anda menguasai pewarisan, Anda akan mendapati lebih mudah menyederhanakan sistem yang kompleks.
Cara yang baik untuk memperdalam pemahaman Anda adalah dengan mencoba membangun struktur pewarisan dalam proyek Anda. Mulailah secara sederhana, lalu bereksperimenlah dengan hierarki yang lebih kompleks untuk melihat bagaimana cara kerjanya dalam praktik.
Jika Anda ingin mengeksplorasi lebih jauh, Anda dapat melihat kursus Programming Paradigm Concepts kami untuk pemahaman yang lebih mendalam tentang pewarisan dan konsep lainnya. Jalur karier Python Developer kami juga merupakan sumber daya yang baik yang menawarkan jalur komprehensif untuk mengembangkan keterampilan pemrograman tingkat lanjut yang akan membekali Anda untuk pengembangan perangkat lunak.

Profesional data dan penulis berpengalaman yang bersemangat memberdayakan calon ahli di bidang data.
FAQ Pewarisan Python
Apa itu pewarisan dalam Python?
Pewarisan di Python adalah mekanisme yang memungkinkan sebuah kelas mewarisi atribut dan metode dari kelas lain, mendorong penggunaan ulang kode dan struktur kelas yang hierarkis.
Bagaimana cara kerja pewarisan Python?
Pewarisan Python bekerja dengan mendefinisikan kelas baru yang mewarisi atribut dan metode dari kelas yang sudah ada, memungkinkan struktur kelas yang hierarkis.
Apa saja jenis pewarisan dalam Python?
Python mendukung beberapa jenis pewarisan, termasuk pewarisan tunggal, berganda, bertingkat, dan hierarkis.
Apa perbedaan antara pewarisan tunggal dan berganda dalam Python?
Pewarisan tunggal melibatkan satu kelas induk, sementara pewarisan berganda memungkinkan sebuah kelas mewarisi dari beberapa kelas induk.
Bagaimana cara mengimplementasikan pewarisan dalam Python?
Implementasikan pewarisan dengan mendefinisikan kelas baru yang menentukan kelas induk dalam definisinya, menggunakan sintaks class ChildClass(ParentClass):.
Apa manfaat menggunakan pewarisan dalam Python?
Pewarisan mendorong penggunaan ulang kode, memungkinkan pembuatan struktur kelas yang hierarkis, dan mendukung polimorfisme, sehingga kode menjadi lebih fleksibel dan mudah dirawat.
Bagaimana cara mengimplementasikan pewarisan berganda dalam Python?
Pewarisan berganda diimplementasikan dengan mendefinisikan kelas yang mewarisi dari lebih dari satu kelas dasar, dan Python menangani resolusi metode menggunakan method resolution order (MRO).

Bayangkan Anda membangun sistem perangkat lunak dengan berbagai peran pengguna seperti siswa, guru, dan administrator. Peran-peran ini berbagi atribut umum seperti nama dan ID, tetapi juga memerlukan fungsi yang unik untuk masing-masing. Alih-alih menduplikasi kode, pewarisan memungkinkan Anda mendefinisikan perilaku bersama dalam kelas induk dan memperluasnya dalam kelas anak yang terspesialisasi.
Dalam artikel ini, kita akan membahas pewarisan Python, mencakup konsep dasar dan lanjutan seperti penimpaan metode dan fungsi
super(), yaitu fungsi bawaan yang mengembalikan objek sementara dari superclass, sehingga Anda dapat mengakses metodenya tanpa harus menyebutkan kelas induk secara eksplisit. Jangan khawatir jika hal ini belum masuk akal, karena kita akan mempelajarinya semua di bawah ini.