2016-11-02 3 views
2

ich auf meiner Aufgabe bin arbeiten, aber ich habe mit den abstrakten Klassen und konkreten Klassen verwirrt, und ich bekomme Fehler von meinem Programm ...Java - Abstrakte Klassen und konkrete Klassen

Angenommen, es ist eine abstrakte Klasse Person und eine konkrete Unterklasse Student:

abstract class Person{ 
    private String name; 
    public Person(String s){ 
      name = s; 
    } 
    public String getName() { 
      return name; 
    } 
    public abstract void doAction(Person other); 
} 

class Student extends Person{ 
    public Student(String name){ 
      super(name); 
    } 
    public void doAction(Person other){ 
      System.out.println("This person's name is " + getName()); 
    } 
} 

Dann implementiere ich eine Hauptfunktion zu testen, aber ich habe einen Fehler ...:

public class TestMain { 
    public static void main(String[] args) { 
     Person person; 
     Student student; 

     person = new Student("Sam"); 
     student = person; 
     student.doAction(person); 
    } 
} 

es wird gesagt, student = person r Empfangen eines Fehlers, der besagt, dass "Error: Incompatible types: Person cannot be converted to Student". Was stimmt daran eigentlich und warum ...? Kann das jemand erklären ...?

+0

Tipp: Verwenden Sie 'getClass() 'um zu sehen, welche Definition ist Ihre Instanz – roeygol

Antwort

2

Während der Laufzeit kann sich die Variable auf Instanzen von Person beziehen, die keine Instanzen von Student sind. Daher ist die Zuweisung student = person; nicht erlaubt.

Sie haben den Laufzeittyp von person zu überprüfen und eine Besetzung, um die Zuordnung durchführen zu arbeiten (na ja, die Typprüfung nicht zwingend vorgeschrieben ist, werden jedoch empfohlen, um mögliche ClassCastException zu vermeiden):

if (person instanceof Student) 
    student = (Student) person; 
+3

Ich glaube nicht, dass Sie instanceof hineinbringen sollten. Das bringt schlechten Oo-Stil zu jemandem, der mit oop-Konzepten kämpft. –

+0

@AndyTurner Also würden Sie Typ Casting empfehlen, ohne zuerst den Typ zu prüfen? – Eran

+1

Ich würde vorschlagen, nicht 'Student = Person;' zu tun, weil es bedeutungslos (und falsch) ist. – Spotted

5

Eine Student ist eine Person, aber nicht jede Person ist eine Student. Wenn Sie eine Variable vom Typ Person haben, können Sie ihren Wert keiner Variablen vom Typ Student zuweisen, da dies im Allgemeinen nicht sicher ist.

Wenn Sie sicher sind, dass es definitiv eine Student ist (z. B. verwenden Sie eine instanceof Überprüfung, oder Sie haben über den Code und damit "wissen"), können Sie die Variable umwandeln; aber eine der zentralen Ideen für objektorientierte Programmierung ist, dass Sie sich nicht um die spezifische Unterklasse kümmern sollten.

Es gibt zwei Möglichkeiten, diese Runde:

  • die new Student() zur ersten Student Variablen zuweisen und weisen Sie dann diesen Wert auf die Person Variable:

    student = new Student("Sam"); 
    person = student; 
    student.doAction(person); 
    

    Das ist in Ordnung, weil jeder Student ist ein Person, so kann eine Person Variable den Wert einer Student Variable zugewiesen werden.

  • Forgo die student Variable ganz, da Sie nur einen Verweis auf eine Person, auf dem brauchen doAction zu nennen, nicht speziell ein Student:

    person = new Student("Sam"); 
    person.doAction(person); 
    
0
package taskassignment; 

public abstract class Person 
{ 
    public String name; 

    public Person(String n) 
    { 
     name = n; 
    } 

    public String getName() 
    { 
     return name; 
    } 

    public abstract String doAction(Person other); 
} 

public class Student extends Person 
{ 
    public Student(String n) 
    { 
     super(n); 
    } 

    @Override 
    public String doAction(Person other) 
    { 
     return "The Person Name is : "+ getName(); 
    } 
} 

public static void main(String args[]) 
{ 
    Person person = new Student("Sam"); 
    Student student = (Student) person; 
    System.out.println(student.doAction(person)); 
} 
Verwandte Themen