Kalıtımın yararını nasıl açıklayabilirim? [kapalı]


16

OOP'ta Kalıtım kavramını açıklamaya çalışırken, yaygın örnek genellikle memeli örneğidir. IMHO, bu gerçekten kötü bir örnek, çünkü yeni gelenlerin bu konsepti yanlış şekilde kullanmasına yol açacak. Dahası, günlük tasarım işlerinde karşılaşacakları ortak bir tasarım değildir.

Peki, Kalıtım kullanılarak çözülen güzel, basit ve somut bir sorun ne olacak?


1
"ortak örnek genellikle memeliler"? Ne demek istiyorsun? Bunun için bir link, referans veya teklif verebilir misiniz?
S.Lott


3
Miras = Bill Gates'in çocuk güven fonunun yararlılığını açıklamak için en iyi gerçek örnek ne olurdu?
Martin Beckett

1
@Chris: bu soru nasıl yapıcı değil? Bir askerin ve 14 cevaplayıcının herkesin zamanını harcadığını mı söylüyorsunuz?
Dan Dascalescu

@DanDascalescu - "lütfen kapatmayı yapıcı değil olarak düşünün: üzerine yığılan cevaplara bakarak, bu tipik bir liste / anket sorusuna benziyor" şeklinde bir bayrak cevabına iki yıl önce kapatıldı. Bunun yanlış olduğunu düşünüyorsanız, açık olmadığını belirtmek için düzenleyin ve topluluğun yeniden inceleme kuyruğu aracılığıyla karar vermesine izin verin.
ChrisF

Yanıtlar:


15

Memeliler gibi tamamen akademik bir örnekle ilgili yanlış bir şey yoktur. Dikdörtgen / kare örneğini de seviyorum, çünkü gerçek dünya taksonomilerinin neden her zaman doğrudan beklediğiniz miras ilişkisine dönüşmediğine dikkat çekiyor.

Bence, her gün en kanonik örnek bir GUI araç takımıdır. Bu herkesin kullandığı bir şey, ancak yeni başlayanlar kaputun altında nasıl çalıştıkları hakkında mantıklı olmayabilir. Herhangi bir uygulama hakkında ayrıntılı bilgi gerektirmeden, tüm kapsayıcılar, tüm widget'lar, etkinlikler vb. İçin hangi davranışların ortak olduğu hakkında konuşabilirsiniz.


5
GUI araç takımları için +1 ... ve ben de bir minimal örnekle () temel şekil ve özelleştirilmiş beraberlik () s ile alt şekiller şekiller örneğini seviyorum.
yati sagade

14

Gerçek dünyadaki örneğim, basit bir İK uygulamasının etki alanı modelidir. Çalışanlar adında bir temel sınıf oluşturabileceğimizi söylüyorum , çünkü tabii ki yöneticiler de çalışan.

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.
    }
}

Sonra açıklamak geliştiriciler olan çalışanlar , test olan çalışanlar , proje yöneticileri olan çalışanlar . Böylece hepsi işçi sınıfından miras alabilirler .


2
Miras avantajları göstermek için, geliştiricilerin çalışanlardan nasıl farklı olduklarını göstermek de ilginç olabilir. Fark yoksa, o zaman bir Geliştirici sınıfı oluşturmanıza gerek yoktur.
David

3
Sanki Employeebir abstractsınıf da olabilir.
StuperUser

+1 Bu, öğretmenlerimin çoğunun kullandığı örnek ve gerçekten hoşuma gitti. tam mantıklıydı ve mirasın nasıl kullanılacağına dair gerçek bir dünya örneği verdi.
David Peterman

18
Bu asla pratikte işler hariç a hem olması gereken en az bir kişi her zaman var, çünkü Developerbir Tester. Benzer bir durum, sahip olduğunuz bir iletişim veritabanıdır Customerve Supplierböyle bir sistemi yaratan herkesin size söyleyeceği gibi, her zaman a'nın her Companyikisinin de olduğu bir durum vardır. Bu yüzden bu örneklerin çoğu sizi yanlış yöne yönlendirir.
Scott Whitlock

11

Değişenleri kapsüle et ... onlara bir şablon yöntemi kalıbı gösterir, bir temel sınıfta ortak davranışlar koyarak ve alt sınıflarda değişen davranışları kapsülleyerek kalıtımın yararlılığını gösterir.

