多态性介绍 101 java

Intro to polymorphism 101 java

我正在制作一款小型角色扮演游戏。有一个 Item class 是游戏中每个项目的父项。这些物品可能是药水(class)或绷带(class)。

项目 class 看起来像这样:

public class Item
{
int qty;
String name;
Hero hero1;

public void passHero(Hero hero1)
{
    this.hero1 = hero1;
}

public void use()
{
    if(qty == 0)
    {
        System.out.println("You have no more of this item to use.");
    }
    else
    {    
        qty--;
    }
}

public void addInv(int value)
{
    qty = qty + value;
}
}

一种传入英雄的方法class。 一种使用物品的方法。 一种添加到物品库存的方法。

此方法激活这些项目 classes:

public void initializeItemInventory()
{
    items[0] = new Potion();
    items[1] = new Bandage();
}

并且此方法理论上会打印所有项目及其数量:

public void useInventory()
{
    for(int i = 0; i<items.length; i++)
    {
        System.out.println("Enter: " + i + " for " + items[i].name);

    }

    int response = input.nextInt();
    items[response].use();

}

药水 class,例如,有一个实例变量,如:

String name = "Potion";

所以我的问题。为什么在 useInventory 方法中不能正确调用 Potion 中的名称变量。它 returns null 告诉我它返回父 class Item 名称,而不是单个子 class 变量的名称。

public class Item
{
  int qty;
  String name;
  ...

Item class 已经有 name,这就是您从 Item 类型的变量访问的内容:

items[0].name

所以如果你有

public class Potion extends Item
{
  String name = "Potion";
  ...

那么 Potion class 有 两个 name 字段:

Potion p = new Potion();
System.out.println(p.name);
System.out.println((Item) p).name);

正如你所说,你想要多态性,但它只适用于方法。因此你需要一个 getter:

public class Item
{
  String name;
  public String getName() { return name; }
  ...

Potion 子class 你可能有

public class Potion extends Item
{
  public Potion() { this.name = "Potion"; }
  ...

items[0].getName() 现在将按预期工作。

补充说明

我将添加这个来展示多态性的一些威力。

如果碰巧 name 属性 对于相同 class 的所有实例始终相同,您可以轻松地重构基于 getter 的解决方案通过完全消除存储 name 变量的需要:

public class Item
{
  public String getName() { return "Generic item"; }
  ...

public class Potion extends Item
{
  @Override public String getName() { return "Potion"; }
  ...

而不是像 "String name = "Potion 那样在子类中声明一个新变量";" 使用构造函数将值传递给超类,如下所示:

// the Item supuerclass has one constructor
public Item(name) {
  this.name = name;
} 

// the Potion subclass has one constructor
public Potion() {
  super("Potion");
}