2011-08-25 30 views

risposta

50

(Come Michael, suppongo che Lei abbia voluto fare B estendere A.)

Ci sono due aspetti sul lavoro qui:

  • Se fai specificare un costruttore in modo esplicito (come in A) il compilatore Java sarà non crea un costruttore senza parametri per te.

  • Se non si specifica esplicitamente un costruttore (come nel B) il compilatore Java creerà un costruttore senza parametri per voi in questo modo:

    B() 
    { 
        super(); 
    } 
    

(L'accessibilità dipende l'accessibilità dei la classe stessa.)

Questo sta provando a chiamare il costruttore senza parametri della superclasse, quindi deve esistere. Sono disponibili due opzioni:

  • fornire un costruttore senza parametri in modo esplicito nel A
  • Fornire un costruttore senza parametri in modo esplicito nel B che richiama esplicitamente il costruttore della classe base con un argomento appropriato int.
+0

@ user358099: per chiarire che stava cercando di chiamare il supercostruttore senza parametri. –

0

Ovviamente è un errore se scritto in questo modo non è JAVA.

Se si utilizza la sintassi JAVA, non sarebbe un errore.

Classe A e B non conoscono l'un l'altro se in file/pacchetti separati.

La classe A non ha bisogno di un costruttore predefinito, funziona perfettamente solo con un costruttore di parametri.

Se B estende A, è semplice utilizzare una chiamata a super (int a) nel costruttore di B e tutto va bene. per i costruttori che non chiamano un super (vuoto/o non) che estende una super classe il compilatore aggiungerà una chiamata a super().

Per ulteriori sguardo lettura Using the Keyword super

+0

davvero una risposta preziosa. Ma un piccolo chiarimento perché super() viene aggiunto implicitamente dal compilatore. – bharanitharan

+0

@ user358099 Ho aggiunto una nuova risposta alla tua domanda modificata. – Farmor

5

Supponendo che si intende scrivere class B extends A:

Ogni costruttore deve chiamare un costruttore della superclasse; se non viene chiamato implicitamente il costruttore della superclasse senza parametri.

Se (e solo se) una classe non dichiara alcun costruttore, il compilatore Java gli assegna un costruttore predefinito che non accetta parametri e chiama il costruttore senza parametri della superclasse.Nell'esempio, A dichiara un costruttore e quindi non ha un costruttore predefinito. La classe B non dichiara un costruttore, ma non può ottenere un costruttore predefinito poiché la sua superclasse non ha un costruttore senza parametri da chiamare. Poiché una classe deve sempre avere un costruttore, questo è un errore del compilatore.

+0

è un errore del compilatore il mio dubbio è ... perché la classe genitore dovrebbe avere un costruttore predefinito esplicitamente ... mentre ha un costruttore argomentato – bharanitharan

+1

@ user358099: Perché il costruttore implicito predefinito viene creato solo se non esiste un costruttore ecplicit. Questo perché un programmatore potrebbe non * desiderare * che la sua classe abbia un costruttore senza parametri, quindi sarebbe un pessimo linguaggio design creare sempre implicitamente uno. –

1

Dite questo compilato, cosa vi aspettereste che stampi?

class A{ 
    A(int i){ 
    System.out.println("A.i= "+i); 
    } 
} 

class B extends A { 
    public static void main(String... args) { 
    new B(); 
    } 
} 

Quando A è costruito un valore per i deve essere passato, ma il compilatore non sa quello che dovrebbe essere in modo da avere specificarlo in modo esplicito in un costruttore (qualsiasi costruttore, esso non deve essere un default)

8

Perché è necessario costruttore di default (esplicitamente) in una classe genitore se ha un costruttore argomentata

direi che questa affermazione non è sempre corretto. Come idealmente non è necessario.

La regola è: Se si fornisce esplicitamente un costruttore argomento-ed, il costruttore predefinito (non argomentato) non è disponibile per la classe.

For Example : 
class A {  
    A(int i){  
    } 
} 

class B extends A { 
} 

Quindi, quando si scrive

B obj_b = new B(); 

Si chiama in realtà il costruttore implicita fornito da Java a B, che chiama ancora una volta il super(), che dovrebbe essere idealmente un(). Ma dato che hai fornito il costruttore argomento-ed a A, il costruttore predefinito i: e A() non è disponibile per B().

Questa è la ragione per cui è necessario che A() sia dichiarato espressamente per B() per chiamare super().

0

Direi che è perché, quando si ha un elenco di parametri vuoto, la variabile super non può essere istanziata. Con la lista dei parametri vuota intendo il super implicito() che il compilatore potrebbe aggiungere se la super-classe avesse un costruttore non parametrico.

Per esempio, se si digita:

int a; 
System.out.print(a); 

otterrete un errore con quello che penso è lo stesso errore logico.

0

Quando abbiamo il costruttore di parametri. siamo esplicitamente vincolati al consumatore dal design. non può creare oggetti di quella classe senza parametri. un po 'di tempo abbiamo bisogno di forzare l'utente a fornire valore. l'oggetto dovrebbe essere creato solo fornendo un parametro (valore predefinito).

class Asset 
{ 
    private int id; 
    public Asset(int id) 
    { 
     this.id = id; 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     /* Gives Error - User can not create object. 
     * Design bound 
     */ 
     Asset asset1 = new Asset();/* Error */ 
    } 
} 

