2015-07-03 24 views
5

Se i costruttori non ereditano in Java, perché ottengo l'errore di compilazione (Il costruttore super implicito A() non è visibile per il costruttore predefinito. un costruttore esplicito)?Perché un costruttore di classe base privato risulta in "Costruttore super implicito non visibile"

class A { 
    private A() { 
    } 
} 

public class B extends A { 

} 

UPD. So che super() viene chiamato nel costruttore implicito B. Ma non capisco perché non può accedere al costruttore privato con super(). Quindi, se abbiamo solo costruttori privati, la classe di fatto è final?

+0

(La risposta alla tua domanda finale è "sì", a patto di "finale" che "non può essere sottoclasse". Dovrebbe (probabilmente, penso) non essere assunto tuttavia che il compilatore individuerà anche questo e tratta la classe A esattamente come se fosse stata dichiarata esplicitamente "finale".) –

+0

possibile duplicato di [Come risolvere 'Implic super constructor classA() non è visibile. Deve esplicitamente invocare un altro costruttore '?] (Http://stackoverflow.com/questions/3904355/how-to-resolve-implicit-super-constructor-classa-is-not-visible-must-explici) – Raedwald

risposta

10

se B extends A, B deve avere accesso a un costruttore A.

Ricordare che un costruttore chiama sempre super(). Quindi, il costruttore implicito senza parametri di B non può chiamare il costruttore A.

+0

So che super() viene chiamato nel costruttore implicito B. Ma non capisco perché non possa accedere al costruttore privato con super(). Quindi, se solo i costruttori privati ​​di classe sono di fatto definitivi? –

+0

@OlegKuts Stai confondendo qualcosa qui! Un costruttore non può essere 'finale', infatti, il JLS ha specificato che un costruttore non può essere ignorato. Quindi, il costruttore 'B' non sta sovrascrivendo il costruttore' A', ma solo chiamandolo. L'impostazione 'private' del costruttore' A' significa che non può essere usato al di fuori della classe 'A', e quindi non può essere usato nella classe' B', ma il costruttore 'B' ha bisogno del costruttore' A', ed è per questo che hai ottenuto l'errore 'super costruttore A() non è visibile per il costruttore predefinito :) Spero che aiuti! – NiziL

+0

forse dovrei usare virgole ...) Voglio dire che la classe è diventata definitiva, quando tutti i costruttori sono impostati come privati. –

3

In Java, se si crea un'istanza di Child Class, l'istanza Parent Class viene creata in modo implicito. Quindi il costruttore della classe Figlio deve essere visibile a Child Class poiché chiama il costruttore del costruttore Parent Class utilizzando super() nella prima istruzione stessa.

Quindi, se si cambia il costruttore della Parent Class-private, Child Class non poteva accedervi e non poteva creare qualsiasi istanza di una propria, in modo compilatore alla prima mano proprio non permettere questo a tutti.

Ma se si vuole private costruttore di default in Parent Class, allora è necessario creare esplicitamente un sovraccarico public costruttore nel Parent Class & poi nel Child class costruttore è necessario chiamare utilizzando super(param) pubblico costruttore di sovraccarico di Parent Class.

Inoltre, si potrebbe pensare a cosa servono i costruttori private. I costruttori private vengono utilizzati principalmente quando non si desidera che gli altri di qualsiasi classe esterna chiamino new() sulla classe. In tal caso, forniamo il metodo getter() per fornire la classe object. In questo metodo è possibile creare/utilizzare l'oggetto esistente della classe & restituirlo da tale metodo.

Es. Calendar cal = Calendar.getInstance();. Questo in realtà costituisce la base del modello di progettazione Singleton.

+0

grazie, lo so. La mia domanda è perché super() non può chiamare il costruttore privato? È lo stesso motivo per cui i metodi privati ​​non possono essere ignorati? –

+1

super() non può chiamare costruttori 'private' di classe' Parent' semplicemente perché i membri 'private' sono accessibili solo all'interno della stessa classe, quindi la classe' Child' è una classe diversa che semplicemente non può accedervi. –

+0

@OlegKuts Se questo ha funzionato, puoi impostarlo come risposta corretta –

1

Il punto importante è capire che la prima riga di ogni costruttore è chiamare il super costruttore. Il compilatore rende il tuo codice più breve inserendo super() sotto le copertine, se non invochi tu stesso un super costruttore.

Ora, se si crea quel costruttore nella superclasse privata, il concetto sopra menzionato fallirà.

0

Può funzionare

class A { 
    private A() { 
    } 
    public A(int i){ 
    } 
} 

public class B extends A { 
    private A(){ 
     super(10); 
    } 
} 

o rimuovere la A privata(), di default a un pubblico(), a meno che non si dispone di un altro costruttore

class A { 

} 

public class B extends A { 
    private A(){ 
     super(); 
    } 
} 
0

un'istanza della classe B crea un'istanza di classe A quindi B deve invocare super(...) se A implementa un costrittore non predefinito. Così il costruttore dovrebbe essere protected per B essere in grado di chiamare super(...)

0
public class B extends A { 

/* 
* The default constructor B means 
* public() B {super();} 
*/ 
    public B() { 
    } 
} 

Così si dovrebbe definire un costruttore che è accessibile da parte della classe B

  1. È possibile cambiare il modificatore di accesso per il genitore Constructor
  2. Oppure è possibile definire un altro costruttore nella classe genitore accessibile dalla classe B e chiamare tale costruttore.
1

La classe B ha un costruttore predefinito, B() - perché non è stato definito esplicitamente nessun altro. Questo costruttore chiama implicitamente il suo super costruttore, A(). Ma hai reso esplicitamente quello privato alla classe A, quindi hai esplicitamente dichiarato che nessun'altra classe, inclusa B, può avere accesso ad essa.