Solved need some help with extending abstract classes

Discussion in 'Plugin Development' started by xize, Dec 12, 2014.

Thread Status:
Not open for further replies.
  1. Offline

    xize

    Hello,

    so I'm trying to make a bit of better design in my plugin so that 2 objects both hold the same FileConfiguration instance rather than having 2 very inefficient ones.

    ive for example 2 instances, one is called Player and the other is called OfflinePlayer.

    I made the Player instance abstract because I don't want to have it instanced, the OfflinePlayer can be instanced though.

    now my idea is to have it casted like this: (Player)offlineinstance, however this doesn't work for me because it throws a ClassCastException even though the Player instance has extended the OfflinePlayer instance and the super constructor is set but ive no idea how to pass something through the constructor while it is abstract.

    my question now is, what did I missed or forgot?, does the field names have to match indentical with each other?

    this is my own xEssentialsPlayer object (Im only going to put the class name and constructor its more than 1k lines):
    Code:
    public abstract class xEssentialsPlayer extends xEssentialsOfflinePlayer {
      //private File f;
      //private FileConfiguration con;
      private Item Potato;
      private AlternateAccount accounts;
      private BukkitTask spectate;
    
      public xEssentialsPlayer(Player p, String uuid) {
      super(p, uuid);
      }
    
    and this one is my offline instance:
    Code:
    public class xEssentialsOfflinePlayer {
      private final File f;
      private final FileConfiguration con;
      private String player;
      private AlternateAccount accounts;
      private Player p;
    
      public xEssentialsOfflinePlayer(Player p, String UUID) {
      if(Configuration.getDebugConfig().isEnabled()) {
      xEssentials.getPlugin().log("setting profile for player " + p.getName(), LogType.DEBUG);
      }
      this.p = p;
      if(Bukkit.getOnlineMode()) {
      this.f = new File(xEssentials.getPlugin().getDataFolder() + File.separator + "players"+File.separator+UUID+".yml"); 
      } else {
      this.f = new File(xEssentials.getPlugin().getDataFolder() + File.separator + "players"+File.separator+p.getName().toLowerCase()+".yml");
      }
      if(this.f.exists()){
      if(Configuration.getDebugConfig().isEnabled()) {
      xEssentials.getPlugin().log("profile found, checking for a possible name change!", LogType.DEBUG);
      }
      this.con = YamlConfiguration.loadConfiguration(this.f);
      if(!this.getData().getString("user").equalsIgnoreCase(p.getName())) {
      if(Configuration.getDebugConfig().isEnabled()) {
      xEssentials.getPlugin().log("the players name is changed from " + this.getData().getString("user") + " to " + p.getName(), LogType.DEBUG);
      }
      String oldName = this.getData().getString("user");
      this.getData().set("user", p.getName());
      this.getData().set("ip", p.getAddress().getAddress().getHostAddress());
      try {
      this.getData().save(f);
      } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
      }
      //call the custom event whenever we noticed the name has been changed!
      //Bukkit.getPluginManager().callEvent(new PlayerNameChangeEvent(oldName, player.getName(), player, this));
      setNameHistory(oldName);
      if(Configuration.getProtectionConfig().isProtectionEnabled()) {
      xEssentials.getManagers().getProtectionDBManager().updatePlayer(oldName, p.getName());
      }
      } else {
      if(Configuration.getDebugConfig().isEnabled()) {
      xEssentials.getPlugin().log("players name is still intact and matches with: " + UUID, LogType.DEBUG);
      }
      this.getData().set("ip", p.getAddress().getAddress().getHostAddress());
      try {
      this.getData().save(f);
      } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
      }
      }
      } else {
      //check if the player file is just a normal name if it is we rename the file to the UUID spec, then cancelling futher code execution.
      if(Configuration.getDebugConfig().isEnabled()) {
      xEssentials.getPlugin().log("profile not found, checking for non converted names in order to convert...", LogType.DEBUG);
      }
      File possiblename = new File(xEssentials.getPlugin().getDataFolder() + File.separator + "players" + File.separator + p.getName().toLowerCase() + ".yml");
      if(possiblename.exists()) {
      if(Configuration.getDebugConfig().isEnabled()) {
      xEssentials.getPlugin().log("profile of "+p.getName()+" has been successfull found and renamed to the uuid spec", LogType.DEBUG);
      }
      possiblename.renameTo(this.f);
      this.con = YamlConfiguration.loadConfiguration(this.f);
      return;
      }
      this.con = YamlConfiguration.loadConfiguration(this.f);
      this.getData().set("isDefault", true);
      this.getData().set("ip", p.getAddress().getAddress().getHostAddress());
      this.getData().set("user", p.getName());
      this.getData().set("fly", false);
      this.getData().set("torch", false);
      this.getData().set("firefly", false);
      this.getData().set("uuid", p.getUniqueId().toString());
      if(Configuration.getEconomyConfig().isEconomyEnabled()){
      this.getData().set("money", Configuration.getEconomyConfig().getStartersMoney());
      }
      try {
      this.getData().save(this.f);
      } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
      }
      }
      update();
      }
    
    now what I do is to instance it is:
    Code:
    xEssentialsPlayer xp= (xEssentialsPlayer)new xEssentialsOfflinePlayer(p, uuid);
    
    but this causes a ClassCastException, Im pretty sure I miss something, or I miss understand how this works.

    thanks for the help though:)
     
  2. Offline

    fireblast709

    @xize you can only cast an object to it's class or a super class. xEssentialsOfflinePlayer does not extend xEssentialsPlayer, and it's not an xEssentialsPlayer, thus you cannot cast it.

    That aside, abstract classes can still be extended, you would need to make the constructor private or package private (no access modifier) to 'stop'* initialisation.

    *There's always reflection
     
    xize likes this.
  3. Offline

    Rocoty

    @xize You can't create an xEssentialsOfflinePlayer and expect it to be an xEssentialsPlayer. Or to put it another way, you can't have a Vehicle and expect it to be a Car, because it isn't necessarily a Car. However, a Car is always a Vehicle. There is a certain "IS-A" relationship involved.

    http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
     
    xize and teej107 like this.
  4. Offline

    teej107

    xize likes this.
  5. Offline

    xize

    aha thanks guys, I think I just keep it as it was since my internal part is not designed for this kind of implementation as it seems:p

    however Im still going to play around with this though to get a idea how the intheriting works, because I thought when you extend a class you only has to put the contents in the super constructor and from there do a cast to the super class I geuss I did it exactly the opposite of that:p
     
Thread Status:
Not open for further replies.

Share This Page