Anche la classe figlio non può creare. quindi è un comportamento di buon design.

4
Why default constructor is required(explicitly) in a parent class if it 
has an argumented constructor 

Non necessariamente!

Ora nella classe B

class B extends A { 
} 

non hanno fornito alcuna costruzione della classe B in modo da un costruttore di default sarà posto. Ora è una regola che ogni costruttore deve chiamare uno dei suoi costruttori di super classi.Nel tuo caso il costruttore predefinito in Classe B proverà a chiamare il costruttore predefinito in classe A (è genitore), ma come non hai un costruttore predefinito in Classe A (come hai esplicitamente fornito un costruttore con argomenti in classe A non hai un costruttore predefinito in Classe A) riceverai un errore.

cosa che si potrebbe fare è

O non forniscono argomenti di costruzione della classe A.

A() 
{ 
    //no arg default constructor in Class A 
} 

O

esplicitamente scrivere senza args costruttore in B e chiamare il super-con qualche argomento int di default.

B() 
{ 
    super(defaultIntValue); 
} 

linea di fondo è che per un oggetto da creare completamente i costruttori di ciascun genitore nella gerarchia di ereditarietà devono essere chiamati. Quelli da chiamare sono davvero la tua scelta di design. Ma nel caso in cui non fornisci esplicitamente alcun java, chiamerai il costruttore predefinito super() come 1a riga di ognuno dei tuoi costruttori sub class e ora, se non lo hai in superclasse, otterrai un errore.

5

Ogni costruttore di sottoclasse chiama il costruttore predefinito della super classe, se il costruttore della sottoclasse non chiama esplicitamente un altro costruttore della super classe. Quindi, se il costruttore della sottoclasse richiama esplicitamente un costruttore di super classi che hai fornito (con argomenti), allora non c'è bisogno di alcun costruttore di argomenti nella super classe. Così, il seguente compilerà:

class B extends A{ 
    B(int m){ 
     super(m); 
    } 
} 

ma la seguente non verrà compilato, a meno che non si fornisce esplicitamente non args costruttore nella classe super:

class B extends A{ 
    int i; 
    B(int m){ 
     i=m; 
    } 
} 
1

Ci sono alcune cose da notare quando usando i costruttori e come dovresti dichiararli nella tua classe base e super classe. Questo può essere un po 'confuso solo perché ci possono essere molte possibilità di disponibilità o esistenza di costruttori nella super classe o nella classe base. Cercherò di approfondire tutte le possibilità:

  • Se si definisce esplicitamente i costruttori a qualsiasi classe (classe base/super classe), il compilatore Java non creerà alcun costruttore per voi in quella rispettiva classe.

  • Se non si definiscono esplicitamente i costruttori in qualsiasi classe (classe base/super classe), il compilatore Java creerà per voi un costruttore senza argomenti nella rispettiva classe.

  • Se la classe è una classe base che eredita da una super classe e non si definiscono esplicitamente i costruttori in tale classe base, non solo verrà creato un costruttore senza argomenti (come il punto precedente) di il compilatore, ma chiamerà implicitamente anche il costruttore no-argument della super-classe.

    class A 
    { 
        A() 
    { 
        super(); 
    } 
    } 
    
  • Ora, se non si digita esplicitamente super(), (o super (parametri)), il compilatore metterà nel super() per voi nel codice.
  • Se super() viene chiamato (esplicitamente o implicitamente dal compilatore), il compilatore si aspetta che la tua superclasse abbia un costruttore senza parametri. Se non trova alcun costruttore nella tua superclasse senza parametri, ti darà un errore del compilatore.

  • Similare se viene chiamato super (parametri), il compilatore si aspetta che la tua superclasse abbia un costruttore con parametri (il numero e il tipo di parametri devono corrispondere). Se non trova un tale costruttore nella tua superclasse, ti darà un errore del compilatore. (Super (parametri) non possono mai essere chiamato implicitamente dal compilatore. Deve essere esplicitamente mettere nel vostro codice, se si è richiesto.)

Possiamo riassumere alcune cose dalle norme di cui sopra

  • Se la superclasse ha solo un costruttore con parametri e non ha un costruttore senza argomenti, è necessario avere un'istruzione esplicita super (parametri) nel costruttore. Questo perché se non lo fai un'istruzione super() sarà implicitamente inserita nel codice e poiché la tua superclasse non ha un costruttore senza argomenti, mostrerà un errore del compilatore.
  • Se la tua superclasse ha un costruttore con parametri e un altro costruttore senza argomenti, non è necessario avere un'istruzione esplicita super (parametri) nel tuo costruttore. Questo perché un'istruzione super() verrà implicitamente inserita nel codice dal compilatore e poiché la superclasse ha un costruttore senza argomenti, funzionerà correttamente.
  • Se la tua superclasse ha solo un costruttore senza argomenti puoi fare riferimento al punto precedente poiché è la stessa cosa.

Un'altra cosa da notare è se la tua superclasse ha un costruttore privato, che creerà un errore durante la compilazione della sottoclasse. Questo perché se non si scrive un costruttore nella propria sottoclasse, chiamerà il costruttore della superclasse e l'implicito super() proverà a cercare un costruttore senza argomenti nella superclasse ma non ne troverà uno.

Problemi correlati