Bagaimana saya bisa menjelaskan manfaat Warisan? [Tutup]

16

Ketika mencoba menjelaskan konsep Warisan dalam OOP, contoh umum adalah contoh mamalia. IMHO, ini benar-benar contoh yang buruk, karena akan mengarahkan pemula untuk menggunakan konsep ini dengan cara yang salah. Dan terlebih lagi, itu bukan desain umum yang akan mereka hadapi dalam pekerjaan desain sehari-hari mereka.

Jadi, apa yang akan menjadi masalah yang bagus, sederhana dan konkret yang diselesaikan dengan menggunakan Inheritance?

Pierre Watelet
sumber
1
"contoh umum adalah mamalia"? Apa maksudmu? Bisakah Anda memberikan tautan, referensi, atau penawaran untuk ini?
S.Lott
3
Apa yang akan menjadi contoh nyata terbaik untuk menjelaskan kegunaan dana perwalian anak-anak Warisan = Bill Gates?
Martin Beckett
1
@ Chris: bagaimana pertanyaan ini tidak konstruktif? Apakah Anda menyatakan bahwa satu penanya dan 14 penjawab menghabiskan waktu semua orang?
Dan Dascalescu
@DanDascalescu - ditutup dua tahun lalu sebagai tanggapan atas bendera yang menyatakan "tolong pertimbangkan menutup sebagai tidak konstruktif: menilai dengan jawaban yang menumpuk di atasnya, ini terlihat seperti pertanyaan daftar / jajak pendapat yang khas". Jika menurut Anda ini salah, edit untuk membuatnya jelas bukan dan biarkan komunitas memutuskan melalui antrean ulasan buka kembali.
ChrisF

Jawaban:

15

Tidak ada yang salah dengan contoh akademis murni seperti mamalia. Saya juga suka contoh persegi panjang / persegi karena ini menunjukkan mengapa taksonomi dunia nyata tidak selalu secara langsung diterjemahkan ke hubungan warisan yang Anda harapkan.

Menurut pendapat saya, contoh setiap hari yang paling kanonik adalah toolkit GUI. Ini adalah sesuatu yang digunakan semua orang, tetapi pemula mungkin tidak beralasan tentang cara mereka bekerja di bawah tenda. Anda dapat berbicara tentang perilaku apa yang umum untuk semua wadah, semua widget, acara, dll. Tanpa memerlukan pengetahuan terperinci tentang implementasi yang diberikan.

Karl Bielefeldt
sumber
5
+1 untuk toolkit GUI ... dan saya juga menyukai contoh bentuk, dengan satu Bentuk sebagai basis dengan gambar minimal () dan bentuk turunan dengan gambar kustom () s.
yati sagade
14

Contoh dunia nyata saya adalah model domain dari aplikasi SDM yang sederhana. Saya katakan bahwa kita dapat membuat kelas dasar yang disebut Karyawan , karena tentu saja, manajer adalah karyawan juga.

public class Employee
{
    public string FirstName { get; set; }

    public string LastName { get; set; }

    public int Code { get; set; }

    public string GetInsuranceHistory()
    {
        // Retrieving insurance history based on employee code.
    }
}

Lalu saya jelaskan bahwa pengembang adalah karyawan , penguji adalah karyawan , manajer proyek adalah karyawan . Dengan demikian mereka semua dapat mewarisi dari kelas karyawan.

Saeed Neamati
sumber
2
Untuk menunjukkan keunggulan warisan, mungkin menarik untuk juga menunjukkan perbedaan pengembang dari karyawan. Jika tidak ada perbedaan, maka tidak perlu membuat kelas Pengembang sama sekali.
David
3
Sepertinya Employeebisa menjadi abstractkelas juga.
StuperUser
+1 ini adalah contoh yang digunakan sebagian besar guru saya dan saya sangat menyukainya. itu masuk akal dan memberikan contoh dunia nyata tentang cara menggunakan warisan.
David Peterman
18
Kecuali ini tidak pernah berhasil dalam praktik karena selalu ada setidaknya satu orang yang perlu menjadi a Developerdan a Tester. Situasi serupa lainnya adalah basis data kontak di mana Anda memiliki Customerdan Supplier, tetapi karena siapa pun yang telah membuat sistem seperti itu akan memberi tahu Anda, selalu ada kasus di mana a Companyadalah keduanya. Itulah sebabnya sebagian besar contoh ini membawa Anda ke arah yang salah.
Scott Whitlock
11

