In primo luogo, è necessario avere una chiara comprensione delle cose. L'espressione di esempio: Object obj = new MyClass();
è in realtà un composto di due operazioni elementari.
Il primo sta creando un'istanza di MyClass: new MyClass()
. La parola chiave new
è fondamentalmente l'unico modo per ottenere effettivamente un'istanza di una classe (ignorare la riflessione di runtime per mantenerla così semplice) e si sta letteralmente nominando ciò che si desidera creare (MyClass) qui dal suo costruttore. Non c'è modo di creare qualcosa di diverso da quello che hai letteralmente chiamato con la nuova parola chiave. Il risultato di new è (implicitamente) un'istanza di MyClass, ma il risultato esplicito di uno new X
è un riferimento di tipo X
(il riferimento riferito all'istanza appena creata).
Ora la seconda operazione assegna il riferimento al (nuovo) MyObject a un altro riferimento di tipo Oggetto. E questo è valido perché MyObject è un oggetto (a causa dell'ereditarietà).
Perché avresti bisogno di questo?
Questa è una caratteristica essenziale di fare effettivamente uso di polimorfismo. La capacità di riferirsi a qualsiasi classe di bambino come sua superclasse è ciò che rende il polimorfismo così potente . Fondamentalmente lo userai ovunque, dove c'è un aspetto comune a due classi, ma ci sono anche delle differenze.
Un esempio reale sarebbe rappresentato dalle interfacce utente grafiche. Ci sono pulsanti, elenchi, tabelle e pannelli in una finestra, che sono tutti elementi dell'interfaccia utente, ma ognuno fa una cosa diversa. Per presentarli ordinatamente organizzati in una finestra, questi elementi sono spesso annidati in riquadri, detti più astrattamente nei contenitori . Ora un contenitore non si cura di che tipo di elementi vi entrano, purché siano componenti. Ma per gestirli correttamente, un contenitore richiede alcune informazioni di base su questi componenti, soprattutto su quanto spazio occupano e su come effettivamente disegnarli. Quindi questo è modellato come qualcosa di simile:
public abstract class Component {
public int getWidth() { ... }
public int getHeight() { ... }
public void paint(Graphics g) { ... }
}
public class Container extends Component {
public void add(Component child) { ... }
public void paint(Graphics g) {
for (Component child : children) {
child.paint(g);
}
}
}
Quello è quasi subito sollevato fuori del JDK, il punto è, se si ha bisogno di fare riferimento a ciascun componente come il suo tipo concreto, sarebbe poco pratico per costruire un contenitore, avrebbe bisogno di un codice aggiuntivo per ogni componente che si decide di creare (ad esempio, ci sarebbe un addButton, addTable e così via). Quindi, Container funziona solo con riferimento a Component. Indipendentemente dal componente creato (ad esempio Button, CheckBox, RadioButton, ecc.), Poiché Container si basa su di essi su tutti gli sia Component, può gestirli.
Per ottenere una risposta precisa dovresti passare a come Java è implementato ... Per darti un'intuizione sul perché 'Oggetto obj = new MyClass();' funziona, è perché un 'MyClass' * è * un 'Object' dal momento che implementa quella classe e ha tutti i suoi metodi/proprietà/ecc. Tuttavia, un 'Object' non implementa i metodi/etc. di 'MyClass' – Shahar
Non si sta utilizzando il costruttore di una classe figlia" nella classe genitore ": si sta utilizzando il costruttore della classe figlio, ma successivamente si assegna l'oggetto" MyClass "a una variabile di classe più generale, un" Oggetto ". – Bram
Guarderei questo per la tua seconda domanda: http://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html – Brunaldo