Pregunta

Estoy leyendo Sybex completa Java 2 Certificación Guía de Estudio de abril de Encuentro 2005 (ISBN0782144195). Este libro es para los desarrolladores de Java que quiere pasar la certificación de Java.

Después de un capítulo sobre modificadores de acceso (junto con otros modificadores) me encontré con la siguiente pregunta (# 17):

  

Verdadero o falso: Si la clase Y se extiende   la clase X, las dos clases están en   diferentes paquetes, y la clase X tiene una   método protegido llama abby (), entonces   cualquier instancia de Y puede llamar a la abby ()   método de cualquier otra instancia de Y.

Esta pregunta me confundió un poco.

Por lo que yo sé que usted puede llamar al método protegido en cualquier variable de la misma clase (o subclase). No se puede llamar de variables, que el aumento en la jerarquía de lo que (por ejemplo interfaces que implementan).

Por ejemplo, no se puede clonar cualquier objeto sólo porque se hereda a él.

Pero las preguntas no dice nada sobre el tipo de variable, sólo el tipo de instancia.

Yo estaba confundido un poco y respondió "verdadero".

La respuesta en el libro es

  

Falso. Un objeto que hereda un método protegido de una superclase en un paquete diferente puede llamar a ese método en sí mismo, pero no en otras instancias de la misma clase.

No hay nada aquí sobre el tipo de variable, sólo el tipo de instancia.

Esto es muy extraño, yo no lo entiendo.

¿Alguien puede explicar lo que está pasando aquí?

¿Fue útil?

Solución

  

Verdadero o falso: Si la clase Y se extiende la clase X, las dos clases se encuentran en diferentes paquetes, y la clase X tiene un método protegido llamado abby (), entonces cualquier instancia de Y puede llamar al método abby () de cualquier otra instancia de Y.

     

"Falso. Un objeto que hereda un método protegido de una superclase en un paquete diferente puede llamar a ese método en sí mismo, pero no en otras instancias de la misma clase".

Vamos a escribir eso, como BalusC lo hizo, y añadir a y un método que llama a la abby () de cualquier otra instancia de y:

package one;
public class X {
    protected void abby() {
    }
}

package other;
import one.X;
public class Y extends X {
    public void callAbbyOf(Y anyOther) {
        anyOther.abby();
    }
}

es posible para Y para llamar al método abby () de cualquier instancia de Y a la que tiene una referencia . Así que la respuesta en el libro es manifiestamente errónea. Java no tiene alcances específicos de la instancia (a diferencia, por ejemplo, Scala, que tiene un alcance instancia-privada).

Si tratamos de ser misericordioso, tal vez la pregunta significa decir " cualquier otra instancia de Y" que puede acceder el método de cualquier instancia de Y, que pasa a estar en la memoria - lo cual no es posible, porque Java no tiene acceso directo a memoria. Pero en ese caso la pregunta es tan mal redactado, que incluso se podría responder: ". Falso No se puede llamar a métodos en los casos que se encuentran en una JVM diferente, o los casos que se han recogido de basura, o instancias en una JVM, que murió uno hace años, etc ".

Otros consejos

La especificación del lenguaje Java :

6.6.2.1 El acceso a un área protegida miembros

Sea C la clase en la que se declara un miembro protegido m. se permite el acceso sólo dentro del cuerpo de una subclase S de C. Además, si Id denota un campo de instancia o método de instancia, entonces:

  • Si el acceso es por un nombre calificado Q.Id, donde Q es un ExpressionName, entonces se permite el acceso si y sólo si el tipo de la expresión Q es S o una subclase de S.
  • Si el acceso es por una expresión de acceso E.Id campo, donde E es una expresión primaria, o por una expresión de invocación de método E.Id (...), Donde E es una expresión primaria, entonces se permite el acceso si y sólo si el tipo de e es S o una subclase de S.

Así que el miembro protegido es accesible en todas las instancias de S, y la respuesta en su libro es simplemente incorrecto.

Esta pregunta parece mal redactada - y le pregunta acerca de un caso muy raro borde (que yo ni siquiera estoy seguro está cubierto en la prueba SCJP). La forma en que está redactado hace que su respuesta correcta y la respuesta dada incorrecta. Codificación de una construcción similar y ejecutarlo fácilmente lo demuestra ...

package inside;

public class Base {

    private String name;

    public Base(String name)  {
        this.name = name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    protected String abby(String name) {
        String old = this.name;
        this.name = name;
        return old;
    }
}




package outside;
import inside.Base;

public class Another extends Base {

    public Another(String name) {
        super(name);
    }

    public String setAnother(Another another, String hack) {
        return another.abby(hack);
    }

    public static void doCrazyStuff() {
        Another one = new Another("one");
        Another two = new Another("two");

        one.abby("Hi one"); 
        two.abby("Hi two");
        one.setAnother(two, "Hi two from one");

        System.out.println("one = " + one.getName());
        System.out.println("two = " + two.getName());

    }

    public static void main(String[] args) {
        Another.doCrazyStuff();
    }
}

Debido a que tipo de variable es irrelevante aquí hasta que es 'sana' en el contexto de la pregunta. Como método abby() pertenece a X (y Y hereda), no importa con qué tipo se declara ejemplo de referencia variable de los Y: que puede ser o bien X o Y. abby() ser accesible, que podríamos llamar a través de dos variables:

X myY1 = new Y();
myY1.abby();

Y myY2 = new Y();
myY2.abby();
  

Verdadero o falso: Si la clase Y se extiende la clase X, las dos clases se encuentran en diferentes paquetes, y la clase X tiene un método protegido llamado abby (), entonces cualquier instancia de Y puede llamar al método abby () de cualquier otra instancia de Y.

Vamos a representarlo.

Clase X:

package one;
public class X {
    protected void abby() {}
}

Clase Y:

package other;
public class Y extends X {}

caso_prueba:

public static void main(String[] args) {
    Y y1 = new Y();
    Y y2 = new Y();
    Y y3 = new Y();
    // ...
}

Ahora vuelva a leer la pregunta: ¿puede y1 abby() llamada en y2, y3, etc? Va a llamar abby() en y1 también llamar a los de y2, y3, etc?

Para preguntas futuras, tratar de agarrar la pluma y papel e interpretar las preguntas literalmente. Hay más o menos agujeros en ese tipo de preguntas simuladas.

Estoy casi seguro de que la pregunta significaba:

"cualquier instancia de Y puede llamar al método Abbey () de cualquier otra instancia de X " (no Y).

En ese caso, será de hecho fracasar. Para tomar prestado el ejemplo de otra respuesta anterior, los siguientes:

package one;
public class X {
    protected void abby() {
    }
}

package other;
import one.X;
public class Y extends X {
    public void callAbbyOf(X anyOther) {
        anyOther.abby();
    }
}

fallará para compilar.

La especificación del lenguaje Java explica por qué aquí: http://java.sun.com/docs/books/jls/third_edition/html/names.html#6.6.2

  

6.6.2.1 El acceso a un miembro protegido

     

Sea C la clase en la que una   miembro protegido m se declara. Acceso   sólo se permite dentro del cuerpo de una   subclase S de C. Además, si Id   denota un campo de instancia o instancia   método, entonces: Si el acceso es por una   nombre calificado Q.Id, donde Q es una   ExpressionName, entonces el acceso es   permitida si y sólo si el tipo de   la expresión Q es S o una subclase de   S. Si el acceso es por un acceso de campo   E.Id expresión, donde E es una primaria   expresión, o por una invocación de método   expresión E.Id (...), donde E es una   expresión primaria, entonces el acceso es   permitida si y sólo si el tipo de E   es S o una subclase de S. (énfasis).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top