Meringkas apa yang bervariasi ... menunjukkan kepada mereka pola metode templat , itu menunjukkan kegunaan warisan dengan menempatkan perilaku umum di kelas dasar dan merangkum berbagai perilaku dalam subkelas.

UI controlsdan Streamsjuga merupakan contoh yang sangat baik untuk kegunaan warisan.

Elang
sumber
Saya pikir pabrik itu akan menjadi contoh yang lebih baik.
Let_Me_Be
1
@Let_Me_Be: Saya pikir hubungan antara pabrik dan pewarisan sifatnya tidak langsung. Tentu, ini menghasilkan tipe konkret dan mengembalikan tipe abstrak / dasar, tetapi juga bisa mengembalikan hanya tipe antarmuka! Imho itu tidak lebih baik dari contoh hewan klasik.
Falcon
@Let_Me_Be: Juga, pabrik abstrak adalah contoh yang cukup kompleks yang melibatkan hierarki pewarisan yang berbeda (satu untuk item, satu untuk pabrik). Saya pikir ini adalah penggunaan warisan yang baik, tetapi bukan contoh yang baik dan sederhana.
Falcon
3

Ingat

Setiap contoh objek adalah contoh konkret tentang manfaat warisan!

Jika yang Anda maksud adalah pewarisan kelas secara khusus , sekarang Anda berada di dunia taksonomi, dan itu akan sangat bervariasi menurut tujuan sistem yang menggunakannya. Contoh hewan / mamalia menggunakan taksonomi umum dan mudah-mudahan akrab dari biologi, tetapi itu (seperti yang Anda sebutkan) hampir tidak berguna untuk sebagian besar masalah pemrograman.

Jadi cobalah sesuatu yang universal: pengertian Program. Setiap program dimulai, dijalankan, dan berakhir. Setiap program memiliki nama, dan parameter baris perintah opsional. Jadi kelas Program dasar akan sangat berguna, untuk memulai eksekusi, mengambil dan memproses argumen baris perintah, menjalankan logika utama, dan mematikan dengan anggun.

Itulah sebabnya begitu banyak bahasa pemrograman berorientasi objek menyediakan kelas Program, atau sesuatu yang berperilaku persis seperti kelas Program.

Steven A. Lowe
sumber
Jadi, Anda memprogram program yang memiliki banyak program di dalamnya? :) Dalam pengalaman saya, Programm Objects hampir selalu lajang yang tidak memiliki warisan, jadi imho mereka bukan contoh terbaik.
keppla
@keppla: apakah Anda pernah menggunakan Java atau .NET? .NET memiliki kelas Program eksplisit, Java's implisit. Mereka bukan orang lajang
Steven A. Lowe
saya menggunakan Java, sekitar versi 1.4.2. Saat itu, hanya ada void main statis, jadi saya kira itu berubah sedikit. Apa yang menjadi alasan khas untuk memiliki lebih dari satu instance dari kelas Programm?
keppla
@keppla: static static void main secara implisit membuat kelas entri mewakili program. Setiap pengguna yang menjalankan program Anda membuat instance baru. Saat ini, saya memiliki tiga contoh menjalankan Google Chrome, empat dokumen Word, tiga Notes, dan dua Windows Explorers. Jika mereka semua lajang saya tidak akan pernah bisa melakukan itu.
Steven A. Lowe
1
Saya pikir Anda sedikit memperluas definisi. class Programm { public static void main(String[] args) { system.out.println('hello world'); }}adalah program Java minimal. Ketika saya menyebutnya, tidak ada instance Program. Program tidak mewarisi dari apa pun. Ketika saya memulai 3 Proses (seperti yang Anda lakukan dengan crhome), mungkin ada 3 Program, tetapi di masing-masing bidang memori, masih ada hanya satu Program. Imho, singleton menyiratkan 'Hanya satu Mesin Virtual per Proses', bukan per Mesin. Jika demikian, mustahil membuat lajang, tidak ada yang menghentikan Anda menjalankan kode apa pun dua kali.
keppla
3

