简体   繁体   中英

UpCasting and DownCasting Java accessing methods

I am unable to understand upcasting and the accessing of methods. I have read through multiple other questions on a similar understanding problem I am having but I still can not understand. I am hoping that a more personalized answer to my question could help me understand it better.

My problem with upcasting is that I've learned from my computer science class that when an child object is upcasted to an parent class it just is labeled something else, because it is labeled something else it is unable to call methods from the child class.

This is there explanation: "Cats can't purr, while being labeled something else If you upcast an object it will lose all its properties which were inherited from below its current position. For example, if you cast a Cat to an Animal, it will lose properties inherited from Mammal and Cat. Note, that data will not be lost you just can't use it until you downcast the object to the right level. Why is it like that? If you have a group of Animals, then you can't be sure which ones can meow() and which ones can bark(). That is why you can't make Animal do things that are only specific for Dogs or Cats."

This explanation makes sense to me but when I tested it in this code:

public class SchoolMember 
{
    public void schoolDay() 
    {
    System.out.print(“School open”); 
    } 
}

public class Teacher extends SchoolMember  
{  
    public void schoolDay()  
    {  
    System.out.print(“Teachers teaching”);  
    }  
}  

public class TeacherAide extends Teacher 
{ 
    public void schoolDay() 
    { 
    System.out.print(“Students learning”); 
    } 
}

public class Main(){
    public static void main(String[] args){
        SchoolMember person1 = new SchoolMember(); 
        Teacher person2 = new Teacher();
        TeacherAide person3 = new TeacherAide();
        person2 = (Teacher) person3;
        person1.schoolDay();
        person2.schoolDay();
    }
}

The output of this code is: Schools OpenStudentsLearning

but from my understanding the output of the code should be Schools OpenTeachers teaching

Could somebody please help me with understanding this question.

What you are talking about is part of a OO concept called Polymorphism. The explanation you reported is correct, but I understand that it can be a bit complex. I think there's a simpler way to say it (and to keep it simple I will use as little technical terms as possible).

Let's introduce handles and objects .

An object is something you create with the new keyword, and has an address in your computer's memory. An object is an instance of a class, so for example you have a single Teacher class but can create any number of Teacher objects, each one using the new keyword (eg new Teacher() ). Each Teacher object contains it's own copy of non-static fields and non-static methods. EACH ONE

An handle, on the other side, is simply a pointer to an object. In Java you can define an handle simply using Classname handlename , (eg Teacher myTeacher ). An handle carries no information, it just points to a specific object in memory or to null . So when you in your code perform the following statement:

person2 = (Teacher) person3;

you are just saying "let the handle person2 point to the same object pointed by the handle person3 " . But from the previous line we know that person3 points to a TeacherAide instance , so now also person2 points to that very same instance! So if you now call person2.schoolDay() you are calling the schoolDay() method of that TeacherAide object, which of course prints "Students learning"...

BTW, the (Teacher) cast is useless, since person3 is an handle to TeacherAide , which is a subclass of Teacher , so itself can be viewed as a Teacher without any explicit cast. In other words: a TeacherAide is always a Teacher (in your model), while not every Teacher is a TeacherAide . Hence the need for explicit cast only when downcasting .

The explanation you quoted is quite correct. However, does not directly apply to your example. In your case you are extending the class SchoolMember and overriding its method schoolDay() . Thus you can still call the method schoolDay() without any compilation error. Meanwhile, being any method invoked dynamically according to the actual type of the object you're still calling the overridden method.

The following example, instead, would generate an error due to upcasting:

public class SchoolMember 
{
    public void schoolDay() {
        System.out.print(“School open”); 
    } 
}

public class Teacher extends SchoolMember  
{  
    public void newMethod(){  
        System.out.print(“Teachers teaching”);  
    }  
}

public class Main(){
    public static void main(String[] args){
        SchoolMember person1; 
        Teacher person2 = new Teacher();
        person1 = (SchoolMember) person2;
        person1.newMethod(); \\ Error even if you are referring to a Teacher object
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM