Reputation:
I'm working on my assignment but I got confused with the abstract classes and concrete classes, and I get error from my program...
Suppose there is an abstract class Person and a concrete subclass 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());
}
}
Then I implement a main function to test it but I got an error...:
public class TestMain {
public static void main(String[] args) {
Person person;
Student student;
person = new Student("Sam");
student = person;
student.doAction(person);
}
}
It is said student = person
receiving an error saying that "Error: Incompatible types: Person cannot be converted to Student"
. What's wrong with that actually and why...? Does anyone can explain this...?
Upvotes: 3
Views: 1621
Reputation: 1
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));
}
Upvotes: 0
Reputation: 140544
A Student
is a Person
, but not every Person
is a Student
.
If you have a variable of type Person
, you can't assign its value to a variable of type Student
because, in general, that might not be safe.
If you are certain that it's definitely a Student
(e.g. you use an instanceof
check, or you have reasoned about the code and thus "know"), you can cast the variable; but one of the central ideas on object-oriented programming is that you shouldn't need to care about the specific subclass.
There are two ways round this:
Assign the new Student()
to the Student
variable first, and then assign that value to the Person
variable:
student = new Student("Sam");
person = student;
student.doAction(person);
This is fine because every Student
is a Person
, so a Person
variable can be assigned the value of a Student
variable.
Forgo the student
variable entirely, since you only need a reference to a Person
on which to call doAction
, not specifically a Student
:
person = new Student("Sam");
person.doAction(person);
Upvotes: 6
Reputation: 394146
During run-time the person
variable can refer to instances of Person
which are not instances of Student
. Therefore the assignment student = person;
is not allowed.
You have to check the run-time type of person
and perform a cast in order for the assignment to work (well, the type check is not mandatory, but recommended, in order to avoid potential ClassCastException
):
if (person instanceof Student)
student = (Student) person;
Upvotes: 2