2017-01-23 2 views
-1

Начну с того, что я прошу прощения, если заголовок слишком неоднозначен/недостаточно хорош, мне было сложно сформулировать мой вопрос в одном заголовке строки ,Java - Попытка понять Абстрактное наследование классов и сравнение объектов подкласса

Я работаю над проектом для своего класса структур данных, и мне было трудно свернуть вокруг абстрактного наследования классов и как его можно манипулировать с помощью подклассов, сравнения объектов, аргументов метода и т. Д. Я читал через StackOverflow posts/java tutorials всю ночь (почти 4 часа), и пока я узнал тонну, я все еще не понимаю некоторые вещи. Я не закодирован в Java в 2-х годах и использовал в основном C в последнее время так что я чувствую себя очень ржавыми и перегружен:/

Обзора проекта

меня попросили создать базу данных сортов который представляет данные для моих студентов и преподавателей. У меня есть абстрактный суперкласс, Person, который имеет 2 дочерних класса Student и Instructor. Наконец (класс, над которым я сейчас работаю) является классом UniversityPeople, который ссылается на массив из Student[] объектов, а также массив объектов Instructor[]. Класс UniversityPeople имеет методы для add(), delete(), search(), валидационные данные, ect. для 2 объектных массивов. Я знаю, что эта реализация кажется действительно странной, но я должен следовать инструкциям, к сожалению. Я попытался сделать эти методы без проблем доступными для обоих массивов, частично из-за которых я запутался. Я постараюсь как можно лучше организовать свои вопросы:

1.) Это своего рода общий вопрос, но я считаю важным понимать наследование. Я сделал тонны чтения на этом, но я все еще довольно смущен. Если я создаю объект, который использует тип суперкласса, но является объектом подкласса, например: Person newStudent = new Student(), будет ли этот объект иметь доступ к методам в его собственном классе или же он ограничивается только методами суперкласса? Я понял, что если суперкласс равен abstract, дети все еще наследуют свои методы при создании экземпляра таким образом.

2.) Мне трудно понять, как различать два массива объектов в методах. Например, я пишу функцию clear(), которая устанавливает указанный массив объектов (Student[] или Instructor[]) в null при вызове. Сначала я попытался использовать метод instanceOf, чтобы проверить, какой тип был массив, но компилятор предупредил меня, что я не мог бы наложить тип Student на Person или что-то в этом роде. Вот конструктор для класса, а также ясная функция, с которой я столкнулся. Я не уверен, если я понять, как наследование полностью работает здесь, так что если есть лучший способ, пожалуйста, просветите меня:

Constructor:

//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 

Наконец, метод, чтобы найти кого-то в массиве из их идентификатора и способ, чтобы очистить все, что массив задан. Я сделал массив arg типа 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(), поскольку раньше мне никогда не приходилось сравнивать этот тип сравнения объектов. Я не уверен, почему сравнение операторов instanceOf давало мне странные результаты. Я действительно хотел бы понять этот материал, это действительно потрясающе и кажется очень полезным. Если вы хотите, чтобы я опубликовал больше кода, я могу, но я чувствовал, что это, вероятно, достаточно хорошо, чтобы понять мою точку зрения. Еще раз спасибо :)

+1

1. Что вы говорите, называется ** Связывание динамического метода **. Случается, что вы объявляете такой объект: 'Person ob = new Student();' Теперь, если вы используете 'ob' для доступа к методу класса Person, исходный метод вызывается, если он не переопределяется в' Student', иначе будет вызван метод overriden. 2. 'instanceof' является ** НЕ ** методом, если это то, о чем вы думали. Это оператор. Если ob является объектом «Student», тогда «ob instanceof Student» вернет true. ПРЕДУПРЕЖДЕНИЕ ПРЕДУПРЕЖДЕНИЕ. – progyammer

+0

@progy_rock Спасибо за пояснение 1.), поскольку он меня смутил. Возможно, я ошибаюсь, если я назвал метод instanceOf', извиняюсь. Я знал, что это оператор сравнения, который возвращает логическое значение, я просто не был уверен в его реализации, и мой компилятор заставил меня больше сомневаться в себе. Это предпочтительный способ сделать этот тип сравнения в сравнении с тем, что я написал? – FuegoJohnson

+0

То, что я показал в своем предыдущем комментарии, было способом сравнения объектов. В вашем коде вы хотите сравнить (скорее проверьте) базовый тип массива. Вы только сделали небольшую ошибку, которая была хорошо указана и исправлена ​​@SME_Dev в их ответе. Что касается предупреждений компилятора, вы можете просто подавить такие предупреждения, которые не повлияют на вашу программу. См. Это: [Что такое SuppressWarnings («unchecked») в Java?] (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; 

, которые должен REINIT данного массива в новый пустой массив нужной длины и reasigne правильного номера для studentCount и instCount.

С уважением.

Немезида.

+0

Большое спасибо. Это кажется намного более чистым и понятным. Поэтому я предполагаю, что в этом случае приемлема передача массива arg '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 [])' не будет вызывать предупреждение компилятора, и если вы выполняете тип cast ('Student [] temp = (Student []) array') в объеме этого' if', то это безопасно. –

1

Для # 1, да, newStudent будет иметь доступ к своим собственным методам, а также это суперкласс, если это не @Override п.

Для # 2 вам нелегко, потому что ваш класс UniversityPeople делает слишком много вещей. Это станет проблемой обслуживания и является запахом кода. UniversityPeople нарушает принцип единой ответственности. Ваш класс должен делать только одно. Почему бы не сделать UniversityInstructor и UniveristyStudent? Но поскольку вы следуете инструкциям, вот идея для вашей четкой функции. Прежде чем вы получите null свой массив, получите одно содержимое в массиве. Скажите Person person = array[0];, тогда вы можете сделать if (person instanceof Student), а затем if (person instanceof Instructor). Таким образом, вы будете знать тип вашего массива и действовать соответствующим образом.

+0

Я знаю, что инструкции довольно глупые ИМО. Даже после некорректного кодирования в java и выяснения, что для меня было очевидно, что вместо 1 следует использовать 2 класса. Тот факт, что я должен манипулировать этими двумя массивами в одном классе, - это то, что меня сбивает с толку. Ваше предложение действительно творческое, хотя, спасибо. Приятно видеть разные точки зрения – FuegoJohnson

Смежные вопросы