UI controlsve Streamsaynı zamanda kalıtımın yararlılığına çok iyi bir örnektir.


Sanırım fabrika daha iyi bir örnek olacaktı.
11:06

1
@Let_Me_Be: Sanırım bir fabrika ve miras arasındaki ilişki doğası gereği çok dolaylı. Elbette, somut türler üretir ve soyut / taban türlerini döndürür, ancak aynı zamanda sadece bir arayüz türü döndürebilir! Bu klasik hayvan örneğinden daha iyi değil.
Falcon

@Let_Me_Be: Ayrıca, soyut bir fabrika farklı miras hiyerarşilerini (bir tanesi öğeler, bir tanesi fabrikalar için) içeren oldukça karmaşık bir örnektir. Bence bu kalıtımın iyi bir kullanımı, ama iyi ve basit bir örnek değil.
Falcon

3

Hatırlamak

Bir nesnenin her örneği kalıtımın yararlılığına somut bir örnektir!

Özellikle sınıf mirasını kastediyorsanız , şimdi sınıflandırma dünyasındasınız ve bunlar onları kullanan sistemin hedeflerine göre büyük ölçüde değişecektir. Hayvanlar / memeliler örneği biyolojiden ortak ve umarım tanıdık bir sınıflandırma kullanır, ancak (bahsettiğiniz gibi) programlama sorunlarının büyük çoğunluğu için neredeyse işe yaramaz.

Bu yüzden evrensel bir şey deneyin: bir Program kavramı. Her program başlar, çalışır ve biter. Her programın bir adı ve isteğe bağlı komut satırı parametreleri vardır. Bu nedenle, temel bir Program sınıfı, yürütmeyi başlatmak, komut satırı bağımsız değişkenlerini alıp işlemek, ana mantığı çalıştırmak ve zarif bir şekilde kapatmak için çok yararlı olacaktır.

Bu nedenle, nesneye yönelik birçok programlama dili bir Program sınıfı veya tam olarak bir Program sınıfı gibi davranan bir şey sağlar.


Peki, içinde birçok program olan bir program mı programlıyorsunuz? :) Deneyimlerime göre, Programm Objeleri neredeyse her zaman kalıtım olmayan tekil öğelerdir, bu yüzden en iyi örnek değildirler.
keppla

@keppla: Hiç Java veya .NET kullandınız mı? .NET'in açık bir Program sınıfı vardır, Java'nın üstü kapalıdır. Tekil değiller
Steven A. Lowe

Sürüm 1.4.2 civarında Java kullandım. O zamanlar, sadece statik boşluk ana vardı, bu yüzden biraz değişti sanırım. Birden fazla Programm sınıfı örneğine sahip olmanın tipik bir nedeni nedir?
keppla

@keppla: java'nın statik void main, giriş sınıfının programı temsil etmesini sağlar. Programınızı çalıştıran her kullanıcı, programın yeni bir örneğini oluşturur. Şu anda üç Google Chrome örneğim var, dört Word belgesi, üç Not Defteri ve iki Windows Kaşif var. Eğer hepsi tekil olsaydı bunu asla yapamazdım.
Steven A. Lowe

1
Bence tanımı biraz uzatıyorsun. class Programm { public static void main(String[] args) { system.out.println('hello world'); }}minimal bir Java programıdır. Ben çağırdığınızda, Program örneği yoktur. Program hiçbir şeyden miras almaz. 3 İşlemi başlattığımda (crhome ile yaptığınız gibi), 3 Program olabilir, ancak kendi bellek alanlarında hala sadece bir Program vardır. Imho, singleton, Makine başına değil, 'İşlem başına sadece bir Örnek' anlamına gelir. Eğer öyleyse, tekilton yapmak imkansız olurdu, hiçbir şey herhangi bir kodu iki kez çalıştırmanızı engellemez.
keppla

3

İş yerinde kameralarla çalışıyorum. Farklı modellere bağlanan cihazlarımız var, bu yüzden soyut bir "kamera sınıfımız" var ve her model bu kameranın belirli işlevlerini desteklemek için bu sınıftan miras alıyor. Bu gerçek bir dünya örneği ve anlaşılması zor değil.


