2016-11-02 4 views
2

я работаю на моем назначении, но я запуталась с абстрактными классами и конкретными классами, и я получаю ошибку из моей программы ...Java - Абстрактные классы и конкретные классы

Пусть имеется абстрактный класс Person и конкретный подкласс 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()); 
    } 
} 

Тогда я реализую основную функцию, чтобы проверить это, но я получил ошибку ...:

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

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

Говорят student = person г получив сообщение об ошибке "Error: Incompatible types: Person cannot be converted to Student". Что не так с этим и почему ...? Кто-нибудь может объяснить это ...?

+0

Подсказка: используйте 'GetClass() ', чтобы узнать, какое определение является вашим экземпляром. – roeygol

ответ

2

В течение времени выполнения переменная person может ссылаться на экземпляры Person, которые не являются экземплярами Student. Поэтому назначение student = person; не допускается.

Вы должны проверить тип вводного времени person и выполнить приведение в порядке для выполнения задания на работу (ну, проверка типа не является обязательным, но рекомендуется, чтобы избежать возможных ClassCastException):

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

Я не думаю, что вы должны принести в него экземпляр. Это создает плохой стиль для тех, кто борется с концепциями oop. –

+0

@AndyTurner Итак, вы бы предложили тип литья, не проверив тип сначала? – Eran

+1

Я бы предложил не делать 'student = person', потому что это бессмысленно (и не так). – Spotted

5

A Student является Person, но не каждый Person является Student.

Если у вас есть переменная типа Person, вы не можете присвоить ее значение переменной типа Student, потому что, в общем, это может быть небезопасно.

Если вы уверены, что это определенно Student (например, вы используете проверку instanceof, или вы рассудили о коде и, таким образом, «знаете»), вы можете указать переменную; но одна из центральных идей объектно-ориентированного программирования заключается в том, что вам не нужно заботиться о конкретном подклассе.

Есть два способа обойти это:

  • Назначьте new Student() к Student переменной, а затем присвоить это значение в Person переменной:

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

    Это прекрасно, потому что каждый Student является Person, поэтому переменной Person может быть присвоено значение переменной Student.

  • поступаться переменную student целиком, так как вам нужно только ссылку на Person, на котором называют doAction, а не конкретно 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)); 
} 
Смежные вопросы