2017-01-23 1 views
-1

Ich werde damit beginnen zu sagen, tut mir leid, wenn der Titel zu zweideutig/nicht gut genug ist, hatte ich eine schwierige Zeit meine Frage in einem einzeiligen Titel zu artikulieren .Java - Ich versuche zu verstehen, abstrakte Klasse Vererbung und Unterklasse Objektvergleich

Ich arbeite an einem Projekt für meine Datenstrukturen Klasse und ich hatte eine harte Zeit, wickelte meinen Kopf um abstrakte Klasse Vererbung und wie es durch Unterklassen, Objektvergleich, Methode args, ect manipuliert werden kann. Ich habe die ganze Nacht durch StackOverflow Posts/Java-Tutorials gelesen (fast 4 Stunden), und obwohl ich eine Tonne gelernt habe, verstehe ich immer noch einige Dinge nicht. Ich habe nicht in 2+ Jahren in Java codiert und wurden mit meist C in letzter Zeit, so dass ich das Gefühl bin sehr rostig und überwältigt:/

Projektübersicht

Ich wurde gebeten, eine Datenbank von Art zu bauen Das sind Daten für meine Studenten und Professoren. Ich habe eine abstrakte Oberklasse, Person, die 2 Kindklassen Student und Instructor hat. Zu guter Letzt (die Klasse, an der ich gerade arbeite) ist eine Klasse namens UniversityPeople, die auf ein Array von Student[] Objekten sowie ein Array von Instructor[] Objekten verweist. Die UniversityPeople Klasse hat Methoden zu add(), delete(), search(), validieren Daten, ect. für die 2 Objekt-Arrays. Ich weiß, diese Implementierung scheint wirklich seltsam, aber ich muss leider den Anweisungen folgen. Ich habe versucht, die Methoden mit beiden Arrays nahtlos arbeiten zu lassen, wo ich teilweise verwirrt bin. Ich werde versuchen, meine Fragen so gut wie möglich zu organisieren:

1.) Dies ist eine Art allgemeiner Frage, aber eine, die ich fühle, ist wichtig, Vererbung zu verstehen. Ich habe viel darüber gelesen, aber ich bin immer noch ziemlich verwirrt. Wenn ich ein Objekt erzeuge, das den Typ der Oberklasse verwendet, aber ein Unterklassenobjekt ist, wie zum Beispiel: Person newStudent = new Student(), hat dieses Objekt Zugriff auf die Methoden in seiner eigenen Klasse oder ist es auf die Oberklassenmethoden beschränkt? Mein Verständnis war, wenn die Oberklasse abstract ist, erben die Kinder immer noch ihre Methoden, wenn auf diese Weise instanziiert.

2.) Es fällt mir schwer zu verstehen, wie man die beiden Objekt-Arrays in den Methoden unterscheidet. Zum Beispiel schreibe ich eine clear() Funktion, die das angegebene Objekt-Array (Student[] oder Instructor[]) auf null setzt, wenn sie aufgerufen wird. Ich versuchte zuerst, die Methode instanceOf zu verwenden, um zu testen, welcher Typ das Array war, aber der Compiler warnte mich, dass ich den Typ "Student to Person" oder so etwas nicht schreiben konnte. Hier ist der Konstruktor für die Klasse sowie die klare Funktion, mit der ich Probleme habe. Ich bin nicht sicher, ob ich verstehe, wie die Vererbung voll hier arbeitet, also wenn es ein besserer Weg, bitte erleuchte mich:

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]; 
      } 
     } 

separate Einsatz Methoden für Schüler/Lehrer, weil ich couldn‘ t Abbildung einen Ausweg zu 1 zu tun, wenn es überhaupt möglich ist:

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

schließlich ein Verfahren jemand in der Anordnung von ihrer ID zu finden und ein Verfahren zu klären, was Array angegeben ist. Ich habe den Arg-Typ Person[] Array in den meisten dieser Methoden gemacht, die ich hoffe, ist akzeptabel.

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."); 
     } 
    } 

Ich freue mich über jede Eingabe oder Beratung.Ich bin besonders verwirrt über die Implementierung der clear()-Methode, da ich noch nie zuvor einen solchen Objektvergleich durchführen musste. Ich bin mir nicht sicher, warum der instanceOf Operator Vergleich mir seltsame Ergebnisse gab. Ich würde wirklich gerne dieses Zeug verstehen, es ist wirklich großartig und scheint sehr nützlich zu sein. Wenn Sie möchten, dass ich mehr Code poste, kann ich das, aber ich hatte das Gefühl, dass das wahrscheinlich gut genug war, um meinen Standpunkt klar zu machen. Thanks again :)

+1

1. Worüber Sie sprechen, heißt ** Dynamic Method binding **. Was passiert, wenn Sie ein Objekt wie folgt deklarieren: 'Person ob = new Student();' Wenn Sie nun 'ob' verwenden, um auf eine Methode der' Person' Klasse zuzugreifen, wird die ursprüngliche Methode aufgerufen, wenn sie nicht in 'überschrieben wird Schüler 'sonst wird die überschriebene Methode aufgerufen. 2. "instanceof" ist ** NOT ** eine Methode, wenn Sie daran gedacht haben. Es ist ein Operator. Wenn ob ein 'Student'-Objekt ist, dann wird 'ob instanceof Student' wahr zurückgegeben. NUR IGNORE IHRE COMPILER WARNUNG. – progyammer

+0

