Come posso spiegare l'utilità dell'ereditarietà? [chiuso]

16

Quando si tenta di spiegare il concetto di ereditarietà in OOP, l'esempio comune è spesso l'esempio dei mammiferi. IMHO, questo è davvero un cattivo esempio, perché porterà i neofiti a usare questo concetto nel modo sbagliato. Inoltre, non è un progetto comune che dovranno affrontare nel loro lavoro di progettazione quotidiana.

Quindi, quale sarà un problema bello, semplice e concreto che viene risolto utilizzando l'ereditarietà?

    
posta Pierre Watelet 14.09.2011 - 10:45
fonte

14 risposte

15

Non c'è niente di sbagliato in un esempio puramente accademico come i mammiferi. Mi piace anche l'esempio rettangolo / quadrato perché sottolinea perché le tassonomie del mondo reale non sempre si traducono direttamente nella relazione di ereditarietà che ci si aspetterebbe.

Secondo me, l'esempio più canonico di tutti i giorni è un toolkit GUI. È qualcosa che tutti hanno usato, ma che i principianti potrebbero non aver ragionato su come lavorano sotto il cofano. Puoi parlare di quali comportamenti sono comuni a tutti i contenitori, tutti i widget, gli eventi, ecc. Senza richiedere una conoscenza dettagliata di una determinata implementazione.

    
risposta data 14.09.2011 - 14:38
fonte
14

Il mio esempio del mondo reale è il modello di dominio di una semplice applicazione HR. Dico che possiamo creare una classe base chiamata Dipendente , perché ovviamente anche i manager sono dipendenti.

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

Quindi spiego che gli sviluppatori sono dipendenti , tester sono dipendenti , responsabili di progetto sono dipendenti . Pertanto, tutti possono ereditare dalla classe dei dipendenti.

    
risposta data 14.09.2011 - 15:06
fonte
11

Incapsula ciò che varia ... mostra loro un modello di metodo del modello , dimostra l'utilità dell'eredità mettendo un comportamento comune in una classe base e incapsulare un comportamento variabile nelle sottoclassi.

UI controls e Streams sono anche un ottimo esempio per l'utilità dell'ereditarietà.

    
risposta data 14.09.2011 - 10:49
fonte
3

Ricorda

Ogni istanza di un oggetto è un esempio concreto dell'utilità dell'ereditarietà!

Se intendi in particolare l'eredità classe , ora ti trovi nel mondo delle tassonomie, e queste variano drasticamente dagli obiettivi del sistema che le usa. L'esempio di animali / mammiferi utilizza una tassonomia comune e spero familiare dalla biologia, ma è (come lei ha detto) quasi inutile per la stragrande maggioranza dei problemi di programmazione.

Quindi prova qualcosa di universale: la nozione di un programma. Ogni programma inizia, corre e termina. Ogni programma ha un nome e parametri opzionali della riga di comando. Quindi una classe base del programma sarebbe molto utile, per avviare l'esecuzione, afferrare ed elaborare gli argomenti della riga di comando, eseguire la logica principale e arrestare con grazia.

Ecco perché così tanti linguaggi di programmazione orientati agli oggetti forniscono una classe di programma o qualcosa che si comporta esattamente come una classe di programma.

    
risposta data 14.09.2011 - 11:08
fonte
3

Sto lavorando con le telecamere al lavoro. Abbiamo dispositivi che si connettono a diversi modelli, quindi abbiamo una "classe di telecamere" astratta e ogni modello eredita da questa classe per supportare funzionalità specifiche di quella telecamera. È un esempio reale e non è difficile da capire.

    
risposta data 14.09.2011 - 19:31
fonte
3

Esempio di elementi di chimica

Questo è un altro esempio saltato fuori dal mio cervello:

class Element_
{
    double atomicWeight; //Atomic weight of element
    double atomicNumber; // Atomic number of element
    String Properties;  // Properties of element
    //Others, if any
}


class Isotope extends Element_  // There can exist Isotopes of element
{
    double halflife;
   //Others if any

}
    
risposta data 11.12.2012 - 06:19
fonte
2

Gli esempi reali quasi sempre sbagliano perché forniscono esempi in cui c'è sempre la possibilità che qualcosa sia sia TypeA che TypeB ma la gerarchia ereditaria singola di molte lingue non lo consente.

Più programma, più mi allontano dall'eredità.

Anche la parola "ereditare" è usata impropriamente qui. Ad esempio, erediti circa il 50% delle caratteristiche di tuo padre e il 50% dei tratti di tua madre. In realtà il tuo DNA è una composizione del DNA di metà tuo padre e del DNA di metà di tua madre. Questo perché la biologia favorisce la composizione sull'ereditarietà , e dovresti farlo anche tu.

Semplicemente implementando le interfacce, o anche meglio, "duck typing", più l'iniezione delle dipendenze, è molto meglio insegnare alle persone che sono nuove alla programmazione orientata agli oggetti.

    
risposta data 22.11.2012 - 18:55
fonte
1

Vorrei solo mostrare loro un esempio di vita reale. Ad esempio, nella maggior parte dei framework UI si ottiene da una sorta di "Dialog" o "Window" o "Control" per creare il proprio.

    
risposta data 14.09.2011 - 15:42
fonte
1

Un buon esempio è la funzione di confronto nell'ordinamento:

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

L'unico problema è che i neofiti troppo spesso pensano che le prestazioni siano più importanti di un buon codice ...

    
risposta data 11.12.2012 - 06:40
fonte
0

Il mio esempio del mondo reale è un veicolo:

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

    }
}

Questo esempio può essere dettagliato come vuoi, e ci sono tutti i tipi di proprietà associate ai veicoli per spiegare l'uso di qualsiasi modificatore che potresti voler insegnare.

    
risposta data 14.09.2011 - 16:26
fonte
0

Questo esempio di non-mammifero, non-uccello e non-pesce potrebbe aiutare:

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

Poi

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

}

NOTA: non dire il segreto: la persona estende Mammal.

    
risposta data 22.11.2012 - 18:26
fonte
0

Che ne dici di una gerarchia di espressioni algebriche. È buono perché include sia l'ereditarietà che la composizione:

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

Ad eccezione dell'espressione radice Costante, tutte le altre espressioni sono entrambe un'espressione e contengono una o più espressioni.

    
risposta data 17.02.2013 - 19:57
fonte
-1

Userò gli uccelli come esempio

come pollo, anatra, aquila

Spiegherò che entrambi hanno artigli, beccate e ali ma i loro attributi sono diversi.

I polli non possono volare, non sanno nuotare, possono mangiare vermi, possono mangiare cereali

Le anatre non possono volare, possono nuotare, possono mangiare cereali, non possono mangiare vermi

L'aquila può volare, non sa nuotare, può mangiare vermi, non può mangiare cereali

    
risposta data 22.11.2012 - 09:16
fonte
-3

Il tipico rails-clone fornisce molti esempi pratici : si ha la classe del modello base (astratta), che incapsula tutta la manipolazione dei dati e si ha la classe del controller di base, che incapsula tutta la comunicazione HTTP.

    
risposta data 14.09.2011 - 11:27
fonte

Leggi altre domande sui tag