java - 无法引用对象属性
问题描述
关于 Stack Overflow 的第一个问题!我觉得这必须是 Java 初学者的常见问题。但我已经尝试了几个小时,但一直无法找到解决方案。我认为可以通过这种方式访问对象属性。
起初我以为那weapon[0]
实际上是一个对象数组,所以当我创建对象数组时Inventory[] inventory
,我在构造函数中使用了一个对象数组。我立即解决了这个问题,但这个问题仍然存在。
更烦人的是,在调试模式下,我可以从字面上看到 weapon[0]
它Inventory[] inventory
的属性。
看看 Eclipse 嘲笑我。
我目前的理论是在对象数组中放置 object weapon[0]
, class 的实例可能是问题,并且由于该放置,对象的属性无法以某种方式访问。任何帮助将不胜感激,谢谢!这是我第一次搞乱数组,所以我绝对是个新手。关于我的格式等的任何提示也将非常有帮助!Weapons
Inventory[] inventory
package arraytest;
import java.util.Scanner;
import java.util.InputMismatchException;
import java.lang.NumberFormatException;
public class ArrayTest {
static Scanner kb = new Scanner(System.in);
static int i = 0;
static int choice = 0;
public static void main(String[] args) {
Weapons[] weapon = new Weapons[3];
weapon[0] = new Weapons(0,"Wooden Sword",1,2);
weapon[1] = new Weapons(1,"Bronze Sword",2.5,7.5);
weapon[2] = new Weapons(2,"Iron Sword",5,10);
Armor[] armor = new Armor[3];
armor[0] = new Armor(3,"Wooden Armor",2,5);
armor[1] = new Armor(4,"Bronze Armor",3,10);
armor[2] = new Armor(5,"Iron Armor",5,15);
Enemy[] enemy = new Enemy[3];
enemy[0] = new Enemy(0,"Skeleton",3,0,10);
enemy[1] = new Enemy(1,"Goblin",2,1,5);
enemy[2] = new Enemy(2,"Zombie",4,1,8);
Inventory[] inventory = new Inventory[256];
String chooseweapon = String.format(
"Choose your weapon:\n"
+ "1. %s\n"
+ "2. %s\n"
+ "3. %s\n"
,
weapon[0].name,
weapon[1].name,
weapon[2].name
);
System.out.print(chooseweapon);
while (i==0) {
i++; //1
try {
choice = Integer.parseInt(kb.nextLine());
} catch (NumberFormatException e) {
System.out.println("Error. Try again.");
i--; //0
continue;
}
if (choice < 1 || choice > 3) {
System.out.println("Error. Try again.");
i--; //0
}
}
if (choice == 1) {
inventory[0] = new Inventory(weapon[0]);
}
System.out.println(inventory[0].item); //this is the problem here. i can't put .item.name, error is "name cannot be resolved or is not a field"
}
}
class Inventory {
public Object item;
Inventory(Object item) {
this.item = item;
}
}
class Armor {
public int id;
public String name;
public double defnum;
public double val;
Armor(int id, String name, double defnum, double val) {
this.id = id;
this.name = name;
this.defnum = defnum;
this.val = val;
}
}
class Weapons {
public int id;
public String name;
public double attdmg;
public double val;
Weapons(int id, String name, double attdmg, double val) {
this.id = id;
this.name = name;
this.attdmg = attdmg;
this.val = val;
}
}
class Enemy {
public int id;
public String name;
public double attdmg;
public double defnum;
public double health;
Enemy(int id, String name, double attdmg, double defnum, double health) {
this.id = id;
this.name = name;
this.attdmg = attdmg;
this.defnum = defnum;
this.health = health;
}
}
解决方案
欢迎来到 StackOverflow!这是一个措辞得当的问题!
这与运行时类型与编译时类型之间的差异有关。您声明item
为 type Object
。
Java 允许多态性,当您将item
in声明Inventory
为 typeObject
时,它允许您分配任何item
“is-a”的对象Object
(这意味着您可以将 a String
、 an Integer
、任何对象分配给item
,因为它们都继承自Object
该类)。
但是,当您item
稍后在程序中访问时,Java 无法在编译时保证任何引用item
都具有name
属性!Integer
,例如,是一个 ,Object
但没有name
属性!Java 编译器只是说,“我只知道这item
是一个s Object
,我不会让你访问一个不是所有Object
s 都有的属性!”。
但是,当您运行程序时,运行时类型item
为Weapon
,因此 Eclipse 能够向您显示其属性。但是 Java 旨在在编译时捕获尽可能多的错误,因此name
如果它不能在编译时保证它有名称,它将不允许您访问该属性。
这可能看起来很烦人或不必要的限制(你知道你要放入的所有东西Inventory
都会有一个名字!),所以这就是超类和接口的重点!这些特性允许您灵活地创建共享相似属性或方法的不同类型的对象,并且仍然允许 Java 提前捕获所有这些潜在问题。
要解决此问题,您可以创建一个InventoryItem
既可扩展Armor
又Weapon
具有name
属性的超类。然后,您可以声明item
为 type InventoryItem
。这样,Java 就会知道,即使运行时类型可能是 aWeapon
或Armor
,它也保证有一个名称。
我们可以引入一个新的类,例如InventoryItem
:
class Inventory {
public InventoryItem item;
public int id;
Inventory(InventoryItem item, int id) {
this.item = item;
this.id = id;
}
}
然后类Inventory
可以带一个InventoryItem
(我建议库存可能包含项目数组)
class Inventory {
public InventoryItem item;
Inventory(InventoryItem item) {
this.item = item;
}
然后你的类,例如Armor
,可以扩展InventoryItem
,例如:
class Armor extends InventoryItem {
public double defnum;
public double val;
Armor(int id, String name, double defnum, double val) {
super(name, id);
this.defnum = defnum;
this.val = val;
}
}
然后这将起作用!
System.out.println(inventory[0].item.name); //Java now knows that inventory[0] is type Inventory, its "item" property is type InventoryItem, and that is *guaranteed* to have a name and id!
推荐阅读
- html - 如何创建html不规则表格?
- javascript - 过滤计算属性不返回所有元素
- extjs - 同时加载所有商店 (2)
- java - Java 正确编码图像 URL
- jenkins - 来自 xx.xxx.xx.xxx:40748 的 Traefik TLS 握手错误:来自 Jira Webhook 的 EOF
- python - 在Python中将列表转换为字符串
- spring-boot - 使用单独的重试逻辑在单个事务中执行 2 个方法
- uwp - 如何在 UWP toast 通知中使用 CharacterEllipsis 效果进行 TextTrimming?
- session - TYPO3 10.4 会话变量
- .net-core - 控制台应用程序无法在任务计划程序中使用 Selenium Scraping 运行