2010-02-04 16 views
1

Je suis nouveau à Java et OOP,Puis-je rendre public un membre protégé en Java? Je veux accéder à partir d'une sous-classe

J'utilisais une sous-classe privée (en fait une struct) B dans une classe A, et tout s'est bien passé jusqu'à ce que je décide de faire un classe parent C pour la sous-classe B. Je veux rendre publics certains des membres protégés de la classe C.

par exemple:

public class A { 
    private class B extends C { 
     public int product; 
     public int x; 
     public int y; 
     public void add() { 
      product=x+y; 
     } 
    } 
    B b=new B; 
    b.x=1; 
    b.y=2; 
    b.multiply(); 
    System.out.println(b.product+"="+b.x+"x"+b.y); 

public class C { 
    protected int x; 
    protected int y; 
    public int sum; 
    public C(px,py) { 
     x=px; 
     y=py; 
    } 
    public void sum() { 
     sum=x+y; 
    } 
} 

Et je reçois

const super implicite Le propriétaire C() n'est pas défini pour le constructeur par défaut. Doit définir un constructeur explicite

Bien sûr, je pourrais supprimer étend C, et revenir à ce que j'avais avant. Ou je pourrais faire un getter/setter. Mais je pense qu'il est compréhensible qu'une structure interne soit acceptable, et qu'elle devrait pouvoir étendre d'autres classes.

Répondre

5

Le message du compilateur est assez clair - en B que vous avez efficacement obtenu:

public B() { 
    super(); 
} 

et qui ne réussit pas parce qu'il n'y a pas de constructeur de C en parameterless appeler. Introduisez un constructeur sans paramètre ou fournissez un constructeur explicite dans B qui appelle le constructeur en C avec les arguments appropriés.

Je ne suis pas sûr que ce soit une bonne idée d'avoir tous ces champs non-privés, ce n'est pas une bonne idée pour les champs dans B pour cacher les champs dans C. voulez vraiment une instance de B pour avoir deux champs x et deux champs y? Vous réalisez qu'ils seront des champs séparés, n'est-ce pas?

Si vous voulez juste de fournir efficacement l'accès du public, vous pourriez avoir:

public void setX(int x) { 
    this.x = x; 
} 

public int getX() { 
    return x; 
} 

(et même pour y) et de supprimer les champs supplémentaires de B. Vous ne pouvez pas modifier l'accessibilité réelle du champs en C si.

+0

wow, qui était rapide grâce à la 3^10 m/s réponse ... Je viens de me douter que j'avais besoin d'un constructeur par défaut protégé – TiansHUo

+0

@Skeet: Voulez-vous vraiment qu'une instance de B ait deux champs x et deux champs y? Vous réalisez qu'ils seront des champs séparés, n'est-ce pas? Non, je ne comprends pas ce que vous voulez dire par les champs séparés? Cela fonctionnera-t-il quand j'appellerai sum() qui se trouve dans la superclasse C? – TiansHUo

+0

@TiansHUo: Non, sum() somme les champs déclarés en C, qui sont entièrement séparés des champs déclarés en B. (Je devrais également souligner que 'product()' et 'sum()' seraient probablement les meilleurs retourner la valeur plutôt que de la placer dans un autre champ.) –

0

D'accord, je fuddling avec mon propre code et trouvé que le problème est que je besoin d'un constructeur par défaut protégé pour superclasse C. Il travaille maintenant ...

+0

Mec, vous pouvez seulement poster une réponse à une question et poster à nous que la réponse fonctionne. Vous auriez pu ajouter un commentaire comme je l'ai fait à votre propre question. Lisez la FAQ. –