Ereditarietà costruttore

di il
3 risposte

Ereditarietà costruttore

Non ho capito una cosa.
Suppongo di avere la classe Rettangolo, la quale ha due costruttori compreso quello di default
public class Rettangolo {
    private int base;
    private int altezza;
    
    public Rettangolo(int b,int h)
    {
        base=b;
        altezza=h;
    }
    
    public Rettangolo()
    {
    }*/
Suppongo di creare Rombo,sottoclasse di Rettangolo
public class Rombo extends Rettangolo {}
In rombo non c'è nessun costruttore.
Se creo un oggetto Rombo r verrà invocato il costruttore VUOTO della superclasse che è presente.

Suppongo ora di cancellare il costruttore vuoto della superclasse Rettangolo e di creare un costruttore nella classe Rombo
public class Rombo extends Rettangolo {
public Rombo(){}
}
Il costruttore di Rettangolo è inibito, ma Rombo ha un suo costruttore.
Perchè se ora tento di creare un oggetto Rombo mi da errore?
Sembra vada sempre a cercare il costruttore della superclasse, nonostante Rombo abbia il suo costruttore vuoto.
Non ho capito perchè accade ciò. E' un meccanismo dell'ereditarietà?

3 Risposte

  • Re: Ereditarietà costruttore

    reynold ha scritto:


    Suppongo di avere la classe Rettangolo, la quale ha due costruttori compreso quello di default
    Il costruttore di "default" è solo quello generato in automatico dal compilatore. Il secondo costruttore di Rettangolo che hai definito tu non è quello di default .... è un costruttore esplicito no-arg (senza argomenti) che "guarda caso" a livello funzionale fa esattamente quello che farebbe quello di "default".

    reynold ha scritto:


    In rombo non c'è nessun costruttore.
    Se creo un oggetto Rombo r verrà invocato il costruttore VUOTO della superclasse che è presente.
    Sì, perché il costruttore di default in Rombo fa implicitamente una invocazione super(); e quindi ci DEVE essere un costruttore nella super-classe (Rettangolo) che è accessibile (sicuramente non private) e senza argomenti.

    reynold ha scritto:


    Suppongo ora di cancellare il costruttore vuoto della superclasse Rettangolo e di creare un costruttore nella classe Rombo
    public class Rombo extends Rettangolo {
    public Rombo(){}
    }
    Il costruttore di Rettangolo è inibito, ma Rombo ha un suo costruttore.
    Perchè se ora tento di creare un oggetto Rombo mi da errore?
    Il costruttore in Rombo che hai messo ora è esplicito ma implicitamente fa comunque una invocazione super(); (la mette il compilatore!)
    Ora però in Rettangolo NON c'è più un costruttore no-arg! Quindi è un errore.

    reynold ha scritto:


    E' un meccanismo dell'ereditarietà?
    No. Tra l'altro l'ereditarietà non si applica ai costruttori. I costruttori NON sono mai ereditati dalle sotto-classi.
  • Re: Ereditarietà costruttore

    I costruttori NON sono mai ereditati dalle sotto-classi.
    Esatto, fin qua ci sono.
    Il costruttore in Rombo che hai messo ora è esplicito ma implicitamente fa comunque una invocazione super(); (la mette il compilatore!)
    Ora però in Rettangolo NON c'è più un costruttore no-arg! Quindi è un errore.
    Bene,avevo compreso il motivo dell'errore.
    Quindi la regola generale è che qualsiasi costruttore di una sottoclasse fa sempre e comunque una invocazione con super al costruttore della classe madre? Sia esso un costruttore vuoto o un costruttore che accetta parametri in ingresso. L'invocazione viene fatta anche quando non servirebbe cioè quando nella sottoclasse viene definito esplicitamente uno specifico costruttore.
    Per questo mi chiedevo se l'invocazione implicita con super fosse un meccanismo dell'ereditarietà.
    La domanda che mi sorge è: perchè viene fatta sempre e comunque l'invocazione con super da parte della sottoclasse anche se dichiaro esplicitamente un costruttore nella sottoclasse stessa?
  • Re: Ereditarietà costruttore

    reynold ha scritto:


    Quindi la regola generale è che qualsiasi costruttore di una sottoclasse fa sempre e comunque una invocazione con super al costruttore della classe madre?
    La prima istruzione di un qualunque costruttore deve essere:
    - una invocazione super(); (con o senza argomenti, dipende) per invocare un costruttore della super-classe.
    oppure
    - una invocazione this(); (con o senza argomenti, dipende) per invocare un altro costruttore nella stessa classe.

    Se non si mette esplicitamente uno dei due, il compilatore mette un super(); chiaramente senza argomenti (non saprebbe certo che passare!).

    reynold ha scritto:


    La domanda che mi sorge è: perchè viene fatta sempre e comunque l'invocazione con super da parte della sottoclasse anche se dichiaro esplicitamente un costruttore nella sottoclasse stessa?
    Una classe può avere più costruttori, uno chiama l'altro, che chiama l'altro ecc... ma ad un certo punto ci deve essere una invocazione ad un super-costruttore.
    Questo perché la inizializzazione deve arrivare fino al costruttore di java.lang.Object affinché l'oggetto sia correttamente istanziato.

    I costruttori di una classe non possono rimpallarsi l'un l'altro ciclicamente. Tra l'altro il compilatore lo scopre subito e dà errore: "recursive constructor invocation"
Devi accedere o registrarti per scrivere nel forum
3 risposte