Saya bekerja dengan kamera di tempat kerja. Kami memiliki perangkat yang terhubung ke model yang berbeda, jadi kami memiliki "kelas kamera" yang abstrak dan setiap model mewarisi dari kelas ini untuk mendukung fungsionalitas spesifik dari kamera itu. Ini adalah contoh dunia nyata dan tidak sulit untuk dipahami.

Lucas
sumber
2
Ini mungkin rusak jika Anda punya, misalnya model yang a Cameradan a Phone(seperti yang kita semua lakukan di saku sekarang). Kelas dasar mana yang harus diwarisi? Atau bukankah seharusnya hanya mengimplementasikan ICameradan IPhoneantarmuka saja? (ha ha)
Scott Whitlock
2
@Scott: Anda tidak dapat mengimplementasikan antarmuka IPhone, atau Anda akan dituntut oleh Apple.
Mason Wheeler
3

Contoh Unsur Kimia

Ini adalah contoh lain yang muncul dari otak saya:

elemen kelas_
{
    Berat atom ganda; // Berat atom unsur
    nomor atom ganda; // Jumlah atom elemen
    Properti String; // Properti elemen
    // Lainnya, jika ada
}


class Isotop extends Element_ // Mungkin ada isotop elemen
{
    halflife setengah;
   // Lainnya jika ada

}
Menandai
sumber
2
Meskipun atomicNumber bisa (harus?) Mungkin bilangan bulat ...
Andrew
Saya tidak akan menggunakan warisan untuk itu. isotopebukan kasus khusus Elemenet. Saya lebih suka memiliki Elementproperti Isotope.
CodesInChaos
2

Contoh dunia nyata hampir selalu salah karena mereka memberikan contoh di mana selalu ada kemungkinan sesuatu menjadi keduanya TypeAdan TypeBtetapi hierarki pewarisan tunggal dari banyak bahasa tidak memungkinkan itu.

Semakin banyak saya memprogram, semakin saya semakin jauh dari warisan.

Bahkan kata "pewarisan" tidak digunakan dengan benar di sini. Misalnya, Anda mewarisi sekitar 50% dari sifat ayah Anda dan 50% dari sifat ibu Anda. Sungguh DNA Anda adalah komposisi setengah DNA ayahmu dan setengah DNA ibumu. Itu karena biologi sebenarnya lebih menyukai komposisi daripada warisan , dan Anda juga harus.

Cukup menerapkan antarmuka, atau bahkan lebih baik, "mengetik bebek", ditambah injeksi ketergantungan, adalah hal yang jauh lebih baik untuk mengajar orang-orang yang baru mengenal pemrograman berorientasi objek.

Scott Whitlock
sumber
1

Saya hanya akan menunjukkan kepada mereka contoh kehidupan nyata. Misalnya, di sebagian besar kerangka kerja UI Anda berasal dari semacam kelas "Dialog" atau "Jendela" atau "Kontrol" untuk membuatnya sendiri.

Nemanja Trifunovic
sumber
1

Contoh yang bagus adalah fungsi bandingkan dalam penyortiran:

template<class T>
class CompareInterface {
public:
   virtual bool Compare(T t1, T t2) const=0;
};
class FloatCompare : public CompareInterface<float> { };
class CompareImplementation : public FloatCompare {
public:
   bool Compare(float t1, float t2) const { return t1<t2; }
};
template<class T>
void Sort(T*array, int size, CompareInterface<T> &compare);

Satu-satunya masalah adalah para pemula terlalu sering berpikir kinerja lebih penting daripada kode yang baik ...

tp1
sumber
0

Contoh dunia nyata saya adalah kendaraan:

public class Vehicle
{
    public Vehicle(int doors, int wheels)
    {
        // I describe things that should be
        // established and "unchangeable" 
        // when the class is first "made"
        NumberOfDoors = doors;
        NumberOfWheels = wheels;
    }

    public void RollWindowsUp()
    {
        WindowsUp = true;
    }

