que - ¿Cómo se protegen los métodos protegidos de java.lang.Object de las subclases?
que es public en programacion (3)
Cuando dijiste " ((Object) this).clone()
", ((Object) this).clone()
a tu propio objeto a través de su objeto superclase. Usted realizó una conversión de ampliación a un Objeto. El código intenta llamar a clon en Object.
Pero, como ha notado, clonar es un método protegido, lo que significa que solo si su objeto estaba en el mismo paquete de java.lang, podría acceder al método de clonación del OBJETO.
Cuando dices this.clone, tu clase extendió Object y, por lo tanto, tuvo acceso para anular o usar el clon directamente a través del modificador de clase protegida debido a la herencia. Pero eso no cambia la implementación del Objeto.
Al decir ((Object) yourObject), obtienes algo a lo que solo se puede acceder a través de la clase Object. Solo los métodos públicos de la clase Object están accesibles fuera del paquete java.lang, por lo que se obtiene la excepción en tiempo de compilación, porque el compilador lo sabe.
Al decir this.clone (), está invocando el método de clonación de su objeto heredado a través de Object, y ahora se puede invocar porque se convierte en una parte de su subclase personalizada.
La palabra clave protected
garantiza el acceso a clases en el mismo paquete y subclases ( http://java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.html ).
Ahora, cada clase tiene java.lang.Object
como superclase ( http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Object.html ).
Por lo tanto, concluyo que cada clase puede acceder a los métodos de java.lang.Object
incluso si están protected
.
Eche un vistazo al siguiente ejemplo:
public class Testclass { public Object getOne() throws CloneNotSupportedException { return this.clone(); } public Object getTwo() throws CloneNotSupportedException { return ((Object) this).clone(); } }
Mientras getOne()
compila bien, getTwo()
da
Testclass.java:6: clone() has protected access in java.lang.Object return ((Object) this).clone();
No entiendo por qué getTwo()
no compila ni cuál es la diferencia (con respecto al acceso de los miembros de java.lang.Object
s) con getOne()
.
La diferencia es cómo está accediendo a Object.clone (). clon solo es accesible cuando se accede a través de una subclase o clase en el mismo paquete. En el ejemplo getOne (), está claling this.clone (). Esto claramente satisface el acceso desde dentro de una subclase.
En getTwo (), aunque estás accediendo a Object.clone () y no a TestClass.clone (). Para que esto funcione, debe tener acceso a nivel de paquete a Object que no tiene y, por lo tanto, el error.
Solo puede acceder a los miembros protegidos de un tipo en un paquete diferente si el tipo de tiempo de compilación de la expresión a la que hace referencia es su propia clase o una subclase. (Donde "tu" clase es la clase que contiene el código.) Tu propia clase tiene que ser una subclase del tipo que originalmente declara el método también.
Aquí hay un ejemplo; Supongamos que Base
está en un paquete diferente a todas las otras clases:
package first;
public class Base
{
protected void Foo() {}
}
// Yes, each class is really in its own file normally - but treat
// all the classes below as being in package "second"
package second;
public class Child extends Base
{
public void OtherMethod(Object x)
{
((Base) x).Foo(); // Invalid: Base is not Child or subclass
((Child) x).Foo(); // Valid: Child is Child
((GrandChild) x).Foo(); // Valid: GrandChild is subclass of Child
((OtherChild) x).Foo(); // Invalid: OtherChild is not Child or subclass
}
}
public class GrandChild extends Child {}
public class OtherChild extends Base {}
En otras palabras, le permite tener acceso a los miembros protegidos de "objetos que son como usted".
Los detalles se encuentran en la sección 6.6.2 de la Especificación del lenguaje Java :
Se puede acceder a un miembro o constructor
protected
de un objeto desde fuera del paquete en el que se lo declara solo por código que es responsable de la implementación de ese objeto.6.6.2.1 Acceso a un Miembro protegido
Sea C la clase en la que se declara un miembro protegido m . El acceso solo está permitido 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 Nombre de expresión , entonces el acceso está permitido si y solo 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 de campo E.Id , 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 el acceso está permitido si y solo si el tipo de E es S o una subclase de S.