2015-07-03 3 views
5

Если конструкторы не наследуются на Java, почему я получаю ошибку компиляции (неявный супер конструктор A() не отображается для конструктора по умолчанию. явный конструктор)?Почему конструктор частного базового класса приводит к тому, что «Неявный супер конструктор не отображается»

class A { 
    private A() { 
    } 
} 

public class B extends A { 

} 

UPD. Я знаю, что super() вызывается в неявном B-конструкторе. Но я не понимаю, почему он не может получить доступ к частному конструктору с super(). Итак, если у нас есть только частные конструкторы, класс de facto - final?

+0

(Ответ на ваш последний вопрос: «да», если вы имеете в виду под «окончательным», что «он не может быть подклассифицирован». Он должен (вероятно, я думаю) не предполагать, однако, что компилятор также обнаружит это и обрабатывать класс А точно так же, как если бы он был явно объявлен «окончательным».) –

+0

Возможный дубликат [Как разрешить] Неявный суперструктор classA() не отображается. Должен явно ссылаться на другой конструктор?? (Http://stackoverflow.com/questions/3904355/how-to-resolve-implicit-super-constructor-classa-is-not-visible-must-explici) – Raedwald

ответ

10

если B extends A, B должен иметь доступ к конструктору A.

Имейте в виду, что конструктор всегда вызывает super(). Таким образом, неявный беззаметный конструктор B не может вызвать конструктор A.

+0

Я знаю, что супер() вызывается в неявном B-конструкторе. Но я не понимаю, почему он не может получить доступ к частному конструктору с помощью функции super(). Итак, если у нас есть только частные конструкторы, то де-факто является окончательным? –

+0

@OlegKuts Вы путаете некоторые вещи здесь! Конструктор не может быть «final», на самом деле JLS, указанный конструктор, нельзя переопределить. Таким образом, конструктор 'B' не переопределяет конструктор' A', а просто вызывает его. Установка '' 'конструктора' private' означает, что он не может использоваться вне класса 'A' ​​и поэтому не может использоваться в классе' B', но конструктору 'B' нужен конструктор' A', и вот почему вы получили ошибку 'super constructor A() не видим для конструктора по умолчанию' :) Надеюсь, что это поможет! – NiziL

+0

Может быть, я должен использовать запятые ...) Я имею в виду, что класс стал окончательным, когда все конструкторы настроены на частные. –

3

В Java, если вы создаете экземпляр Child Class, Parent Class экземпляр создается неявно. Конструктор дочернего класса должен быть видимым до Child Class, поскольку он вызывает конструктор конструктора Parent Class, используя super() в самом первом утверждении.

Так что, если вы измените конструктор Parent Class к private, Child Class не мог получить доступ к нему и не может создать любой экземпляр самостоятельно, так компилятор на первой руке просто не позволяет этого вообще.

Но если вы хотите private конструктор по умолчанию в Parent Class, то вам необходимо явно создать перегруженную public конструктора в Parent Class & затем в Child class конструкторе вам нужно вызвать с помощью super(param) общественности перегруженного конструктора Parent Class.

Кроме того, вы можете подумать, что использовать private конструкторы. private конструкторы в основном используются, когда вы не хотите, чтобы другие из любого внешнего класса вызывали new() на ваш класс. Таким образом, в этом случае мы предоставляем некоторый метод getter() для предоставления класса object. В этом методе вы можете создать/использовать существующий объект своего класса &, чтобы вернуть его из этого метода.

Например. Calendar cal = Calendar.getInstance();. Это фактически составляет основу шаблона проектирования Singleton.

+0

спасибо, я это знаю. Мой вопрос в том, почему super() не может вызвать частный конструктор? Это та же причина, по которой частные методы нельзя переопределить? –

+1

super() не может вызывать конструкторы 'private' класса' Parent' просто потому, что члены 'private' доступны только в одном классе, поэтому класс' Child' является другим классом, который просто просто не может получить к нему. –

+0

@OlegKuts Если это сработало для вас, вы можете установить это как правильный ответ –

1

Важным моментом является понимание того, что первая строка любого конструктора - это вызов супер-конструктора. Компилятор делает ваш код короче, вставив super() под обложки, если вы не вызываете супер-конструктор самостоятельно.

Теперь, если вы создадите этот конструктор в закрытом суперклассе, вышеупомянутая концепция не удастся.

0

Может работать

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

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

Или удалить частный A(), по умолчанию общественности A(), , если у вас нет другого конструктора

class A { 

} 

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

Экземпляр класса B создает экземпляр класс A, поэтому B должен ссылаться на super(...), если A реализует нестандартный конструктор. Таким образом, конструктор должен быть protected для B быть в состоянии назвать super(...)

0
public class B extends A { 

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

Таким образом, вы должны определить конструктор, который доступен по классу B

  1. Вы можете изменить модификатор доступа для родительского конструктора
  2. Или вы можете определить другой конструктор в родительском классе, доступный классом B и вызвать этот конструктор.
1

Ваш класс B имеет конструктор по умолчанию, B() - потому что вы явно не определили какой-либо другой. Этот конструктор неявно называет его супер-конструктор A(). Но вы явно сделали это частным для класса A, так что вы явно заявили, что ни один другой класс, включая B, не может иметь к нему доступ.

Смежные вопросы