    // I cover modifiers on properties to show
    // how to protect certain things from being
    // overridden
    public int NumberOfDoors { get; private set; }
    public int NumberOfWheels { get; private set; }

    public string Color { get; set; }
    public bool WindowsUp { get; set; }
    public int Speed { get; set; }
}

public class Car : Vehicle
{
    public Car : base(4, 4)
    {

    }
}

public class SemiTruck : Vehicle
{
    public SemiTruck : base(2, 18)
    {

    }
}

Contoh ini bisa sedetail yang Anda mau, dan ada semua jenis properti yang melekat pada kendaraan untuk menjelaskan penggunaan pengubah apa pun yang mungkin ingin Anda ajarkan.

Joel Etherton
sumber
2
Saya selalu benci menggunakan kendaraan sebagai contoh, karena tidak mendapatkan programmer baru lebih dekat untuk memahami bagaimana warisan dapat digunakan untuk meningkatkan kode. Kendaraan adalah mesin yang sangat rumit yang mengingatkan banyak ide non-abstrak dalam benak non-programmer. Mencoba menggambarkan ini dalam kode membuat pemula rata-rata percaya bahwa ada banyak detail yang ditinggalkan dari contoh dan memberikan perasaan bahwa mereka tidak lebih dekat untuk mendapatkan sesuatu untuk bekerja. Saya mengatakan ini dari pengalaman, karena itulah yang saya rasakan ketika seseorang mencoba menggunakan kendaraan untuk menjelaskannya kepada saya.
riwalk
@ Stargazer712: Saya menggunakan kendaraan terutama karena mereka bisa serumit atau sesederhana yang Anda suka. Saya serahkan pada penilaian instruktur untuk menentukan tingkat muridnya. Saya menjelaskan OOP dasar kepada istri saya (yang tidak memiliki pengalaman pemrograman) menggunakan properti sederhana dari sebuah kendaraan yang menggambarkan dasar-dasar umum. Semua kendaraan memiliki pintu, semua kendaraan memiliki roda, dll. Contoh objek tidak dapat disalahkan karena rencana pelajaran yang buruk.
Joel Etherton
istrimu tidak mencoba menulis kode. Saya dapat dengan aman mengatakan bahwa contoh kendaraan tidak melakukan apa pun untuk membantu saya memahami warisan. Apa pun yang Anda gunakan untuk menggambarkan warisan, itu harus lengkap dan praktis . Tujuannya bukan untuk menggambarkannya sedemikian rupa sehingga non-programmer dapat memahaminya. Tujuannya adalah untuk mendeskripsikannya sedemikian rupa sehingga seorang programmer pemula dapat menggunakannya , dan satu-satunya cara untuk melakukannya adalah dengan menunjukkan contoh-contoh pemula tentang bagaimana seorang programmer profesional akan menggunakannya.
riwalk
@ Stargazer712: Saya akan menempatkan ketidakmampuan Anda untuk awalnya memahami warisan pada rencana pelajaran yang buruk. Saya juga menggunakan kendaraan untuk menjelaskan warisan kepada junior yang bekerja sama dengan saya, dan saya tidak pernah memiliki masalah dengan konsep yang muncul. Menurut pendapat saya, jika sebuah rencana pelajaran dibuat secara menyeluruh dan benar, objek kendaraan lengkap dan praktis. 1 orang acak di internet tidak akan mengubah itu dalam menghadapi 30 atau lebih magang dan junior yang saya ajari OOP. Jika Anda tidak menyukai kendaraan, turunkan suara dan lanjutkan.
Joel Etherton
Terserah Anda ....
riwalk
0

Contoh non-mamalia, non-burung, non-ikan ini dapat membantu:

public abstract class Person {

    /* this contains thing all persons have, like name, gender, home addr, etc. */

    public Object getHomeAddr() { ... }

    public Person getName() { ... }

}

public class Employee extends Person{

    /* It adds things like date of contract, salary, position, etc */

    public Object getAccount() { ... }

}

public abstract class Patient extends Person {
    /* It adds things like medical history, etc */
}

Kemudian