2
Eğer varsa, bu örneğin bir ikisi de bir model, yıkmak olabilir Camerave bir Phone(artık hepimiz cebimizde olduğu gibi). Hangi temel sınıftan miras almalı? Yoksa sadece ikisi uygulamaması gerektiği ICamerave IPhonearayüzleri? (ha ha)
Scott Whitlock

2
@Scott: IPhone arayüzünü uygulayamazsınız, yoksa Apple tarafından dava edilirsiniz.
Mason Wheeler

3

Kimya Elemanları Örneği

Bu, beynimden atılan başka bir örnek:

sınıf Element_
{
    çift ​​atom ağırlığı; // Elementin atom ağırlığı
    çift ​​atom numarası; // Atomik element sayısı
    Dize Özellikleri; // Elemanın özellikleri
    // Varsa diğerleri
}


sınıf İzotop öğesi Element_ //'yi genişletir Öğenin izotopları olabilir
{
    çift ​​yarılanma ömrü;
   // Varsa diğerleri

}

2
AtomicNumber muhtemelen tamsayı olsa da ...
Andrew

Bunun için miras kullanmazdım. isotopeözel bir durum değil Elemenet. ElementÜzerinde bir mülk olmasını tercih ederim Isotope.
CodesInChaos

2

Gerçek dünya örnekleri neredeyse her zaman yanlış yapar çünkü her zaman bir şeyin her ikisi de olma olasılığının olduğu TypeAve TypeBbirçok dilin tek miras hiyerarşisinin buna izin vermediği örnekler verir.

Ne kadar çok program yaparsam kalıtımdan o kadar uzaklaşırım.

"Devral" kelimesi bile burada yanlış kullanılmıştır. Örneğin, babanızın özelliklerinin yaklaşık% 50'sini ve annenizin özelliklerinin% 50'sini miras alırsınız. Gerçekten DNA'nız, babanızın DNA'sının yarısının ve annenizin DNA'sının yarısının bir bileşimidir. Çünkü biyoloji aslında miras yerine kompozisyonu tercih eder ve siz de yapmalısınız.

Sadece arayüzler uygulamak ya da daha iyisi, "ördek yazma", artı bağımlılık enjeksiyonu, nesne yönelimli programlamaya yeni başlayan insanlara öğretmek için çok daha iyi bir şey.


1

Onlara gerçek hayattan bir örnek gösterirdim. Örneğin, çoğu UI çerçevesinde kendi türünüzü oluşturmak için bir çeşit "İletişim Kutusu" veya "Pencere" veya "Kontrol" sınıfından türetmiş olursunuz.


1

Sıralamada karşılaştırma işlevi iyi bir örnektir:

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);

Tek sorun, yeni başlayanların performansın iyi koddan daha önemli olduğunu düşünmesidir ...


0

Gerçek dünya örneğim bir araç:

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)
    {

    }
}

Bu örnek istediğiniz kadar ayrıntılı olabilir ve öğretmek isteyebileceğiniz herhangi bir değiştiricinin kullanımını açıklamak için araçlara eklenmiş her türlü özellik vardır.


2
Her zaman örnek olarak araç kullanmaktan nefret ettim , çünkü yeni bir programcı, mirasın kodu geliştirmek için nasıl kullanılabileceğini anlamaya daha yakın olmuyor. Araçlar, programcı olmayan kişinin zihninde soyut olmayan pek çok fikri akla çağıran son derece karmaşık makinelerdir. Bunu kodda tarif etmeye çalışmak, ortalama aceminin, örnekten çok fazla detayın kaldığına inandığını ve işe yarayacak bir şey elde etmeye daha yakın olmadıklarını hissettiriyor. Bunu deneyimle söylüyorum, çünkü biri bana bunu açıklamak için araç kullanmaya çalıştığında hissettiğim şey tam olarak bu .
riwalk

@ Stargazer712: Araçları öncelikle kullanıyorum çünkü istediğiniz kadar karmaşık veya basit olabilirler. Öğrencisinin seviyesini belirlemek için öğretmenin kararına bırakıyorum. Ortak temelleri açıklayan bir aracın basit özelliklerini kullanarak temel OOP'yi eşime (sıfır programlama deneyimi olan) açıkladım. Tüm araçların kapıları, tüm araçların tekerlekleri vb. Vardır. Nesne örneği kötü bir ders planı için suçlanamaz.
Joel Etherton

