多态性是OOP独有的吗?
我是一名学生,所以我不知道我的问题是否放错了位置。我知道在OOP中,多态性通常是通过方法重写、函数重载等实现的。但这是OOP语言独有的概念吗?如果不是,您能否提供一些示例,说明如何在非OOP语言中实现它,包括C语言,但不限于C语言?(到目前为止,我有一些java、C++、C、JavaScript和PHP经验) 谢谢 但这是OOP语言独有的概念吗 有点。它是OO语言的定义属性。根据函数调用中涉及的一个或多个对象选择运行时行为的能力是OOP的全部内容多态性是OOP独有的吗?,oop,language-agnostic,polymorphism,Oop,Language Agnostic,Polymorphism,我是一名学生,所以我不知道我的问题是否放错了位置。我知道在OOP中,多态性通常是通过方法重写、函数重载等实现的。但这是OOP语言独有的概念吗?如果不是,您能否提供一些示例,说明如何在非OOP语言中实现它,包括C语言,但不限于C语言?(到目前为止,我有一些java、C++、C、JavaScript和PHP经验) 谢谢 但这是OOP语言独有的概念吗 有点。它是OO语言的定义属性。根据函数调用中涉及的一个或多个对象选择运行时行为的能力是OOP的全部内容 但当然还有许多其他类型的多态性。例如,C++通过
但当然还有许多其他类型的多态性。例如,C++通过模板支持编译时多态性。但是很多人会说这不是OOP。多态性并不是OOP所独有的,甚至不是OOP类系统所独有的,但正如您所指出的,它们被认为是为软件中的普遍理念提供了一种标准模式。它可以在没有一流支持的语言中模拟(并且在某些语言中有语法帮助,例如lua)
旧的程序语言,使用相同的技巧C++,或多或少明确;通常为一些动态分配的数据添加一个void*,并为其上的操作添加一些函数指针。标准的库函数在一定程度上说明了这一点
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct Sortable {
char *(*toString)(struct Sortable *p);
} Sortable;
typedef struct AThing {
Sortable p;
int value;
} AThing;
typedef struct BThing {
Sortable p;
const char *str;
} BThing;
int sortableCompare(const void *a, const void *b) {
int res;
Sortable *aa = *((Sortable **)a);
Sortable *bb = *((Sortable **)b);
char *astr = aa->toString(aa);
char *bstr = bb->toString(bb);
res = strcmp(astr, bstr);
free(astr);
free(bstr);
return res;
}
char *AThing_toString(Sortable *p) {
AThing *self = (AThing*)p;
char *res = malloc(15);
snprintf(res, 15, "%d", self->value);
return res;
}
char *BThing_toString(Sortable *p) {
BThing *self = (BThing*)p;
return strdup(self->str);
}
AThing *createIntSortable(int i) {
AThing *self = malloc(sizeof(*self));
self->p.toString = AThing_toString;
self->value = i;
return self;
}
BThing *createStringSortable(const char *str) {
BThing *self = malloc(sizeof(*self));
self->p.toString = BThing_toString;
self->str = str;
return self;
}
int main() {
Sortable *array[3];
array[0] = &createIntSortable(1)->p;
array[1] = &createStringSortable("hi")->p;
array[2] = &createIntSortable(3)->p;
qsort
( array // auto decay and coerce to void*
, sizeof(array) / sizeof(array[0]) // nelem
, sizeof(array[0]) // elem size
, &sortableCompare // compare function
);
for (int i = 0; i < sizeof(array) / sizeof(array[0]); ++i) {
char *p = array[i]->toString(array[i]);
printf("%d %s\n", i, p);
free(p);
}
for (int i = 0; i < sizeof(array) / sizeof(array[0]); ++i) {
// To be more fancy, make a destructor in p
free(array[i]);
}
}
#包括
#包括
#包括
typedef结构可排序{
char*(*toString)(结构可排序*p);
}可排序的;
类型定义结构{
可排序p;
int值;
}阿辛;
类型定义结构类型{
可排序p;
常量字符*str;
}BThing;
int可排序比较(常量无效*a,常量无效*b){
国际关系;
可排序*aa=*((可排序**)a);
可排序*bb=*((可排序**)b);
char*astr=aa->toString(aa);
char*bstr=bb->toString(bb);
res=strcmp(应力应变率、应力应变率);
免费(应科院);
免费(bstr);
返回res;
}
char*AThing_toString(可排序*p){
AThing*self=(AThing*)p;
char*res=malloc(15);
snprintf(分辨率,15,“%d”,自->值);
返回res;
}
字符*b字符串(可排序*p){
BThing*self=(BThing*)p;
返回strdup(self->str);
}
AThing*createIntSortable(inti){
AThing*self=malloc(sizeof(*self));
self->p.toString=AThing\u toString;
自我->价值=i;
回归自我;
}
BThing*createStringSortable(常量字符*str){
BThing*self=malloc(sizeof(*self));
self->p.toString=b字符串;
自我->str=str;
回归自我;
}
int main(){
可排序*数组[3];
数组[0]=&createIntSortable(1)->p;
数组[1]=&createStringSortable(“hi”)->p;
数组[2]=&createIntSortable(3)->p;
快速排序
(数组//自动衰减并强制为无效*
,sizeof(数组)/sizeof(数组[0])//nelem
,sizeof(数组[0])//元素大小
,&可排序比较//比较函数
);
对于(int i=0;itoString(array[i]);
printf(“%d%s\n”,i,p);
自由基(p);
}
对于(int i=0;i
go和rust并不是严格面向对象的,而是使用接口和duck类型转换为所有类型提供与对象相同的属性。您可以用方法装饰任何东西,并选择self参数是通过引用还是通过值
Haskell有类型类,这有点类似于go和rust风格的多态性,因为提供类型的人提供该类型上接口的实现(例如,可以用作列表的对象可能实现)。然后,接受实现monoid的对象的任何函数都可以接收对象对monoid typeclass实现的自动强制
在没有类型类的函数式语言中(甚至在haskell中的大部分时间),人们通过编写通用的高阶函数,然后在他们关心的对象上传递操作集,来实现多态性。通过这种方式,您可以拥有容器、过滤器、变压器等,它们不知道自己在做什么,但根据用户自己的目标执行一组操作。这方面的一个很好的完整示例是,它在一种没有任何多态功能的语言中实现了*。与C相比,它获得了一些简洁性,因为虽然多态性不是内置的,但泛型类型是。根据定义:
“在编程语言和类型理论中,多态性(源自希腊语πολύς,polys,“many,much”和μορφή,morpē,“form,shape”)是为不同类型的实体提供单一接口。多态类型的操作也可以应用于其他类型的值。”
为尼尔的回答增添了色彩。多态性不仅仅是基于继承的,尽管泛化非常适合它。在C++中,您可以通过更多的努力使用STL来应用<强>多态性p>
进一步阅读和引用:
-
-< /P>当然,选择你喜欢的静态类型的函数语言,并且输入系统可能支持多态性,例如Haskell。-记住,原来的C++编译器只是把C++代码翻译成普通C代码。因此,它可以肯定地使用非OOP语言来完成(虽然它可能需要一些工作)。“有些不,这不是cFAN(原来的C++编译器)做的那样——它是一个真正的编译器,而不是汇编语言,而不是许多汇编语言。C类是预处理器,但是它处理的语言不是C++。