2017-01-23 58 views
-1

如果标题太模糊/不够好,我会开始说我很抱歉,我很难用一行标题来表达我的问题。Java - 尝试理解抽象类继承和子类对象比较

我正在为我的数据结构类进行项目工作,我一直在围绕抽象类的继承以及如何通过子类,对象比较,方法参数等操作它。我一整晚都在阅读StackOverflow文章/ java教程(现在差不多4个小时),虽然我学了很多东西,但我还是不理解一些东西。我没有在Java编码在2年以上,并已使用大多数是C近来一直非常我感觉很生疏和不知所措:/

项目概况

我被要求建立各种各样的数据库代表我的大学学生和教授的数据。我有一个抽象超类,Person,它有两个子类StudentInstructor。最后(我目前正在处理的课程)是一个名为UniversityPeople的课程,其中引用了一组Student[]对象以及一组Instructor[]对象。 UniversityPeople类的方法有add(),delete(),search(),验证数据等。为2个对象数组。我知道这个实现看起来很奇怪,但不幸的是我必须按照说明操作。我试图使这两种方法无缝地工作,这部分是我感到困惑的地方。我会尽力组织我的问题尽我所能:

1.)这是一个普遍的问题,但我认为对理解继承很重要。我已经完成了大量的阅读,但我仍然很困惑。如果我创建一个使用超类的类型但是子类对象的对象,如:Person newStudent = new Student(),该对象是否可以访问它自己的类中的方法,还是仅限于超类方法?我的理解是,如果超类是abstract,孩子仍然以这种方式实例化时继承他们的方法。

2.)我很难理解如何区分方法中的两个对象数组。例如,我正在编写一个clear()函数,该函数在调用时将指定的对象数组(Student[]Instructor[])设置为null。我第一次尝试使用instanceOf方法来测试数组是什么类型,但编译器警告我,我不能将类型学生投给Person或类似的东西。这里是该类的构造函数以及我遇到的明确函数。我不知道如果我理解如何充分继承在这里工作,所以如果有更好的方法请赐教:

构造:

//Global declarations 
    //Declares arrays of student and instructor classes 
    private Student[] studentArray; 
    private Instructor[] instArray; 
    private int studentCount; 
    private int instCount; 

     /* 
     checks user input. If user enters 1, create student array. 
     if user enters 2, create Instructor array 
     */ 
     public UniversityPeople(int type, int size) 
     { 
      if (type == 1) 
      { 
       studentArray = new Student[size]; 
      } 
      else if (type == 2) 
      { 
       instArray = new Instructor[size]; 
      } 
     } 

单独的插入方法,让学生/教师,因为我不能”牛逼想出一个办法做到1, 如果它甚至有可能:

/* 
    checks if array is full or duplcate id exists. 
    If not, new Student object is created and 
    inserted into the student array 
    */ 
    public void insertStudent(String lastName, String firstName, int id, 
           int age, String yearStanding, double GPA) 
    { 
     boolean checkFull = isFull(); 
     boolean checkId = containsID(studentArray, id); 

     if (checkFull) 
     { 
      System.out.println("Array is full. Please delete a data member."); 
     } 
     else if (checkId) 
     { 
      System.out.println("Duplicate ID. Please check data and re-enter."); 
     } 
     if (!checkFull && !checkId) 
     { 
      Student newStudent = new Student(lastName, firstName, id, age, yearStanding, GPA); 
      newStudent = studentArray[studentCount]; 
      studentCount++; 
     } 
     else 
      System.err.println("There was an error while attempting to \n" + 
           "process your request. Please check your \n" + 
           "data entry and try again."); 

    }//end insertStudent 

    /* 
    checks if array is full or duplicate id exists. 
    If not, new Instructor object is created and 
    inserted into instructor array 
    */ 
    public void insertInstructor (String lastName, String firstName, int id, 
            int age, int officeNum, String subjectTaught) 
    { 
     boolean checkFull = isFull(); 
     boolean checkId = containsID(instArray, id); 

     if (checkFull) 
     { 
      System.out.println("Array is full. Please delete a data member."); 
     } 
     else if (checkId) 
     { 
      System.out.println("Duplicate ID. Please check data and re-enter."); 
     } 
     if (!checkFull && !checkId) 
     { 
      Instructor newInstructor = 
          new Instructor(lastName, firstName, id, age, officeNum, subjectTaught); 
      newInstructor = instArray[instCount]; 
      instCount++; 
     } 
     else 
      System.err.println("There was an error while attempting to \n" + 
           "process your request. Please check your \n" + 
           "data entry and try again."); 

    }//end insertInstructor 

最后,方法找人从他们的ID和清除指定任何阵列的方法在数组中。我已经在大多数这些方法中使用了参数类型Person[],我希望这些方法都可以接受。

public int findPerson(Person[] array, int id) 
    { 
     for (int i = 0; i < array.length; i++) 
     { 
      if (array[i].getId() == id) 
      { 
       return i; 
      } 
     } 

     return -1; 
    } 

    //Sets specified array to null. I need to reset the count of objects in 
    //the specified array to 0, but i'm really confused about how that works. Below is the best 
    //understanding I could come up with 
    public void clear(Person[] array) 
    { 
     for (int i = 0; i < array.length; i++) 
     { 
      array[i] = null; 
     } 

     if (array.getClass().equals(Student.class)) 
     { 
      studentCount = 0; 
     } 
     else if (array.getClass().equals(Instructor.class)) 
     { 
      instCount = 0; 
     } 
     else 
     { 
      System.out.println("There was an issue validating the object type."); 
     } 
    } 