karınız kod yazmaya çalışmıyordu. Ben yapabilirsiniz çok güvenli olduğunu taşıt örnekleri bana miras anlamalarına yardımcı olmak için hiçbir şey yapmadı demek. Miras tanımlamak için ne kullanırsanız kullanın, tam ve pratik olmalıdır . Amaç, bunu programcı olmayan bir kişinin anlayabileceği şekilde tanımlamak değildir. Amaç acemi bir programcı anlamına şekilde tarif etmektir kullanmak onu ve bunu yapmanın tek yolu profesyonel programcı bunu nasıl kullanacağını acemi örneklerini göstermektir.
riwalk

@ Stargazer712: Kötü bir ders planında başlangıçta mirasını anlama yetersizliğinizi koyardım. Ayrıca, birlikte çalıştığım gençlere mirası açıklamak için araçlar kullandım ve bu konseptle karşılaştığım bir problemim olmadı. Bence, bir ders planı ayrıntılı ve düzgün bir şekilde oluşturulmuşsa, bir araç nesnesi hem eksiksiz hem de pratiktir. İnternette 1 rastgele adam OOP öğrettiğim 30 kadar stajyer ve genç dev karşısında değişmeyecek. Eğer aracı beğenmezseniz, aşağı oy ve devam edin.
Joel Etherton

İstediğiniz gibi ....
riwalk

0

Bu memeli olmayan, kuş olmayan, balık olmayan örnek yardımcı olabilir:

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 */
}

Sonra

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());
    }       

}

NOT: Sırrı söyleme: Kişi Memeli uzatır.


1
Çalışanlarınızdan biri de hasta olana kadar çalışır.
Scott Whitlock

Bu durumda, hasta ve çalışanı soyut sınıflar yerine arayüz olarak ilan etmenin daha anlamlı olduğunu düşünüyorum. Bu, Kişinin birden fazla arabirim uygulama esnekliği sağlar.
Jin Kim

@JinKim - Tamamen katılıyorum, bu daha iyi bir yaklaşım.
Scott Whitlock

@JinKim Özel değiller. Bir kişiye herhangi bir zamanda çalışan veya hasta olarak davranırsınız, ancak aynı anda değilsiniz. İki arayüz sorun değil ama ne zaman her ikisini de uygulayan somut bir sınıf diyorsunuz, EmployeePatient? Kaç kombinasyonunuz olacak?
Tulains Córdova

Somut sınıfı istediğiniz gibi arayabilirsiniz. Kod yalnızca Çalışanlar ile ilgilenmeyi bekliyorsa, başvuruyu Çalışan olarak bildirirsiniz. (örn. Çalışan çalışan = yeni Kişi ();) Kod yalnızca bir Hastayla ilgilenmeyi bekliyorsa, başvuruyu Hasta olarak beyan edersiniz. Nadiren doğrudan somut sınıf olarak bir referans beyan etmek istersiniz.
Jin Kim

0

Cebirsel ifadeler hiyerarşisine ne dersiniz? Hem kalıtım hem de kompozisyon içerdiği için iyidir:

+--------------------+------------------------+
| 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

Kök ifadesi Constant dışında, tüm diğer ifadeler hem bir İfadedir hem de bir veya daha fazla ifade içerir.


-1

Kuşları örnek olarak kullanacağım

tavuk, ördek, kartal gibi

Her ikisinin de pençeleri, çekleri ve kanatları olduğunu açıklayacağım, ancak özellikleri farklı.

Tavuklar uçamaz, yüzemez, solucan yiyebilir, tahıl yiyebilir

Ördekler uçamaz, yüzebilir, tahıl yiyebilir, solucan yiyemez

Kartal uçabilir, yüzemez, solucan yiyebilir, tahıl yiyemez


4
Bir keresinde kompozisyonun ve arayüzlerin muhtemelen bu tür bir konsepti aktarmanın en iyi yolu olduğunu okudum, yani uçmak, yüzmek vb.
dreza

Ördek uçamaz mı ?!
Adam Cameron

-3

Tipik rails klonunuz birçok pratik örnek sağlar : tüm veri manipülasyonlarını kapsayan (soyut) temel model sınıfına ve tüm HTTP iletişimini kapsayan temel kontrol sınıfına sahipsiniz.


Bu cevabın neden kötü olduğunu açıklamak ister misiniz?
keppla
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.