@progy_rock Danke für die Klarstellung von 1.) da es mich ziemlich durcheinander gebracht hat. Ich habe vielleicht falsch verstanden, wenn ich 'instanceOf' eine Methode genannt habe, entschuldige ich mich. Ich wusste, dass es ein Vergleichsoperator ist, der einen booleschen Wert zurückgibt, ich war mir seiner Implementierung nicht sicher, und mein Compiler hat mich dazu gebracht, weitere Zweifel zu haben. Ist das der bevorzugte Weg, diese Art von Vergleich zu machen, was ich geschrieben habe? – FuegoJohnson

+0

Was ich in meinem vorherigen Kommentar gezeigt habe, war die Art, Objekte zu vergleichen. In Ihrem Code möchten Sie den Basistyp des Arrays vergleichen (eher überprüfen). Du hast dort gerade einen kleinen Fehler gemacht, der von @SME_Dev in der Antwort deutlich herausgestellt und korrigiert wurde. Was die Compiler-Warnungen betrifft, können Sie einfach solche Warnungen unterdrücken, die Ihr Programm nicht beeinflussen. Siehe hierzu: [Was ist SuppressWarnings ("unchecked") in Java?] (Http://stackoverflow.com/questions/1129795/what-is-suppresswarnings-unched-in-java) – progyammer

Antwort

1

Für die klare Methode:

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

, dass die gegebene Array auf ein neues leeres Array der richtigen Länge REINIT sollte und korrekte Anzahl an studentCount und instCount reasigne.

Grüße.

Nemesis.

+0

Vielen Dank. Das scheint viel sauberer und leichter zu verstehen. Ich nehme also an, dass das Argument 'Person [] Array' in dieser Situation akzeptabel ist? – FuegoJohnson

+0

wie ich es ja sehe ;-). – Nemesis

2

[...] hat dieses Objekt Zugriff auf die Methoden in seiner eigenen Klasse oder ist es nur auf die Superklassenmethoden beschränkt? Mein Verständnis war, wenn die Oberklasse abstrakt ist, erben die Kinder immer noch ihre Methoden , wenn auf diese Weise instanziiert.

Es spielt keine Rolle, ob die Oberklasse abstract ist. Eine untergeordnete Klasse inherits Methoden und Attribute der Elternklasse. Ob diese von der Kindklasse erreichbar sind, hängt von visibility modifiers ab.

Ich habe eine harte Zeit zu verstehen, wie zwischen den zwei Objektfeldern in den Verfahren zu unterscheiden. Zum Beispiel schreibe ich eine clear() - Funktion, die das angegebene Objekt-Array (Student [] oder Instructor []) beim Aufruf auf null setzt.

könnten Sie überlasten die clear() Methode wie:

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

oder (wenn ich den Zweck Ihres Beispiel richtig verstanden) zu vergleichen, das Referenz des Eingangsfeldes mit den Array-Referenzen in Ihrer Klassendefinition:

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

Aber wenn Sie wollen eigentlich die Typen Arrays vergleichen, können Sie tun:

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

oder

array instanceof Student[] 
+0

Vielen Dank, du hast über alles berichtet, worüber ich verwirrt war. Manchmal braucht es nur eine bestimmte Art, Dinge zu erklären. Ich habe nie daran gedacht, die klare Methode zu überladen, das ist eine gute Idee. Mein erster Versuch verwendete dein letztes Beispiel 'if (array instanceOf Student [])', aber mein Compiler hat mir Angst gemacht. Was wäre Ihrer Meinung nach in diesem Fall die beste Option? – FuegoJohnson

+0

@FuegoJohnson Bitte fügen Sie ein Codebeispiel hinzu, wo Sie Ihre Compiler-Warnung erhalten. 'if (array instanceOf Student [])' erzeugt keine Compiler-Warnung und wenn Sie einen Typ-Cast ('Student [] temp = (Student []) Array ') im Bereich dieses' if' machen, dann ist es das sicher auch. –

1

Für 1 #, ja, newStudent haben Zugriff auf seine eigenen Methoden und auch dann ist es übergeordnete Klasse, es sei denn es @Override n ist.

Für # 2 haben Sie eine harte Zeit, weil Ihre Klasse UniversityPeople zu viele Dinge tut. Dies wird zu einem Wartungsproblem und ist ein Code-Geruch. UniversityPeople verstößt gegen das Prinzip der einheitlichen Verantwortung. Deine Klasse sollte nur eines tun. Warum nicht eine UniversityInstructor und eine UniveristyStudent? Aber da Sie den Anweisungen folgen, ist hier eine Idee für Ihre klare Funktion. Bevor Sie null Ihr Array, erhalten Sie einen Inhalt im Array. Sagen Sie Person person = array[0];, dann können Sie eine if (person instanceof Student) und dann if (person instanceof Instructor) tun. Auf diese Weise werden Sie den Typ Ihres Arrays kennen und entsprechend vorgehen.

+0

Ich weiß, die Anweisungen sind ziemlich dumm IMO. Auch nachdem ich eine Zeit lang nicht mehr in Java programmiert hatte und mir klar wurde, dass 2 Klassen anstelle von 1 verwendet werden sollten. Die Tatsache, dass ich diese beiden Arrays in einer Klasse jonglieren muss, verwirrte mich. Ihr Vorschlag ist aber wirklich kreativ, danke. Es ist cool, verschiedene Blickwinkel zu sehen – FuegoJohnson

Verwandte Themen