我很感激任何意见和建议。我对clear()方法的实现特别困惑,因为我以前从来不需要做这种类型的对象比较。我不确定为什么运算符比较会给我奇怪的结果。我真的很想理解这个东西,这真的很棒,看起来很有用。如果你想让我发布更多的代码,我可以,但是我觉得这可能足以说明我的观点。再次感谢:)

+1

1.你在说什么叫**动态方法绑定**。假设你声明一个像这样的对象:'Person ob = new Student();'现在,如果你使用'ob'来访问'Person'类的方法,那么原始方法将被调用,如果它没有在'学生“,否则,将调用重写方法。 2.'instanceof'是** NOT **的一种方法,如果这就是你的想法。这是一个运营商。如果ob是一个Student对象,那么'ob instanceof Student'将返回true。只要忽略编译器警告。 – progyammer

+0

@progy_rock谢谢你澄清1.),因为它让我很困惑。如果我打电话给'instanceOf'的方法,我可能会有错误,我很抱歉。我知道这是一个返回布尔值的比较运算符,我只是不确定它是否实现,我的编译器让我进一步怀疑自己。这是比较我写的那种比较的首选方式吗? – FuegoJohnson

+0

我在之前的评论中展示的是比较对象的方式。在你的代码中,你想比较(而不是检查)数组的基类型。你在那里犯了一个小错误,这个错误已经被@SME_Dev在他们的答案中很好地指出和纠正了。就编译器警告而言,您可以简单地禁止这些警告,这些警告不会影响您的程序。看看这个:[什么是Java中的SuppressWarnings(“unchecked”)?](http://stackoverflow.com/questions/1129795/what-is-suppresswarnings-unchecked-in-java) – progyammer

回答

1

对于明确方法:

array = new Person[array.length] // re-init arrayt ot it's inital size. 
studentCount = studentArrayl.length; 
instCount = instArray.length; 

应该给定数组重新初始化到正确长度的新的空数组和reasigne正确数量studentCount和instCount。

问候。

复仇女神。

+0

非常感谢。这似乎更清晰,更易于理解。所以我认为在那种情况下可以接受参数ar' Person []数组? – FuegoJohnson

+0

,因为我看到它是;-)。 – Nemesis

2

该对象是否可以访问它自己的类中的方法,或者是否仅限于超类方法的 ?我的理解是,如果 超类是抽象的,那么当以这种方式实例化时,孩子们仍然继承他们的方法 。

无关紧要,无论超类是否为abstract。子类inherits父类的方法和属性。这些是否可以通过儿童课程取决于visibility modifiers

我很难理解如何区分方法中的两个对象数组,如 。例如,我正在写一个clear()函数,它在调用时将指定的对象数组(Student []或Instructor [])设置为null。

你可以重载clear()方法,如:

public void clear(Student[] array) {...} 
public void clear(Instructor[] array) {...} 

或者(如果我正确理解你的例子的目的)在类定义与数组引用比较输入数组的参考:

public void clear(Person[] array) { 
    if(array == this.studentArray) { 
     // clear students 
    } else if(array == this.instArray) { 
     // clear instructors 
    } 
} 

但是,如果你想实际比较阵列的类型,你可以这样做:

array.getClass().equals(Student[].class) 

array instanceof Student[] 
+0

非常感谢,你几乎涵盖了我所困惑的一切。有时它只是用一定的方式来解释事物。我从来没有想过超载清晰的方法,这是一个好主意。我的第一次尝试使用了你的最后一个例子,'if(array instanceOf Student [])'但我的编译器吓跑了我。在你看来,什么在这种情况下是最好的选择? – FuegoJohnson

+0

@FuegoJohnson请添加一个代码示例,您可以在其中获得编译器警告。 'if(array instanceOf Student [])'不会产生编译器警告,如果你在该if的范围内进行类型转换('Student [] temp =(Student [])array'),那么它就是安全。 –

1

#1,是的,newStudent将有机会获得它自己的方法也很超除非它是@Overrideñ。

对于#2,你很难过,因为你的UniversityPeople类正在做太多的事情。这将成为维护问题并且是代码味道。 UniversityPeople违反单一责任原则。你的班级只应做一件事。为什么不做UniversityInstructorUniveristyStudent?但是,由于您遵循了说明,因此以下是您的清晰功能的主意。在你的数组之前,你可以在数组中获得一个内容。说Person person = array[0];,那么你可以做一个if (person instanceof Student),然后if (person instanceof Instructor)。这样你就可以知道你的数组的类型并相应地进行操作。

+0

我知道说明是非常愚蠢的国际海事组织。即使没有在java中编写一段时间,并且看到我明显应该使用2个类而不是1个。我必须在一个类中处理这两个数组的事实是令我困惑的。你的建议非常有创意,谢谢。看到不同的观点很酷 – FuegoJohnson