Perché i framework Windows Form / Swing preferiscono l'ereditarietà invece della composizione?


12

Oggi un mio professore ha commentato di aver trovato strano che, sebbene la filosofia di SWT sia quella di prendere i propri controlli per composizione, Swing sembra favorire l'eredità.

Non ho quasi alcun contatto con entrambi i framework, ma da quello che ricordo in Windows Forms di C # di solito si estendono i controlli, proprio come Swing.

Essendo che generalmente le persone tendono a preferire la composizione rispetto all'eredità, perché la gente di Swing / Windows Form non preferisce la composizione invece dell'eredità?


2
Molte cose sono cambiate negli ultimi 15-20 anni che quelle API erano in circolazione! I motori di rendering non avevano una colla XML magica per legare oggetti dello schermo a istanze di qualsiasi classe di cemento arbitraria "back in the day";)

1
La maggior parte del codice Swing che vedo usa l'estensione per composizione. Non sono sicuro di dove il tuo prof stia ottenendo i suoi dati.

Io stesso ho visto molta oscillazione in rete con eredità anziché composizione - per lo più tutorial. ma i moduli di Windows sono davvero usati basandosi quasi esclusivamente sull'eredità!
divorò elisio

Risposte:


7

JComponentespone molte funzionalità . Se JComponentfosse un'interfaccia e i componenti fossero implementati con la composizione, i componenti semplici avrebbero bisogno di dozzine di involucri di metodo banali, ad es.

class MyComponent implements JComponent {
    JPanel panel;
    public boolean contains(int x, int y) {
        return panel.contains(x, y);
    }
    ...
}

C'è anche un motivo di efficienza per preferire l'eredità rispetto alla composizione: l'override non costa nulla (supponendo che non ci sia superchiamata), mentre la composizione costa un extra INVOKEVIRTUAL. Non so se questo abbia influenzato il design di Swing, ma è una grande preoccupazione per le lezioni di collezione.


2

Swing Framework è in realtà progettato secondo il modello di design composito. Concesso che ci sia molta eredità lì dentro, ma di solito comporresti le tue forme usando la composizione. Cioè, una forma è una composizione di contenitori e controlli di livello intermedio.


"Cioè, una forma è una composizione di contenitori e controlli di livello intermedio." Sicuro. Ma quello che vedo di solito è che quando le persone vogliono creare la propria finestra (o come si chiama Swing), erediteranno da una classe di finestre invece di usare la composizione.
divorato elisio

@ elisio consumato È vero. Ma per creare la forma avrebbero usato la composizione. Quindi è un po 'di eredità e molta composizione.

@devoured, penso che sia un caso di persone che non si rendono conto che il tutorial che usano non segue le migliori pratiche perché favorisce la brevità.
Peter Taylor,

1

Con Java, è molto più facile finire per usare l'eredità solo perché tutto è virtuale. Devi correggere una "funzione" in JTable / JFrame? Estenderlo, sovrascrivere i metodi del problema e utilizzare invece la tua tabella / cornice ovunque.

Penso a cose come WPF, in cui l'associazione dei dati è una caratteristica principale del progetto, rende molto più semplice fare la composizione invece dell'eredità.


Cosa intendi con "tutto è virtuale "?
Jonas,

in Java, ogni metodo è implicitamente virtuale (può essere ignorato). In C #, devi dichiarare esplicitamente un metodo come virtuale, per sovrascriverlo, lo dichiari esplicitamente come override. In Java, puoi ignorare tutto ciò che puoi vedere e puoi aumentarne la visibilità in una sottoclasse (puoi rendere pubblici i metodi protetti in una sottoclasse!)
John Gardner,

Si noti che non è possibile sovrascrivere un finalmetodo in Java, anche se la classe base stessa non lo è final.
perp

è vero @perp. ma in java devi fare di tutto (aggiungendo final) per prevenire il virtuale. C # è l'opposto, devi fare di tutto per essere virtuale. E una percentuale molto piccola del runtime java standard è contrassegnata come definitiva.
John Gardner,

1

In Effective Java , Item 17, Bloch menziona che una classe progettata per l'ereditarietà "deve documentare il suo uso personale di metodi sostituibili". Un segno distintivo di questo è la frase questa implementazione . Lo vedrai in classi come JTablee JInternalFrame. È una misura dell'eredità di progettazione in Swing.


-2

Da C # 3.5, abbiamo un concetto chiamato come Metodi di estensione che consente il concetto di composizione rispetto all'eredità.

In questo processo, implementiamo una funzionalità estesa a una classe esistente semplicemente aggiungendo una classe di estensione che rende la nuova funzionalità alla classe esistente.

Puoi fare riferimento qui per maggiori dettagli


Non vedo l'importanza per la creazione di nuove classi di controllo WinForms. Potresti elaborare?
Peter Taylor,

@Peter: questo non è correlato solo alle classi di moduli Windows. Questo può essere applicabile anche dal nostro codice. È possibile estendere qualsiasi classe esistente semplicemente aggiungendo una classe statica e quindi aggiungendo un nuovo metodo con il 1 ° argomento in questo modo in modo che l'oggetto base possa essere collegato. Dopo aver compilato il codice, si ottiene il metodo appena aggiunto come metodo della classe base stessa. Questo è ciò che afferma la composizione. spero di avere ragione ..
Saravanan,

1
So quali sono i metodi di estensione, e sono abbastanza utili a volte, ma questa domanda riguarda approcci diversi alla creazione di nuove classi.
Peter Taylor,

@Peter: Quindi posso solo indicare l'uso di classi parziali, a parte quello per la mia comprensione C # non ha altre caratteristiche notevoli. Se ne conosci qualcuno, fammi sapere.
Saravanan,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.