sirve que para modificadores herencia constructores comando acceso java constructor private

que - protected java



Visibilidad de los constructores privados de Java (3)

Intento entender por qué hay una diferencia entre la accesibilidad de los miembros de la clase cuando se habla de constructores.

Considere el siguiente ejemplo:

class A { static class B { private B(String s) {} private void foo() {} } static class C extends B { public C(String s) { super(s); // call B(String), which is private, and obviously accessible } void bar() { foo(); // compilation error (symbol unknown), as B.foo() is private } } }

Los miembros privados de A , como privados, no deberían ser accesibles desde B Para campos y métodos, es el caso, pero parece que los constructores no siguen la misma regla.

Desde el JLS-8 ( 6.6.1. Determinación de la accesibilidad ), podemos leer:

[...]

Un miembro (clase, interfaz, campo o método) de un tipo de referencia, o un constructor de un tipo de clase, es accesible solo si el tipo es accesible y el miembro o constructor está declarado para permitir el acceso:

  • [...]

  • De lo contrario, el miembro o el constructor se declara private , y el acceso está permitido si y solo si ocurre dentro del cuerpo de la clase de nivel superior (§7.6) que encierra la declaración del miembro o constructor.

¿Alguien puede explicarme por qué se puede acceder al constructor desde C , incluso cuando se declara private ?


El método foo() es privado, por lo que no lo hereda y no puede llamarlo directamente desde la clase C

Sin embargo, puedes ver los métodos privados y el constructor desde B ya que todo está declarado en la misma clase contenedora, y acceder a ellos con super , por lo que super() funciona. De la misma manera, puedes acceder a foo con super.foo() .

Tenga en cuenta que puede redefinir un nuevo método foo en C , pero este método no reemplazará a B.foo() .


El método Foo () no es accesible en la clase C, ya que el método foo () es privado y el método privado no se puede heredar en la clase base.

Para los constructores, LOS CONSTRUCTORES NUNCA SERÁN HEREDADOS. Además, compilé este código:

class Vehicle{ int speed=50; private Vehicle() { System.out.println("Private Vehicle constructor"); } } public class Bike4 extends Vehicle{ int speed=100; Bike4() { super(); System.out.println("Hi I n constructor"); } void display(){ System.out.println(super.speed);//will print speed of Vehicle now } public static void main(String args[]){ Bike4 b=new Bike4(); b.display(); } }

Y obtenga Error de tiempo de compilación: Vehicle () tiene acceso privado en Vehicle super (); ^ Lo que indica claramente que no se puede acceder a un constructor privado usando super. Si podemos inicializar o acceder a un constructor privado, entonces ¿qué sentido tiene crear un constructor privado?


Entonces, el truco aquí podría ser el siguiente:

no puedes acceder a foo porque está declarado privado, por lo que no lo heredas en C.

Sin embargo, como se señaló en los comentarios, puede acceder a super.foo(); porque super refiere a un tipo que se declara en la misma clase de nivel superior (vea JLS 6.6.1 para esto).

Entonces el truco es que llamar a los super(s) se puede ver como a los que llaman super.<init>(s) que termina siendo el mismo caso que super.foo()