java - 为什么 Java 不理解我放在这个多维数组中的对象的类?
问题描述
我正在开发一个小游戏,但为了举例,我将使用假设类 Student 中的对象和假设类 Books 中的对象。
我有一个多维网格,希望由 Student 对象或 Book 对象填充。也许它被称为
classroom[][]
并有四张桌子:
[0][0], [0][1], [1][0], and [1][1].
我希望能够放置一个学生或一本书(永远不要同时放置),并且能够打印
classroom[0][1].someStudentAttribute
如果我知道是学生或
classroom[0][1].someBookAttribute
如果我知道这是一本书。
需要明确的是,当它是学生或书籍时会很明显。我不需要一个万无一失的方法来区分,也就是说,我只会在代码中肯定是那个桌子上的学生的情况下使用“.someStudentAttribute”。
我在这里的某个地方读到,我可以通过在名称前声明变量类型 Object[][] 来创建一个接受多种类型对象的多维数组。
Student alice = new Student("alice", 10);
Student bob = new Student("bob", 11);
Student charlie = new Student("charlie", 10);
Book mathBook = new Book("mathematics", 578);
Object[][] classroom = new Object[2][2];
classroom[0][0] = alice;
classroom[0][1] = bob;
classroom[1][0] = charlie;
classroom[1][1] = mathBook;
这将返回正确的班级(班级学生)
System.out.println(classroom[0][0].getClass());
这也返回正确的类(类书)
System.out.println(classroom[1][1].getClass()):
但是一旦我尝试打印一个属性,我就会得到一个错误:
System.out.println(classroom[0][0].age);
错误是:
java: cannot find symbol
symbol: variable age
location: java.lang.Object
看起来Java似乎忘记了这一点
classroom[0][0]
一问属性就属于学生类!如果
classroom[0][0]
不是在数组的那个槽中表示对象的正确方法,是什么?
可能与将变量声明为 Object[][] 有关,但重点是能够将来自不同类的对象放入其中。如果我只是将其称为 Student[][],我将无法放入书籍。
解决方案
对象的类类型classroom
是Object
,当您调用classroom[0][0].age
时,Object
类不知道您在自己的自定义类中定义的属性。您将需要classroom[0][0]
像这样将您的自定义类转换为您的自定义类,
if (classroom[0][0] instanceof Student) { // Although it is a bad practice and against OOP
System.out.println(((Student)classroom[0][0]).age);
}
我会建议阅读一些关于 OOP 原则的东西,然后设计一个合适的解决方案。
编辑:我可能不清楚您必须尝试实现什么,但这里有一个示例实现,可能会给您一些想法。通常避免使用对象直接访问变量,而是使用 getter/setter。
查看此示例实现。
public class Classroom {
enum ClassRoomObjectType {
STUDENT,BOOK;
}
static abstract class ClassRoomObject {
private String name;
private int age;
private ClassRoomObjectType classRoomObjectType;
protected ClassRoomObject(ClassRoomObjectType classRoomObjectType, String name, int age) {
this.classRoomObjectType = classRoomObjectType;
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return String.format("Type: %s, Name: %s, Age: %s", classRoomObjectType, name, age);
}
}
static class Student extends ClassRoomObject {
public Student(String name, int age) {
super(ClassRoomObjectType.STUDENT, name, age);
}
}
static class Book extends ClassRoomObject {
public Book(String name, int age) {
super(ClassRoomObjectType.BOOK, name, age);
}
}
public static void main(String[] args) {
Student alice = new Student("alice", 10);
Student bob = new Student("bob", 11);
Student charlie = new Student("charlie", 10);
Book mathBook = new Book("mathematics", 578);
ClassRoomObject[][] classRoomObjects = new ClassRoomObject[2][2];
classRoomObjects[0][0] = alice;
classRoomObjects[0][1] = bob;
classRoomObjects[1][0] = charlie;
classRoomObjects[1][1] = mathBook;
for(int i=0;i<2;i++) {
for(int j=0;j<2;j++) {
System.out.println(classRoomObjects[i][j]); // This is how you can print the object content by overriding toString method
System.out.println(classRoomObjects[i][j].getAge()); // This is how you should access the value of an object attribute by using getters and not directly the variable
}
}
}
}
推荐阅读
- angular - Angular HTTPClient 动态获取 Id
- c++ - C++ 系统();函数未按预期工作/C++ 中的 Windows 控制台命令
- .net - 符号不能在 Docker 容器中加载
- wordpress - Wordpress - 如何访问不在媒体库中的上传内容?
- react-redux - 从 Redux 存储中检索状态
- css - 文本框不会环绕图像
- rabbitmq - RabbitMQ 在固定大小队列上的消息比预期的多
- python - 避免嵌套 .apply()
- python - 正则表达式删除python中多余的反斜杠
- symfony - Symfony 5 - 在 VPS 上安装 API