Java上转型变量调用子类重写的方法时,方法中调用的属性是被隐藏的还是子类重写的变量?

Python09

Java上转型变量调用子类重写的方法时,方法中调用的属性是被隐藏的还是子类重写的变量?,第1张

在 Java 中,当使用父类的引用变量调用子类重写方法时,被调用的方法是子类重写的方法。这是因为在 Java 中,方法的调用是在运行时进行的,称为动态绑定,它允许在运行时根据对象的实际类型来调用方法。

举个例子,假设你有一个父类 Person 和一个子类 Student,其中父类有一个方法 getName,子类重写了该方法,如下所示:

class Person {

protected String name

public String getName() {

return name

}

}

class Student extends Person {

@Override

public String getName() {

return "Student: " + name

}

}

然后你可以这样使用父类的引用变量调用子类重写的方法:

Person person = new Student()

System.out.println(person.getName())

这将输出 "Student: [name]",因为调用的是子类重写的方法。

另外,在调用重写的方法时,方法中使用的属性也是子类重写的属性。例如,在上面的例子中,如果你在子类中重写了 name 属性,那么调用 getName 方法时将使用子类重写的 name 属性。

在 Java 中,如果一个子类重写了父类的方法,则可以使用父类的引用变量调用子类的重写方法。这种调用方法的机制被称为动态绑定,它允许在运行时根据对象的实际类型来调用方法。

你可以使用父类的引用变量来引用子类的对象,例如:

Person person = new Student()

在这个例子中,person 是一个 Person 类型的引用变量,但它实际上引用了一个 Student 类型的对象。当你使用这个引用变量调用方法时,将调用子类重写的方法,而不是父类中定义的方法。

例如,假设你有一个父类 Person 和一个子类 Student,其中父类有一个方法 getName,子类重写了该方法,如下所示:

class Person {

protected String name

public String getName() {

return name

}

}

class Student extends Person {

@Override

public String getName() {

return "Student: " + name

}

}

然后你可以这样使用父类的引用变量调用子类重写的方法:

Person person = new Student()

System.out.println(person.getName())

这将输出 "Student: [name]",因为调用的是子类重写的方法。

另外,在调用重写的方法时,方法中使用的属性也是子类重写的属性。例如,在上面的例子中

静态绑定:例如一个变量在声明的时候,就初始化最初值;

动态绑定:声明一个变量,在后续用set方法对其动态设置值;

静态编译:编译器在编译可执行文件的时候,将可执行文件需要调用的对应动态链接库(.so)中的部分提取出来,链接到可执行文件中去,使可执行文件在运行的时候不依赖于动态链接库。

动态编译:某些程式语言在执行时用来增进效能的方法。

前绑定:还未出现即绑定了某些事件

后绑定:出现后才会绑定的某些事件

一、多态的概念多态即“一个接口,多种实现”,在父类中声明的方法,可以在子类中进行覆盖(声明为finial的除外),这样,父类的引用在引用子类对象的时候可以做出不同的响应。所以,多态也可以说成是:相同的消息被发送到子类或父类对象上,将导致完全不同的行为。多态允许将子类的对象当作父类的对象使用,某父类型的引用指向其子类型的对象,调用的方法是该子类型的方法。这里引用和调用方法的代码编译前就已经决定了,而引用所指向的对象可以在运行期间动态绑定。二、多态存在的条件1、必须存在继承关系。2、子类必须覆盖父类中声明过的方法。三、java多态的实现机制java多态是由动态绑定技术来实现的,动态绑定即运行时绑定(以之对应的有静态绑定,即编译时绑定),在java语言中,除了声明为finial的方法外(声明为private的方法默认为finial)其余都是采用动态绑定来调用的,过程如下:当程序运行时,需要动态的调用方法时,则是虚拟机的工作,虚拟机将依照具体环境首先拟定出一张方法表,列举出可能的方法调用,继而在实现调用的时候,可以节省寻找函数方法所带来的时间开销,其将调用最合适及最合理的方法,在派生类中能调用相应的重名函数的则调用该新方法,不能则调用超类(父类)方法,同时应注意一点,若虚拟机放弃对本类的相应方法调用,那么虚拟机将搜索超类的方法表,依次类同,若都没有相应的处理来响应,则程序运行出错,一般来说在编译阶段,编译器将作出相应的控制。下面我们来看看动态绑定的内部实现机制。JAVA虚拟机调用一个类方法时,它会基于对象引用的类型(通常在编译时可知)来选择所调用的方法。相反,当虚拟机调用一个实例方法时,它会基于对象实际的类型(只能在运行时得知)来选择所调用的方法,这就是动态绑定。在编译阶段,编译器会为制造两种表,一种叫做方法表,一种叫做常量表。方法表以数组的形式记录了当前类及其所有超类的可见方法字节码在内存中的直接地址。此表有两个特点::(1) 子类方法表中继承了父类的方法。 (2) 相同的方法(相同的方法签名:方法名和参数列表,即被覆盖的方法)在所有类的方法表中的索引相同。而常量表(CONSTATN_Methodref_info ) 记录的是被调用方法信息的符号引用(包括方法所在的类名,方法名和返回类型)。详细调用过程如下:(1)JVM首先根据常量表中的符号所引找到调用方法的全额限定名(要用多态机制的话,一般是用基类来声明引用)。(2)在基类的方法表中查找到调用方法,如果找到,则将此方法在基类方法表中的索引记录到常量表中。这里要注意,这里必须要基类中有此方法的定义,如果没有,及时子类中存在,编译器也会报错。(3)根据(2)中记录到常量表中的索引找到子类中的响应方法。四、多态的作用1、 应用程序不必为每一个派生类编写功能调用,只需要对抽象基类进行处理即可。大大提高程序的可复用性。//继承2、 派生类的功能可以被基类的方法或引用变量所调用,这叫向后兼容,可以提高可扩充性和可维护性。 //多态的真正作用,以前需要用switch实现