繁体   English   中英

UpCasting 和 DownCasting Java 访问方法

[英]UpCasting and DownCasting Java accessing methods

我无法理解向上转换和方法的访问。 我已经阅读了关于我遇到的类似理解问题的多个其他问题,但我仍然无法理解。 我希望对我的问题的更个性化的答案可以帮助我更好地理解它。

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.

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

这个解释对我来说很有意义,但是当我在这段代码中测试它时:

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();
    }
}

此代码的 output 为:Schools OpenStudentsLearning

但据我了解,代码的 output 应该是 Schools OpenTeachers 教学

有人可以帮助我理解这个问题。

您正在谈论的是称为多态性的面向对象概念的一部分。 您报告的解释是正确的,但我知道它可能有点复杂。 我认为有一种更简单的说法(为了简单起见,我将尽可能少地使用技术术语)。

让我们介绍句柄和对象

object 是您使用关键字创建的,并且在您的计算机的 memory 中有一个地址。 object 是 class 的一个实例,例如,您有一个Teacher class,但可以创建任意数量Teacher对象,每个对象使用new关键字(例如new Teacher() )。 每个Teacher object 都包含它自己的非静态字段和非静态方法的副本。 每一个

另一方面,句柄只是指向 object 的指针。 在 Java 中,您可以简单地使用Classname handlename定义句柄(例如Teacher myTeacher )。 句柄不携带任何信息,它仅指向 memory 或 null 中的特定null 因此,当您在代码中执行以下语句时:

person2 = (Teacher) person3;

您只是说“让句柄person2指向句柄 person3 指向的同一个object 但是从上一行我们知道person3 指向一个TeacherAide实例,所以现在 person2 也指向同一个实例! 因此,如果您现在调用person2.schoolDay() ,您就是在调用TeacherAide object 的schoolDay()方法,它当然会打印“学生学习”...

顺便说一句, (Teacher)演员表是无用的,因为person3TeacherAide的句柄,它是Teacher的子类,所以它本身可以被视为没有任何明确演员表的Teacher 换句话说: TeacherAide始终是Teacher (在您的模型中),而不是每个Teacher都是TeacherAide 因此,只有在向下转换时才需要显式转换。

你引用的解释是非常正确的。 但是,并不直接适用于您的示例。 在您的情况下,您正在扩展 class SchoolMember并覆盖其方法schoolDay() 因此,您仍然可以调用方法schoolDay()而不会出现任何编译错误。 同时,作为根据 object 的实际类型动态调用的任何方法,您仍在调用被覆盖的方法。

相反,以下示例会由于向上转换而产生错误:

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