简体   繁体   English

UpCasting 和 DownCasting Java 访问方法

[英]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. 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."这是那里的解释:“猫不能发出咕噜声,而被标记为其他东西如果你向上转换 object,它将失去从其当前 position 下面继承的所有属性。例如,如果你将猫投射到动物,它将丢失从 Mammal 和 Cat 继承的属性。请注意,该数据不会丢失,除非您将 object 向下转换到正确的级别,否则您无法使用它。为什么会这样?如果您有一组动物,那么您不能确定哪些可以喵(),哪些可以吠()。这就是为什么你不能让动物做只针对狗或猫的事情。

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此代码的 output 为:Schools OpenStudentsLearning

but from my understanding the output of the code should be Schools OpenTeachers teaching但据我了解,代码的 output 应该是 Schools OpenTeachers 教学

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. object 是您使用关键字创建的,并且在您的计算机的 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() ). object 是 class 的一个实例,例如,您有一个Teacher class,但可以创建任意数量Teacher对象,每个对象使用new关键字(例如new Teacher() )。 Each Teacher object contains it's own copy of non-static fields and non-static methods.每个Teacher object 都包含它自己的非静态字段和非静态方法的副本。 EACH ONE每一个

An handle, on the other side, is simply a pointer to an object.另一方面,句柄只是指向 object 的指针。 In Java you can define an handle simply using Classname handlename , (eg Teacher myTeacher ).在 Java 中,您可以简单地使用Classname handlename定义句柄(例如Teacher myTeacher )。 An handle carries no information, it just points to a specific object in memory or to null .句柄不携带任何信息,它仅指向 memory 或 null 中的特定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 " .您只是说“让句柄person2指向句柄 person3 指向的同一个object But from the previous line we know that person3 points to a TeacherAide instance , so now also person2 points to that very same instance!但是从上一行我们知道person3 指向一个TeacherAide实例,所以现在 person2 也指向同一个实例! So if you now call person2.schoolDay() you are calling the schoolDay() method of that TeacherAide object, which of course prints "Students learning"...因此,如果您现在调用person2.schoolDay() ,您就是在调用TeacherAide object 的schoolDay()方法,它当然会打印“学生学习”...

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.顺便说一句, (Teacher)演员表是无用的,因为person3TeacherAide的句柄,它是Teacher的子类,所以它本身可以被视为没有任何明确演员表的Teacher In other words: a TeacherAide is always a Teacher (in your model), while not every Teacher is a TeacherAide .换句话说: TeacherAide始终是Teacher (在您的模型中),而不是每个Teacher都是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() .在您的情况下,您正在扩展 class SchoolMember并覆盖其方法schoolDay() Thus you can still call the method schoolDay() without any compilation error.因此,您仍然可以调用方法schoolDay()而不会出现任何编译错误。 Meanwhile, being any method invoked dynamically according to the actual type of the object you're still calling the overridden method.同时,作为根据 object 的实际类型动态调用的任何方法,您仍在调用被覆盖的方法。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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