Apa perbedaan utama antara Warisan dan Polimorfisme?

172

Saya dihadapkan dengan pertanyaan ini di akhir ujian buku terbuka modul hari ini dan ternyata saya tersesat. Saya sedang membacaHead first Java dan kedua definisi itu tampaknya persis sama. Saya hanya ingin tahu apa perbedaan UTAMA untuk pikiran saya sendiri. Saya tahu ada sejumlah pertanyaan serupa untuk ini tetapi, tidak ada yang saya lihat yang memberikan jawaban pasti.

Darren Burgess
sumber
2
Entah bagaimana terkait dengan pertanyaan ini: Apakah polimorfisme mungkin tanpa warisan
Edwin Dalorzo

Jawaban:

289

Warisan adalah ketika 'kelas' berasal dari 'kelas' yang ada. Jadi, jika Anda memiliki Personkelas, maka Anda memiliki Studentkelas yang meluas Person, Student mewarisi semua hal yang Persondimiliki. Ada beberapa detail di sekitar pengubah akses yang Anda letakkan di bidang / metode di Person, tapi itu ide dasarnya. Misalnya, jika Anda memiliki bidang pribadi di Person, Studenttidak akan melihatnya karena bidang pribadi, dan pribadi tidak terlihat oleh subclass.

Polimorfisme berkaitan dengan bagaimana program memutuskan metode mana yang harus digunakan, tergantung pada jenis benda apa yang dimilikinya. Jika Anda memiliki Person, yang memiliki readmetode, dan Anda memiliki Studentyang meluas Person, yang memiliki implementasi sendiri read, metode mana yang dipanggil ditentukan untuk Anda oleh runtime, tergantung apakah Anda memiliki PersonatauStudent . Agak sulit, tetapi jika Anda melakukan sesuatu seperti

Person p = new Student();
p.read();

metode baca pada Siswa dipanggil. Itulah polimorfisme yang sedang beraksi. Anda dapat melakukan tugas itu karena a Student adalah Person , tetapi runtime cukup pintar untuk mengetahui tipe sebenarnya darip adalah Siswa .

Perhatikan bahwa detail berbeda di antara bahasa. Anda dapat melakukan pewarisan dalam javascript misalnya, tetapi sama sekali berbeda dari cara kerjanya di Jawa.

hvgotcodes
sumber
9
@ hvgtcodes sehingga secara singkat, hubungan superclass-subclass adalah warisan dan konsep implementasi metode yang sama dengan cara yang berbeda di antara kelas induk dan sub-kelasnya, dan menyebutnya berdasarkan situasi adalah Polimorfisme. Apakah saya benar?
Muhammad Raihan Muhaimin
1
@hvgotcodes tetapi mengatakan jika Person's readmetode menggunakan akses pengubah publik, tidak akan Studentbenda dapat mengakses mereka? dan Student s = new Student();bukankah itu akan lebih mudah? Saya masih belum benar-benar mendapatkan manfaat dari Polymporphism sebenarnya.
Scorpiorian83
1
@hvgotcodes Student s = Student baru () akan berfungsi. Tapi katakanlah setelah Anda menulis banyak kode menggunakan ide ini, dan kemudian Anda menyadari bahwa Anda membuat kesalahan. Orang itu sebenarnya bukan siswa, itu adalah seorang guru. Jadi Anda bisa dengan mudah mengubah dari Orang p = Siswa baru () menjadi Orang p = Guru baru (), maka itu akan membuat hidup Anda jauh lebih sederhana.
munmunbb
Pertanyaan saya di sini adalah mengapa Anda ingin menggunakan Person p = new Student();bukan Student p = new Student();?
PerfectContrast
@PerfectContrast Saya pikir ini berguna ketika Anda ingin memiliki siswa, sopir, guru dll sebagai Orang dan Anda mengelompokkan mereka di bawah Daftar atau sesuatu. Jadi, ketika Anda memanggil 'baca' untuk semua, semua orang memanggil metode 'baca' mereka sendiri.
savante
205

Inheritance mengacu pada penggunaan struktur dan perilaku kelas super dalam subkelas.

Polimorfisme mengacu pada mengubah perilaku kelas super di subkelas.

Ted Hopp
sumber
5
Apakah jawaban ini menyiratkan bahwa polimorfisme memerlukan pewarisan?
jaco0646
6
@ jaco0646 - Dalam konteks Jawa, saya kira begitu. (Dalam bahasa lain, mungkin tidak terlalu banyak.) Perhatikan bahwa "kelas super" dan "subkelas" digunakan secara longgar di sini. Polimorfisme juga bisa berarti warisan perilaku yang ditentukan (tetapi tidak diimplementasikan) dalam suatu antarmuka.
Ted Hopp
1
@AlirezaRahmani - Saya tidak mengerti komentar Anda. Apakah maksud Anda bahwa pewarisan tidak melibatkan mewarisi sifat dan perilaku? Itu akan bertentangan dengan bagaimana Java (dan sebagian besar berbasis kelas, bahasa berorientasi objek) mendefinisikan warisan. Dari Spesifikasi Bahasa Jawa, §8.4.8 : "A kelas C mewarisi dari superclass langsungnya semua metode konkret m(keduanya staticdan instance) dari superclass yang ..." (diikuti dengan perincian tentang pewarisan). Kedengarannya seperti "code reuse" bagi saya.
Ted Hopp
@TedHopp Inheritance pada dasarnya adalah alat polimorfik, tetapi beberapa orang, jauh di bawah risiko kemudian, mencoba menggunakannya sebagai cara menggunakan kembali / berbagi kode. Alasannya adalah "baik jika saya mewarisi maka saya mendapatkan semua metode gratis", tetapi mengabaikan fakta bahwa dua kelas ini berpotensi tidak memiliki hubungan polimorfik.
Alireza Rahmani Khalili
1
@AlirezaRahmani - Di Jawa (yang ditanyakan secara khusus oleh OP, menurut tag), warisan kelas pasti melibatkan perilaku pewarisan. Itu bagian dari definisi bahasa. Fakta bahwa ini dapat disalahgunakan seperti yang Anda gambarkan adalah salah satu kelemahan Jawa. (Kelemahan terkait melibatkan mendeklarasikan kelas untuk mengimplementasikan antarmuka hanya untuk mengimpor konstanta yang didefinisikan dalam antarmuka. Akhirnya desainer Jawa diperkenalkan import staticuntuk menghilangkan penyalahgunaan antarmuka.) Untuk polimorfisme murni di Jawa, alat yang digunakan adalah antarmuka, bukan warisan kelas.
Ted Hopp
63

Polimorfisme : Kemampuan untuk memperlakukan objek dari berbagai jenis dengan cara yang serupa. Contoh: Jerapah dan Buaya adalah Hewan, dan hewan juga bisa Move. Jika Anda memiliki instance dari Animalmaka Anda dapat memanggil Movetanpa mengetahui atau peduli apa jenis binatang itu.

Warisan : Ini adalah salah satu cara untuk mencapai Polimorfisme dan penggunaan kembali kode secara bersamaan.