public static void main(String[] args) {

    /* you can send Xmas cards to patients and employees home addresses */

    List<Person> employeesAndPatients = Factory.getListOfEmployeesAndPatients();

    for (Person p: employeesAndPatients){
        sendXmasCard(p.getName(),p.getHomeAddr());
    }

    /* or you can proccess payment to employees */

    List<Employee> employees = Factory.getListOfEmployees();

    for (Employee e: employees){
        proccessPayment(e.getName(),e.getAccount());
    }       

}

CATATAN: Hanya saja, jangan katakan rahasianya: Orang itu memperpanjang mamalia.

Tulains Córdova
sumber
1
Bekerja sampai salah satu karyawan Anda juga sabar.
Scott Whitlock
Dalam hal ini, saya pikir lebih masuk akal untuk mendeklarasikan Pasien dan Karyawan sebagai antarmuka daripada kelas abstrak. Itu memberi Anda fleksibilitas memiliki Orang mengimplementasikan beberapa antarmuka.
Jin Kim
@ JinKim - Saya setuju sepenuhnya, itu pendekatan yang lebih baik.
Scott Whitlock
@ JinKim Mereka tidak eksklusif. Anda memperlakukan seseorang sebagai karyawan atau sebagai pasien pada waktu tertentu, tetapi tidak pada waktu yang sama. Dua antarmuka OK tapi ketika apa yang Anda sebut kelas konkret mengimplementasikan keduanya, EmployeePatient Berapa banyak kombinasi yang akan Anda miliki?
Tulains Córdova
Anda dapat memanggil kelas konkret apa pun yang Anda inginkan. Jika kode hanya berharap untuk berurusan dengan Karyawan, Anda menyatakan referensi sebagai Karyawan. (mis. Karyawan Karyawan = Orang baru ();) Jika kode hanya berharap untuk berurusan dengan Pasien, Anda menyatakan referensi sebagai Pasien. Jarang Anda ingin mendeklarasikan referensi secara langsung sebagai kelas konkret.
Jin Kim
0

Bagaimana dengan hierarki ekspresi aljabar. Baik karena termasuk warisan dan komposisi:

+--------------------+------------------------+
| Expression         |<------------------+    |
+--------------------+----------+        |    |
| + evaluate(): int  |<---+     |        |    |
+--------------------+    |     |        |    |
          ^               |     |        |    |
          |               |     |        |    |
   +--------------+  +---------------+  +-------------+  ...
   | Constant     |  | Negation      |  | Addition    |
   +--------------+  +---------------+  +-------------+
   | -value: int  |  |               |  |             |
   +--------------+  +---------------+  +-------------+
   | +evaluate()  |  | +evaluate()   |  | +evaluate() |
   | +toString()  |  | +toString()   |  | +toString() |
   +--------------+  +---------------+  +-------------+

   Addition(Constant(5), Negation(Addition(Constant(3),Constant(2))))
   (5 + -(3 + 2)) = 0

Dengan pengecualian ekspresi akar Konstan, semua ekspresi lainnya adalah Ekspresi dan mengandung satu atau lebih ekspresi.

edalorzo
sumber
-1

Saya akan menggunakan burung sebagai contoh

seperti ayam, bebek, elang

Saya akan menjelaskan keduanya memiliki cakar, kecupan, dan sayap tetapi atribut mereka berbeda.

Ayam tidak bisa terbang, tidak bisa berenang, bisa makan cacing, bisa makan biji-bijian

Bebek tidak bisa terbang, bisa berenang, bisa makan biji-bijian, tidak bisa makan cacing

Elang bisa terbang, tidak bisa berenang, bisa makan cacing, tidak bisa makan biji-bijian

Raju yourPepe
sumber
4
Saya pernah membaca bahwa komposisi dan antarmuka mungkin adalah cara terbaik untuk menyampaikan jenis konsep ini yaitu terbang, berenang dll
dreza
Seekor bebek tidak bisa terbang ?!
Adam Cameron
-3

Kloning rel khas Anda memberikan banyak contoh praktis : Anda memiliki kelas model dasar (abstrak), yang merangkum semua manipulasi data dan Anda memiliki kelas pengendali basis, yang merangkum semua komunikasi HTTP.

keppla
sumber
Ingin menjelaskan mengapa jawaban ini buruk?
keppla