为什么 Java 不理解我放在这个多维数组中的对象的类?



我正在从事一个小游戏工作,但是为了举例来说,我将使用假设班级学生的对象和假设类书籍的对象。

我有一个多维网格,我想被学生对象或书籍对象填充。也许叫做

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;

最新更新