我正在从事一个小游戏工作,但是为了举例来说,我将使用假设班级学生的对象和假设类书籍的对象。
我有一个多维网格,我想被学生对象或书籍对象填充。也许叫做
classroom[][]
有四个桌子:
[0][0], [0][1], [1][0], and [1][1].
我希望能够放置学生或书籍(从不同时),并且能够打印
classroom[0][1].someStudentAttribute
如果我知道这是学生或
classroom[0][1].someBookAttribute
如果我知道这是一本书。
清楚,当它是学生或书籍时,这将是显而易见的。我不需要一种万无一失的方式来区分,也就是说,在代码中绝对是该桌子的学生时,我只会在代码中使用" .somestudentattribute"。
我在这里的某个地方阅读了我可以创建一个多维数组,该数组通过在名称之前声明变量类型对象来接受多种类型的对象。
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]
不是在数组的插槽中表示对象的正确方法,什么是?
可能与将变量声明为对象[] []有关,但是重点是能够将对象从内部的不同类中放置。如果我只是称之为学生[] [],我将无法写书。
对象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
}
}
}
}
java所谓的静态键入语言,与javascript相比,它是动态键入的。这意味着,应在Java中的编译时知道每种表达式的类型。一旦将classroom
称为Object[][]
,表达式classroom[0][0]
具有Object
类型,并且此类型没有age
字段。您需要明确地将表达式施放给Student
:
if (classroom[0][0] instanceof Student)
System.out.println(((Student)classroom[0][0]).age);
或将课堂元素的类型更改为具有age
属性的东西。
如果要将不同类型的对象存储在同一数组中,并且仍然能够访问常见属性而无需显式类型的铸件,请将常见属性移至常见的超级类别,例如:
class ClassroomObject {
// Common stuff
public int age;
}
class Book extends ClassroomObject {
// Book-specific stuff
}
class Student extends ClassroomObject {
// Student-specific stuff
}
ClassroomObject [][] classroom;