详述多态性
Elaborating on Polymorphism
我在 Whosebug 上阅读了很多关于多态性的问题。这个问题是构建我的想法的问题,因为我已经阅读和研究了很多,以至于我有很多想法。我需要对我对多态性的想法进行评论和批评。我会用Java来证明我的想法。
多态性是在谈论某个实体时具有不同形式的特征。可以通过以下方式实现:
派生的 class 从其基础 class 继承所有可见的方法,因此可以 override
某些方法的行为。
例如:
class Shape {
void draw(){
System.out.println("I am drawing using a shape object");
}
}
class Rectangle extends Shape{
void draw(){
// This method is overriden
System.out.println("I am drawing using a rectangle object");
}
}
这里实现多态性的方式是,如果在 运行 时,draw()
与 Rectangle
的实例一起使用 draw()
在 Rectangle
class 将被调用。
由于矩形是一种形状,多态性是 draw()
根据调用它的上下文采用不同形式的事实。这也称为继承多态性。
另一种实现多态性的方法是通过接口。
interface Vehicle{
void move();
}
class Car implements Vehicle{
void move(){
System.out.println("The car is moving!");
}
}
class Plane implements Vehicle{
void move(){
System.out.println("The plane is flying!");
}
}
// we declare an object of type Vehicle
// At compile-time, the concrete implementation of someVehicle is no known
// and thus polymorphism is achieved in the sense that someVehicle could
// either be a Car or a Plane depending on which concrete class is used
// to instantiate it at run-time.
Vehicle someVehicle;
用户定义的运算符重载(不在Java,但在C++中)
在 Java 中,运算符重载的一个示例是 + 运算符,其中根据操作数,+ 执行特定功能。如果 + 被应用于字符串,它会连接它们。如果它被应用于整数,它会进行算术加法。
那么,方法重载也是一种实现多态的方式吗?我对多态性的理解遗漏了什么?
多态性按照您所解释的方式运行,但并不是实现覆盖先前定义的方法的新方法的实际行为。多态性更像是一个抽象的概念。总的来说:
Polymorphism is the ability of an object to take on many forms. The
most common use of polymorphism in OOP occurs when a parent class
reference is used to refer to a child class object.
还可以找到更多信息 here。
我认为您对 java 中发生的其他事情感到困惑。运算符重载是其他编程语言(如 C++)中多态性的一种形式,但是在 java 中,它们是原始类型(例如 int 和布尔值(也包括 String 类型))与扩展基础的所有其他东西之间的区别 java.lang.Object.语言设计者决定不对 class 进行运算符重载,因为它可能会非常混乱。所以你在 Java 中没有有效的运算符多态性,因为你不能定义自己的运算符或覆盖其他运算符, toString() 方法除外,但在我看来这确实是一个接口。我认为你不能说 +(用于字符串)运算符是 java 中运算符重载的示例,即使是字符串,它也是调用的 toString() 方法,而这并不是真正的运算符重载在我看来,因为只有当您应用有关执行操作的顺序的规则时,操作员才会使用该术语。如果您只有一个运算符,即 + 将字符串连接在一起,则不会应用任何评估顺序规则,因此它只是一种语法。你有用于整数和浮点数的 +、-、/ 运算符,但你不能重载它们,所以这不是多态性。
多态这个词的意思是"many forms"。
您给出的两个示例是多态性的明确有效示例:
在第一个示例中,您拥有 "draw" 功能的 "many forms",具体取决于您在 [=10= 上调用 "draw" 的对象的形状类型]
在第二个中,您有 "move" 的 "many forms" 功能,具体取决于车辆
由于后期绑定,将在运行 时决定实际调用的方法
事实上,这两个示例非常相似,它们都是 子类型 的示例,这是您在 Java.
中实现多态性的方式
请注意,在 Java 中需要子类型化,因为 Java 是一种静态类型语言。在像 Smalltalk 这样的动态类型语言中,具有 "draw" 方法的不同实现就足够了,即使对象的 classes 不属于相同的 class 层次结构。
现在,关于 方法重载 :确实,如果您定义一个方法的多个版本来接收不同的参数类型,您也会有该方法的 "many forms"。
区别在于,在那种情况下,调用哪个方法的决定是在编译时做出的。这就是为什么许多人将方法重载称为 静态多态性 .
但是,由于它是静态的,而且您基本上可以通过为方法指定不同的名称并根据您使用的类型自行决定调用哪个方法来实现相同的目的,许多人也会说该方法重载实际上不是多态性。
我觉得主要还是要看你要用的"polymorphism"的定义,不过希望上面的解释能帮助搞清楚区别。
我在 Whosebug 上阅读了很多关于多态性的问题。这个问题是构建我的想法的问题,因为我已经阅读和研究了很多,以至于我有很多想法。我需要对我对多态性的想法进行评论和批评。我会用Java来证明我的想法。
多态性是在谈论某个实体时具有不同形式的特征。可以通过以下方式实现:
派生的 class 从其基础 class 继承所有可见的方法,因此可以
override
某些方法的行为。 例如:class Shape { void draw(){ System.out.println("I am drawing using a shape object"); } } class Rectangle extends Shape{ void draw(){ // This method is overriden System.out.println("I am drawing using a rectangle object"); } }
这里实现多态性的方式是,如果在 运行 时,draw()
与 Rectangle
的实例一起使用 draw()
在 Rectangle
class 将被调用。
由于矩形是一种形状,多态性是 draw()
根据调用它的上下文采用不同形式的事实。这也称为继承多态性。
另一种实现多态性的方法是通过接口。
interface Vehicle{ void move(); } class Car implements Vehicle{ void move(){ System.out.println("The car is moving!"); } } class Plane implements Vehicle{ void move(){ System.out.println("The plane is flying!"); } } // we declare an object of type Vehicle // At compile-time, the concrete implementation of someVehicle is no known // and thus polymorphism is achieved in the sense that someVehicle could // either be a Car or a Plane depending on which concrete class is used // to instantiate it at run-time. Vehicle someVehicle;
用户定义的运算符重载(不在Java,但在C++中)
在 Java 中,运算符重载的一个示例是 + 运算符,其中根据操作数,+ 执行特定功能。如果 + 被应用于字符串,它会连接它们。如果它被应用于整数,它会进行算术加法。
那么,方法重载也是一种实现多态的方式吗?我对多态性的理解遗漏了什么?
多态性按照您所解释的方式运行,但并不是实现覆盖先前定义的方法的新方法的实际行为。多态性更像是一个抽象的概念。总的来说:
Polymorphism is the ability of an object to take on many forms. The most common use of polymorphism in OOP occurs when a parent class reference is used to refer to a child class object.
还可以找到更多信息 here。
我认为您对 java 中发生的其他事情感到困惑。运算符重载是其他编程语言(如 C++)中多态性的一种形式,但是在 java 中,它们是原始类型(例如 int 和布尔值(也包括 String 类型))与扩展基础的所有其他东西之间的区别 java.lang.Object.语言设计者决定不对 class 进行运算符重载,因为它可能会非常混乱。所以你在 Java 中没有有效的运算符多态性,因为你不能定义自己的运算符或覆盖其他运算符, toString() 方法除外,但在我看来这确实是一个接口。我认为你不能说 +(用于字符串)运算符是 java 中运算符重载的示例,即使是字符串,它也是调用的 toString() 方法,而这并不是真正的运算符重载在我看来,因为只有当您应用有关执行操作的顺序的规则时,操作员才会使用该术语。如果您只有一个运算符,即 + 将字符串连接在一起,则不会应用任何评估顺序规则,因此它只是一种语法。你有用于整数和浮点数的 +、-、/ 运算符,但你不能重载它们,所以这不是多态性。
多态这个词的意思是"many forms"。
您给出的两个示例是多态性的明确有效示例:
在第一个示例中,您拥有 "draw" 功能的 "many forms",具体取决于您在 [=10= 上调用 "draw" 的对象的形状类型]
在第二个中,您有 "move" 的 "many forms" 功能,具体取决于车辆
由于后期绑定,将在运行 时决定实际调用的方法
事实上,这两个示例非常相似,它们都是 子类型 的示例,这是您在 Java.
中实现多态性的方式请注意,在 Java 中需要子类型化,因为 Java 是一种静态类型语言。在像 Smalltalk 这样的动态类型语言中,具有 "draw" 方法的不同实现就足够了,即使对象的 classes 不属于相同的 class 层次结构。
现在,关于 方法重载 :确实,如果您定义一个方法的多个版本来接收不同的参数类型,您也会有该方法的 "many forms"。
区别在于,在那种情况下,调用哪个方法的决定是在编译时做出的。这就是为什么许多人将方法重载称为 静态多态性 .
但是,由于它是静态的,而且您基本上可以通过为方法指定不同的名称并根据您使用的类型自行决定调用哪个方法来实现相同的目的,许多人也会说该方法重载实际上不是多态性。
我觉得主要还是要看你要用的"polymorphism"的定义,不过希望上面的解释能帮助搞清楚区别。