简体   繁体   English

从父类型子类对象Java访问子类实例方法

[英]Accessing Child class instance method from Parent type child class object Java

I apologise if my question seems a little ambiguous, and I know its been asked before but my circumstances are significantly different from what I've read.如果我的问题看起来有点模棱两可,我深表歉意,我知道之前有人问过它,但我的情况与我读过的有很大不同。

I'm looking for a SIMPLE, ELEGANT solution, not a complex workaround.我正在寻找一个简单、优雅的解决方案,而不是一个复杂的解决方法。

I'm working on coding an RPG, and ran into a snag while working on the inventory/item system.我正在编写 RPG 代码,在处理库存/物品系统时遇到了障碍。 Here is my object structure(not sure if that's the correct terminology) in English first, and some example code second.这是我的英语对象结构(不确定这是否是正确的术语),然后是一些示例代码。

A Player class has an instance variable of type Inventory. Player 类有一个 Inventory 类型的实例变量。

The Inventory class has an array of Item objects, that represent an item stored in an inventory slot. Inventory 类有一个 Item 对象数组,表示存储在库存槽中的项目。

The Item class has children such as Weapon, Armour, Potion etc. Item 类有子类,例如 Weapon、Armor、Potion 等。

I don't know what item the player will have, so the Inventory is initialised with Item objects, but when the player picks up a sword for example a new Weapon(ID) object is created and stored in the inventory, i still can't access the Weapon variables or methods without Typecasting every calling method over.我不知道玩家将拥有什么物品,所以库存是用 Item 对象初始化的,但是当玩家拿起一把剑时,例如一个新的武器(ID)对象被创建并存储在库存中,我仍然可以'无需对每个调用方法进行类型转换即可访问武器变量或方法。 This wouldn't normally be too much of an issue but with 20+ Item subsclasses totalling 100's of different variables and methods, they code required would be enormous to Typecast every time.这通常不会成为太大的问题,但是有 20 多个 Item 子类,总共有 100 个不同的变量和方法,每次 Typecast 所需的代码都是巨大的。

if (you see no problem and that's how its done) {如果(你看没有问题,这就是它的完成方式){

let me know让我知道

} else if (you have a better way of doing this) { } else if(你有更好的方法){

let me know.让我知道。

} }

Thanks!谢谢!

Player--has--Inventory--has--Item--hasChildren--Weapon/Armour.玩家--拥有--库存--拥有--物品--拥有孩子--武器/盔甲。

Below is a snipped to show what i have right now.下面是一个剪辑,以显示我现在所拥有的。 NOTE: There is significantly more variables and methods for each class, just showing what feels important.注意:每个类都有明显更多的变量和方法,仅显示重要的内容。

class Player {
   private Inventory inventory = new Inventory();
   public Item getInventoryItem(int slot){
      return inventory.getItemFromSlot(slot);
   }
}

class Inventory {
   private Item[] item;
   public Inventory() {
      this.item = new Item[INVENTORY_SIZE];
   }

   public Item getItemFromSlot(int slot) {
      return item[slot];
   }

// called when i pick up ANY ITEM.
// having a addWeapon(Weapon weapon) would make no difference (see end of code)
   public addItem(int slot, Item item) {
      inventory[slot] = item;  
   }
}

class Item {
   private int itemID;
   private int itemType;
   private String itemName;

   public Item(int ID) {
      this.itemID = ID;-
      this.itemName = getItemName(ID); //access a database which holds all item data
      this.itemType = getItemType(ID); //access a database holding all item types
   }
}

class Weapon extends Item {
   private int damage;

   public Weapon(int ID) {
      super(ID);
      this.damage = getWeaponDamage(ID);
   }

   public getDamage(){
      return damage;
   }
}

PROBLEM:

class Game {

//lets assume i have picked up a Weapon and it is now stored in slot i, as a Weapon not as an Item.

int test = player.getInventoryItem(i).getDamage(); //doesn't work, even when the item (i) class IS weapon
int test = ((Weapon)player.getInventoryItem(i)).getDamage(); //works
}

如果要访问武器特定的方法或变量,则必须将 Item 列表元素强制转换为武器,如果要使用多态,则类项必须具有该方法或变量,因此可以为每个项调用它。

Casting is necessary in this case because the class Item has no Method getDamage() .在这种情况下, getDamage()转换是必要的,因为Item类没有方法getDamage() Calling getInventoryItem() returns an Item , not a Weapon , so the parent class does not know anything about the methods of its child.调用getInventoryItem()返回一个Item ,而不是一个Weapon ,因此父类对其子类的方法一无所知。 One possible solution would be using self-type pattern mentioned here: Avoid casting in inherited java-classes一种可能的解决方案是使用这里提到的自类型模式: 避免在继承的 java 类中进行强制转换

So I've been testing some things myself.所以我自己一直在测试一些东西。 Because the compiler THINKS getInventoryItem() will always return an Item, it doesn't allow for the method getDamage() to be called.因为编译器认为getInventoryItem()将始终返回一个 Item,所以它不允许调用getDamage()方法。 But when the object referenced by getInventoryItem() is a Weapon, if I simply add int getDamage(){return -1} as a method of the Item class, I still get the correct int damage value from Weapon, and a -1 from anything else.但是当getInventoryItem()引用的对象是一个 Weapon 时,如果我简单地添加int getDamage(){return -1}作为 Item 类的方法,我仍然从 Weapon 中得到正确的int damage值,而从还要别的吗。 Perfect!完美的!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM