覆盖 toString() 是否被视为多态性?
Is overriding toString() considered polymorphism?
我今天 Java 考试,考官问我是否可以提供任何在我的 Spring Boot 项目中使用多态性的示例。
一开始我什么也想不起来,他指出我在我的模型中覆盖了 toString(),这是 dynamic/runtime 多态性。
但是,我不确定我是否理解他的观点,因为据我所知,当我们有一个 parent class 引用变量指向 subclass对象(关注动态多态).
然后在运行时获取父 class 变量指向的实际对象并调用其方法,如解释得很好 here。
但是,我没有在我的项目中使用向上转换(即使用对象 class 变量初始化我的 POJO classes)。
因此,我的问题是 - 重写 toString() 被认为是多态性,尽管父 class(对象)从未用作参考变量?
我在 Whosebug 上找到的所有运行时多态性示例,包括那些 here and this 带有 toString 的示例,说明了我们有一个父 class 变量指向子 class 对象,例如:
Object object = new User("petar");
String name = object.toString(); // assign to variable for clarity`s sake
System.out.println(name);
// prints petar
我的用户 class 在哪里:
public class User {
String name;
public User(String name) {
this.name = name;
}
public String toString() {
return name;
}
}
但是,在我的项目中,我只是简单地创建用户和其他 POJO classes,它们具有自己的引用变量,例如:
User user = new User("petar");
String name = user.toString();
System.out.println(name);
// prints petar, as toString is overriden
上面是否考虑了多态性,虽然没有涉及向上转型/父引用变量?
我的 class 伙伴认为它是,因为对于 非最终实例方法 ,编译器不知道调用哪个方法 - 它只确保在 superclass 中有这样的方法,所以它通过在编译代码中插入一条指令将这个决定延长到运行时(后期绑定),然后检查它获取变量指向的实际对象,并调用其方法 (source)。
然而,在this article中指出:
Method Overriding is an example of runtime polymorphism. When a parent
class reference points to the child class object then the call to the
overridden method is determined at runtime, because during method call
which method(parent class or child class) is to be executed is
determined by the type of object. This process in which call to the
overridden method is resolved at runtime is known as dynamic method
dispatch.
那么:方法重写是否足以实现多态性,或者是否需要父 class 引用子 class 对象?我在面试中可以肯定地说仅仅重写 toString() 就是多态性的一个例子吗?
感谢评论和其他一些来源,我相信我现在可以回答我的问题如下:
有人可能会争辩说 覆盖 toString() 是 [=43]的一个例子=]多态性 因为:
Java 虚拟机 (JVM) 总是 选择在 non-final 实例 方法上调用的方法基于它所引用的 object,而不是变量类型定义的方法。这被称为动态方法调用或后期绑定,即在运行时决定调用哪个方法,因此称为“运行时”多态性。资料来源:Oracle Docs, JavaWorld.
因此,无论我们是否有意识地使用多态性,例如programming to interfaces 或者我们做一个简单的 toString() 方法覆盖,但仍然继续使用我们的 classes 和它们自己的 class 变量(即使用“User”变量而不是 parent class "Object" 变量),关于调用哪个方法的决定总是在运行时通过检查 object 我们的变量所指的类型来决定.
因此,无论我们使用两个初始化中的哪一个,都会对调用哪个模型(即多态行为)进行评估:
User user = new User("username1");
System.out.println(user);
// or
Object object = new User("username1");
System.out.println(object);
变量的类型对于我们的问题来说是微不足道的,重要的是它所指的object,以及所有可能的object ]s 它指的是(即 parent 或 child),由运行时决定。
变量的 type 仅与将可用方法的范围限制为 parent class 中的方法相关,并且可能被它的 children(如果我们使用 parent class 引用变量)或访问 child 的特定方法(如果我们使用 child class参考变量)。
例如,如果我们向 User class 添加了一个新方法:
public String instanceMethod () {
return "User instance method called";
}
无法通过 Object class 变量获得:
它只能通过用户 class 变量使用。
希望这能为其他也需要更详细解释的人消除困惑。
我今天 Java 考试,考官问我是否可以提供任何在我的 Spring Boot 项目中使用多态性的示例。
一开始我什么也想不起来,他指出我在我的模型中覆盖了 toString(),这是 dynamic/runtime 多态性。
但是,我不确定我是否理解他的观点,因为据我所知,当我们有一个 parent class 引用变量指向 subclass对象(关注动态多态).
然后在运行时获取父 class 变量指向的实际对象并调用其方法,如解释得很好 here。
但是,我没有在我的项目中使用向上转换(即使用对象 class 变量初始化我的 POJO classes)。
因此,我的问题是 - 重写 toString() 被认为是多态性,尽管父 class(对象)从未用作参考变量?
我在 Whosebug 上找到的所有运行时多态性示例,包括那些 here and this 带有 toString 的示例,说明了我们有一个父 class 变量指向子 class 对象,例如:
Object object = new User("petar");
String name = object.toString(); // assign to variable for clarity`s sake
System.out.println(name);
// prints petar
我的用户 class 在哪里:
public class User {
String name;
public User(String name) {
this.name = name;
}
public String toString() {
return name;
}
}
但是,在我的项目中,我只是简单地创建用户和其他 POJO classes,它们具有自己的引用变量,例如:
User user = new User("petar");
String name = user.toString();
System.out.println(name);
// prints petar, as toString is overriden
上面是否考虑了多态性,虽然没有涉及向上转型/父引用变量?
我的 class 伙伴认为它是,因为对于 非最终实例方法 ,编译器不知道调用哪个方法 - 它只确保在 superclass 中有这样的方法,所以它通过在编译代码中插入一条指令将这个决定延长到运行时(后期绑定),然后检查它获取变量指向的实际对象,并调用其方法 (source)。
然而,在this article中指出:
Method Overriding is an example of runtime polymorphism. When a parent class reference points to the child class object then the call to the overridden method is determined at runtime, because during method call which method(parent class or child class) is to be executed is determined by the type of object. This process in which call to the overridden method is resolved at runtime is known as dynamic method dispatch.
那么:方法重写是否足以实现多态性,或者是否需要父 class 引用子 class 对象?我在面试中可以肯定地说仅仅重写 toString() 就是多态性的一个例子吗?
感谢评论和其他一些来源,我相信我现在可以回答我的问题如下:
有人可能会争辩说 覆盖 toString() 是 [=43]的一个例子=]多态性 因为:
Java 虚拟机 (JVM) 总是 选择在 non-final 实例 方法上调用的方法基于它所引用的 object,而不是变量类型定义的方法。这被称为动态方法调用或后期绑定,即在运行时决定调用哪个方法,因此称为“运行时”多态性。资料来源:Oracle Docs, JavaWorld.
因此,无论我们是否有意识地使用多态性,例如programming to interfaces 或者我们做一个简单的 toString() 方法覆盖,但仍然继续使用我们的 classes 和它们自己的 class 变量(即使用“User”变量而不是 parent class "Object" 变量),关于调用哪个方法的决定总是在运行时通过检查 object 我们的变量所指的类型来决定.
因此,无论我们使用两个初始化中的哪一个,都会对调用哪个模型(即多态行为)进行评估:
User user = new User("username1");
System.out.println(user);
// or
Object object = new User("username1");
System.out.println(object);
变量的类型对于我们的问题来说是微不足道的,重要的是它所指的object,以及所有可能的object ]s 它指的是(即 parent 或 child),由运行时决定。
变量的 type 仅与将可用方法的范围限制为 parent class 中的方法相关,并且可能被它的 children(如果我们使用 parent class 引用变量)或访问 child 的特定方法(如果我们使用 child class参考变量)。
例如,如果我们向 User class 添加了一个新方法:
public String instanceMethod () {
return "User instance method called";
}
无法通过 Object class 变量获得:
它只能通过用户 class 变量使用。
希望这能为其他也需要更详细解释的人消除困惑。