J'ai une classe abstraite, relation
dans le paquet database.relation
et une sous-classe de celui-ci, Join
, dans le paquet database.operations
. relation
a un membre protégé nommé mStructure
.
Dans Join
:
public Join(final Relation relLeft, final Relation relRight) {
super();
mRelLeft = relLeft;
mRelRight = relRight;
mStructure = new LinkedList<Header>();
this.copyStructure(mRelLeft.mStructure);
for (final Header header :mRelRight.mStructure) {
if (!mStructure.contains(header)) {
mStructure.add(header);
}
}
}
Sur des lignes
this.copyStructure(mRelLeft.mStructure);
et
for (final Header header : mRelRight.mStructure) {
Je reçois l'erreur suivante:
La relation de champ.mstructure n'est pas visible
Si je mettez les deux classes dans le même paquet, cela fonctionne parfaitement. Quelqu'un peut-il expliquer ce problème?
Cela fonctionne, mais seuls vous les enfants essaient d'y accéder propre variable, pas variable d'une autre instance (même s'il appartient au même arborescence d'héritage).
Voir cet exemple de code pour mieux comprendre:
//in Parent.Java
package parentpackage;
public class Parent {
protected String parentVariable = "whatever";// define protected variable
}
// in Children.Java
package childenpackage;
import parentpackage.Parent;
class Children extends Parent {
Children(Parent withParent ){
System.out.println( this.parentVariable );// works well.
//System.out.print(withParent.parentVariable);// doesn't work
}
}
Si nous essayons de compiler en utilisant le withParent.parentVariable
nous avons:
Children.Java:8: parentVariable has protected access in parentpackage.Parent
System.out.print(withParent.parentVariable);
Il est accessible, mais seulement à sa propre variable.
Un peu de mise en garde connue sur protégée :
6.6.2 Détails sur l'accès protégé
Un membre protégé ou un constructeur d'un objet peut être accessible de l'extérieur de l'emballage dans lequel il n'est déclaré que par code responsable de la mise en œuvre de cet objet.
Si protected
, votre instance de Join
ne peut pas accéder à mStructure
dans d'autres instances (relRight
, relLeft
) en dehors du package.
ÉDITER:
La table ici explique cette situation assez bien. J'ai marqué le coupable dans votre question avec []
s
Access Levels
Modifier Class Package Subclass World
public Y Y Y Y
protected Y [Y] Y N
no modifier Y Y N N
private Y N N N
Le problème est que vous accédez à un autre membre protégé d'instance.
Vous pouvez appliquer plusieurs solutions, par exemple si possible, vous pouvez déclarer dans la classe mère ces deux méthodes:
protected void copyRelationStructure(Relation r) {
this.copyStructure(r.mStructure);
}
protected void mergeRelationStructure(Relation r) {
for (final Header header: r.mStructure) {
if (!mStructure.contains(header)) {
mStructure.add(header);
}
}
}
Puis dans le code des enfants remplacer:
this.copyStructure(mRelLeft.mStructure);
for (final Header header :mRelRight.mStructure) {
if (!mStructure.contains(header)) {
mStructure.add(header);
}
}
Avec:
this.copyRelationStructure(mRelLeft);
this.mergeRelationStructure(mRelRight);
Cela devrait fonctionner. Maintenant, la relation a la responsabilité de fournir des méthodes qui permettent des opérations avec elle-même à ses enfants. La raison de cette politique est probablement que les enfants ne devraient pas gâcher les internes des parents à moins qu'ils ne font partie du même paquet logiciel afin de limiter les incompatibilités.