Domanda di implementazione
Questo è un modo sfumato per osservare la classe base e le classi derivate.
L'implicazione è che si dovrebbe considerare ciò che la classe derivata (anche in sottoclasse) eredita come una specie di contratto con la classe base. Ciò che la classe base fornisce, o non fornisce, influenza il modo in cui le classi derivate possono essere utilizzate e quanto lavoro ci vuole.
Quindi usiamo una classe base di "Shape" con la proprietà "Name."
Ho ricavato un "Quadrato" e un "Cerchio" da Forma, e sono in grado di utilizzare il loro campo Nome ereditato per impostare il nome dell'oggetto.
Finora, tutto bene.
Ora aggiungiamo una proprietà "Area" e un metodo "GetArea ()" a Shape.
Possiamo codificare GetArea () all'interno di Shape perché restituiamo semplicemente la proprietà Area.
Ma come facciamo a fare in modo che le forme calcolino la loro area? Non possiamo scrivere Shape.CalcArea () poiché non abbiamo dato alcuna conoscenza delle dimensioni della forma. Quindi siamo obbligati a scrivere una routine CalcArea () in ciascuna delle classi derivate in modo che Shape.GetArea () non abbia esito negativo. (fallimento == non produce risultati attesi)
Ci sono modi per risolvere questo attraverso override, virtuals, abstract, ecc ... basati sul linguaggio. Ma il punto della frase è farti riflettere attraverso quelle relazioni.
Dobbiamo riflettere perché ora vogliamo usare Shape per ottenere una classe "Cone". I coni non hanno un'area, hanno un volume. E ora ti occupi delle domande sulla progettazione di classe di ciò che dovrebbe essere implementato dalla classe base, e cosa dovrebbero implementare le classi derivate.
Incapsulamento
Per definizione, la classe derivata può vedere e accedere a tutto ciò che la classe base ha da offrire. Nell'esempio Shape, questa è una "cosa buona" e vogliamo condividere esplicitamente tutto, dalla base alla classe derivata.
Ma diciamo che in Shape v2.0, ho bisogno di pre-compilare cose da un database. Così faccio derivare Shape da una classe di connessione al database "DBConn". Ora, tutti i miei cerchi, quadrati e coni sono anche connessioni al database. Ogni singola forma ha accesso a tutte le informazioni di connessione al database ed è potenzialmente strettamente legata al modo in cui funziona effettivamente DBConn.
Quindi, invece di chiamare Square.myDBConn.Connect (), posso semplicemente chiamare Square.Connect (). Quindi, se dovessi voler modificare l'implementazione di Connect () in un secondo momento, dovrò esaminare tutte le classi di forma derivate per vedere cosa potrebbe rompere con quel cambiamento.
Al suo punto cruciale, questa è la domanda di incapsulamento "Is A ..." vs. "Has A ..." che deve essere sempre considerata quando si combinano gli oggetti.