Bentuk lain dari polimorfisme : Ada cara lain untuk mencapai polimorfisme, seperti antarmuka, yang hanya menyediakan polimorfisme tetapi tidak ada kode yang digunakan kembali (kadang-kadang kode sangat berbeda, seperti Moveuntuk Ular akan sangat berbeda dariMove untuk Anjing, dalam hal ini sebuah Antarmuka akan menjadi pilihan polimorfik yang lebih baik dalam kasus ini.

Dalam bahasa dinamis lain, polimorfisme dapat dicapai dengan Duck Typing, yaitu kelas-kelas yang bahkan tidak perlu berbagi kelas dasar atau antarmuka yang sama, mereka hanya perlu metode dengan nama yang sama. Atau bahkan lebih dinamis seperti Javascript, Anda bahkan tidak perlu kelas sama sekali, hanya sebuah objek dengan nama metode yang sama dapat digunakan secara polimorfik.

Davy8
sumber
17

Perbedaan utama adalah polimorfisme adalah hasil khusus dari pewarisan. Polimorfisme adalah di mana metode yang akan dipanggil ditentukan pada saat runtime berdasarkan pada jenis objek. Ini adalah situasi yang terjadi ketika Anda memiliki satu kelas yang diwarisi dari yang lain dan mengganti metode tertentu. Namun, dalam pohon pewarisan normal, Anda tidak perlu mengganti metode apa pun dan karenanya tidak semua pemanggilan metode harus polimorfik. Apakah itu masuk akal? Ini masalah yang sama dengan semua kendaraan Ford adalah mobil, tetapi tidak semua mobil Ford (walaupun tidak cukup ....).

Selain itu, polimorfisme berkaitan dengan pemanggilan metode sedangkan pewarisan juga menggambarkan anggota data, dll.

Chris Thompson
sumber
12

Di Jawa, keduanya terkait erat. Ini karena Java menggunakan teknik untuk pemanggilan metode yang disebut "pengiriman dinamis". Jika saya punya

public class A {
  public void draw() { ... }
  public void spin() { ... }
}

public class B extends A {
  public void draw() { ... }
  public void bad() { ... }
}

...

A testObject = new B();

testObject.draw(); // calls B's draw, polymorphic
testObject.spin(); // calls A's spin, inherited by B
testObject.bad(); // compiler error, you are manipulating this as an A

Kemudian kita melihat bahwa B mewarisi spindari A. Namun, ketika kita mencoba memanipulasi objek seolah-olah itu tipe A, kita masih mendapatkan perilaku B untuk draw. Itudraw perilaku polimorfik.

Dalam beberapa bahasa, polimorfisme dan pewarisan tidak begitu erat hubungannya. Dalam C ++, misalnya, fungsi yang tidak dideklarasikan virtual diwariskan, tetapi tidak akan dikirim secara dinamis, jadi Anda tidak akan mendapatkan perilaku polimorfik itu bahkan ketika Anda menggunakan warisan.

Dalam javascript, setiap panggilan fungsi dikirim secara dinamis dan Anda memiliki ketikan yang lemah. Ini berarti Anda dapat memiliki banyak objek yang tidak terkait, masing-masing dengan miliknya sendiri draw, memiliki fungsi yang berulang di atasnya dan memanggil fungsi tersebut, dan masing-masing akan berperilaku baik-baik saja. Anda akan memiliki undian polimorfik Anda sendiri tanpa membutuhkan warisan.

ccoakley
sumber
12

Polimorfisme: Misalkan Anda bekerja di perusahaan yang menjual pena. Jadi Anda membuat kelas yang sangat bagus yang disebut "Pena" yang menangani semua yang perlu Anda ketahui tentang pena. Anda menulis semua jenis kelas untuk penagihan, pengiriman, pembuatan faktur, semua menggunakan kelas Pena. Seorang bos datang dan berkata, "Berita bagus! Perusahaan ini berkembang dan kami menjual Buku & CD sekarang!" Bukan berita bagus karena sekarang Anda harus mengubah setiap kelas yang menggunakan Pena untuk juga menggunakan Buku & CD. Tetapi bagaimana jika Anda awalnya membuat antarmuka yang disebut "SellableProduct", dan Pen mengimplementasikan antarmuka ini. Maka Anda bisa menulis semua pengiriman, faktur, dll. Kelas untuk menggunakan antarmuka itu, bukan Pen. Sekarang yang harus Anda lakukan adalah membuat kelas baru bernama Book & CompactDisc yang mengimplementasikan antarmuka SellableProduct. Karena polimorfisme, semua kelas lain dapat terus bekerja tanpa perubahan! Masuk akal?

Jadi, itu berarti menggunakan Warisan yang merupakan salah satu cara untuk mencapai polimorfisme.

Polimorfisme dapat dimungkinkan dalam suatu kelas / antarmuka tetapi Warisan selalu di antara 2 atau lebih kelas / antarmuka. Warisan selalu sesuai dengan hubungan "is-a" sedangkan itu tidak selalu dengan Polymorphism (yang dapat menyesuaikan keduanya "is-a" / "has-a".

AmitK
sumber
6

Warisan lebih merupakan hal yang statis (satu kelas memperluas yang lain) sementara polimorfisme adalah hal yang dinamis / runtime (objek berperilaku sesuai dengan tipe dinamis / runtime bukan tipe statis / deklarasi).

Misalnya

// This assignment is possible because B extends A
A a = new B();
// polymorphic call/ access
a.foo();

-> Meskipun tipe statik / deklarasi a adalah A, tipe dinamis / runtime aktual adalah B dan karenanya a.foo () akan menjalankan foo sebagaimana didefinisikan dalam B bukan dalam A.

Puce
sumber
3

Polimorfisme adalah suatu pendekatan untuk mengekspresikan perilaku umum antara jenis-jenis objek yang memiliki sifat yang sama. Hal ini juga memungkinkan variasi sifat-sifat tersebut dibuat melalui penggantian. Warisan adalah cara untuk mencapai polimorfisme melalui hierarki objek di mana objek mengekspresikan hubungan dan perilaku abstrak. Ini bukan satu-satunya cara untuk mencapai polimorfisme. Prototipe adalah cara lain untuk mengekspresikan polimorfisme yang berbeda dari warisan. JavaScript adalah contoh bahasa yang menggunakan prototipe. Saya membayangkan ada cara lain juga.

laz
sumber
3

Warisan adalah konsep yang terkait dengan penggunaan kembali kode. Sebagai contoh jika saya memiliki kelas induk katakan Animaldan berisi atribut dan metode tertentu (untuk contoh ini katakan makeNoise()dan sleep()) dan saya membuat dua kelas anak yang disebut Dogdan Cat. Karena kedua anjing dan kucing tidur dengan cara yang sama (saya akan berasumsi), tidak perlu menambahkan lebih banyak fungsionalitas ke sleep()metode dalam Dogdan Catsubkelas yang disediakan oleh kelas induk Animal. Namun, Doggonggongan danCat mengeong jadi meskipunAnimalkelas mungkin memiliki metode untuk membuat suara, anjing dan kucing membuat suara yang berbeda relatif satu sama lain dan hewan lainnya. Dengan demikian, ada kebutuhan untuk mendefinisikan kembali perilaku itu untuk tipe spesifik mereka. Demikianlah definisi polimorfisme. Semoga ini membantu.

pembalas12
sumber
3

Dokumentasi Oracle mengutip perbedaannya dengan tepat.

inheritance: Kelas mewarisi bidang dan metode dari semua superclasses, baik langsung atau tidak langsung. Subclass dapat menimpa metode yang diwarisi, atau dapat menyembunyikan bidang atau metode yang diwarisi . (Perhatikan bahwa menyembunyikan bidang umumnya merupakan praktik pemrograman yang buruk.)

polimorfisme: polimorfisme mengacu pada prinsip dalam biologi di mana suatu organisme atau spesies dapat memiliki berbagai bentuk atau tahapan. Prinsip ini juga dapat diterapkan pada pemrograman dan bahasa berorientasi objek seperti bahasa Java. Subclass dari suatu kelas dapat mendefinisikan perilaku unik mereka sendiri dan berbagi fungsi yang sama dari kelas induknya.

polimorfisme tidak berlaku untuk bidang.

Posting terkait:

Polimorfisme vs Overriding vs Overloading

Ravindra babu
sumber
1

Polimorfisme adalah efek dari warisan . Itu hanya bisa terjadi di kelas yang saling memperpanjang. Hal ini memungkinkan Anda untuk memanggil metode kelas tanpa mengetahui jenis kelas yang tepat. Juga, polimorfisme memang terjadi pada saat run time .

Misalnya, contoh polimorfisme Java:

masukkan deskripsi gambar di sini

Warisan memungkinkan kelas turunan berbagi antarmuka dan kode kelas dasar mereka. Itu terjadi pada waktu kompilasi .

Misalnya, Semua Kelas di Platform Java adalah Keturunan Objek (image courtesy Oracle):

masukkan deskripsi gambar di sini

Untuk mempelajari lebih lanjut tentang pewarisan Java dan polimorfisme Java

Johnny
sumber
0

Warisan adalah ketika kelas A mewarisi semua metode / bidang nonstatis yang dilindungi / dari semua orang tuanya hingga Object.

Cosmin Cosmin
sumber
0

Jika Anda menggunakan JAVA, sesederhana ini:

Polimorfisme menggunakan metode yang diwariskan tetapi "Mengesampingkan" mereka untuk melakukan sesuatu yang berbeda (atau sama jika Anda memanggil super sehingga secara teknis tidak akan menjadi polimorfik).

Koreksi saya jika saya salah.

Oliver Dixon
sumber
0

Tujuan utama polimorfisme : Untuk membuat variabel referensi ke kelas super dan memegang objek subclass => suatu objek dapat melakukan banyak perilaku .

Dalam pewarisan , subkelas mewarisi sifat-sifat kelas super .

satya
sumber
0

Warisan adalah jenis polimorfisme, Tepatnya sebenarnya pewarisan adalah polimorfisme dinamis. Jadi, ketika Anda menghapus warisan Anda tidak bisa menimpa lagi.

Alireza Rahmani Khalili
sumber
0

Dengan Inheritance , implementasinya didefinisikan dalam superclass - sehingga perilaku diwarisi.

class Animal
{
  double location;
  void move(double newLocation)
  {
    location = newLocation;
  }
}

class Dog extends Animal;

Dengan Polymorphism , implementasinya didefinisikan dalam subclass - jadi hanya antarmuka yang diwarisi.

interface Animal
{
  void move(double newLocation);
}

class Dog implements Animal
{
  double location;
  void move(double newLocation)
  {
    location = newLocation;
  }
}
mherzl
sumber
0

Polimorfisme dicapai oleh Pewarisan di Java.

├── Animal
└── (instances)
    ├── Cat
    ├── Hamster
    ├── Lion
    └── Moose

├── interface-for-diet
   ├── Carnivore
   └── Herbivore
├── interface-for-habitat
   ├── Pet
   └── Wild

public class Animal {
    void breath() {
    };
}

public interface Carnivore {
    void loveMeat();
}

public interface Herbivore {
    void loveGreens();
}

public interface Pet {
    void liveInside();
}

public interface Wild {
    void liveOutside();
}

public class Hamster extends Animal implements Herbivore, Pet {

    @Override
    public void liveInside() {
        System.out.println("I live in a cage and my neighbor is a Gerbil");
    }

    @Override
    public void loveGreens() {
        System.out.println("I eat Carrots, Grapes, Tomatoes, and More");
    }
}

public class Cat extends Animal implements Carnivore, Pet {
    @Override
    public void liveInside() {
        System.out.println("I live in a cage and my neighbr is a Gerbil");
    }

    @Override
    public void loveMeat() {
        System.out.println("I eat Tuna, Chicken, and More");
    }
}

public class Moose extends Animal implements Herbivore, Wild {

    @Override
    public void liveOutside() {
        System.out.println("I live in the forest");
    }

    @Override
    public void loveGreens() {
        System.out.println("I eat grass");
    }
}

public class Lion extends Animal implements Carnivore, Wild {

    @Override
    public void liveOutside() {
        System.out.println("I live in the forest");
    }

    @Override
    public void loveMeat() {
        System.out.println("I eat Moose");
    }
}

Hamsterkelas mewarisi struktur dari Animal, Herbivoredan Petuntuk menunjukkan behaviorisme Polimorfik hewan peliharaan.

Catkelas mewarisi struktur dari Animal, Carnivoredan Petjuga menunjukkan behaviorisme Polimorfik hewan peliharaan.

nabster
sumber