多态性介绍 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");
}
我正在制作一款小型角色扮演游戏。有一个 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");
}