1
votes

Accéder à une propriété d'une sous-classe

Je suis assez nouveau sur Java et j'ai du mal à comprendre pourquoi j'obtiens toujours une erreur sur la ligne de commande. J'ai une superclasse, Guest, avec des variables guestID, fName, lName et dateJoin. J'ai aussi une sous-classe VIPGuest avec les variables supplémentaires VIPstartDate et VIPexpiryDate.

J'ai un invité ArrayList, qui contient tous les objets invités que j'ai dans mes enregistrements. Je veux parcourir ArrayList et écrire chaque invité dans un fichier texte, avec chaque invité sur une nouvelle ligne sous la forme guestID, fName, lName, dateJoin séparés par des virgules (ou guestID, fName, lName, dateJoin, VIPstartDate, VIPexpiryDate si l'invité est un VIPGuest).

Mon code est ci-dessous. Cela fonctionne bien lorsque j'utilise un code similaire pour faire une chose similaire pour une ArrayList d'objets d'une classe sans sous-classes, mais lorsque j'essaye de le faire fonctionner autour du fait que certains invités ont des variables supplémentaires, l'erreur est: p>

  public boolean saveGuestsData(String guestsTxtFileName){
    BufferedWriter writer;
    try{
      writer = new BufferedWriter(new FileWriter(guestsTxtFileName));
    } catch (IOException e){
      System.out.print("Invalid file.");
      return false;
    }
      try{
            for (Guest g : guests){
              if (!(g instanceof VIPGuest)){
                writer.write(
                g.getGuestID() + "," + g.getFName() + "," + getLName() 
                + "," + g.getDateJoin());

              }
              else {
                writer.write(
                g.getGuestID() + "," + g.getFName() + "," + 
                getLName() + "," + g.getDateJoin() + "," + 
                g.getVIPstartDate() + "," + g.getVIPexpiryDate());
              }
              writer.newLine();

            }
          writer.close();
          return true;
          } catch (FileNotFoundException ex) {
            System.out.print("File not found.");
            return false;
          } catch (IOException e){
            System.out.print("Invalid file.");
            return false;
          }
  }

Je peux voir qu'il a des problèmes avec les variables supplémentaires pour les objets VIPGuest, mais j'ai pensé que j'avais corrigé cela avec le if / else:

  HotelImpl.java:440: error: cannot find symbol
                    + "," + g.getVIPstartDate() + "," + g.getVIPexpiryDate());
                             ^
      symbol:   method getVIPstartDate()
      location: variable g of type Guest
    HotelImpl.java:440: error: cannot find symbol
                    + "," + g.getVIPstartDate() + "," + g.getVIPexpiryDate());
                                                         ^
      symbol:   method getVIPexpiryDate()
      location: variable g of type Guest
    2 errors


3 commentaires

g est un invité, pas un VIPGuest. Si vous souhaitez utiliser les méthodes de la classe VIPGuest, vous devez convertir g en VIPGuest - par exemple. ((VIPGuest) g) .getVIPstartDate ()


Cela l'a corrigé! Merci :)


@Habilee je vous recommande d'utiliser un IDE, il vous expliquera ce type d'erreur


3 Réponses :


1
votes

Dans cette réponse, je suppose que VIPGuest étend Guest .

Avant de pouvoir utiliser l'une des méthodes VIPGuest sur un serveur Invité , vous devez convertir l'invité en VIPGuest.

for (Guest g : guests){
  if (!(g instanceof VIPGuest)){
    // omitted for brevity
  } else {
    VIPGuest vip = (VIPGuest)g;
    writer.write(vip.getGuestID() + "," + vip.getFName() + "," + vip.getLName() + "," + 
                 vip.getDateJoin() + "," + vip.getVIPstartDate() + "," + vip.getVIPexpiryDate());
  }
  writer.newLine();

}

Bien que vous le sachiez - en utilisant le instanceof code > vérifiez - que g est en fait un VIPGuest, la référence que vous y avez n'est que d'un invité.

Notez que si g ne l'était pas en fait une instance de VIPGuest , la tentative de cast (VIPGuest) g lèverait probablement une ClassCastException.


1 commentaires

Droite. J'étais sur le point de publier une réponse similaire;)



0
votes

Votre variable g est de type Guest et bien que l'instance soit un VIPGuest , la méthode getVIPstartDate est non disponible.

Ce que vous devez faire est:

else
{
  VIPGuest vg;
  vg = (VIPGuest)g;
  writer.write(
    vg.getGuestID() + "," + vg.getFName() + "," + 
    getLName() + "," + vg.getDateJoin() + "," + 
    vg.getVIPstartDate() + "," + vg.getVIPexpiryDate());
}

Encore mieux:

Remplacez la méthode toString () dans Guest et VIPGuest .
Ce dernier appelle super.toString () et ajoute les informations supplémentaires.


0 commentaires

1
votes

g est une référence de type Guest , vous ne pouvez donc accéder qu'aux membres de Gusest depuis celle-ci. Si vous souhaitez accéder aux membres de VIPGuest , vous devrez le décliner explicitement. Par exemple:

for (Guest g : guests) {
    writer.write(g.toString());
}

Cela devrait fonctionner, mais c'est une mauvaise conception, cela oblige votre méthode saveGuestsData à avoir une connaissance intime de vos implémentations Guest . Une conception plus robuste consiste à déplacer cette logique vers les classes Guest , et que cette méthode les appelle simplement:

public class Guest {
    @Override
    public String toString() {
        return getGuestID() + "," + getFName() + "," +  getLName() + "," + g.getDateJoin();
    }

    // other methods...
}

public class VIPGuest extends Guest {
    @Override
    public String toString() {
        return super.toString() + ", " + getVIPstartDate() + "," + getVIPexpiryDate());

    // other methods...
}

Et puis appelle simplement cette méthode :

VIPGuest vg = (VIPGuest) g;
writer.write(g.getGuestID() + "," + 
             g.getFName() + "," + 
             g.getLName() + "," +
             g.getDateJoin() + "," + 
             vg.getVIPstartDate() + "," + 
             vg.getVIPexpiryDate());


0 commentaires