这句话是真的吗?
编写面向对象的代码,即使是非面向对象的语言。
任何人都可以举个例子......或提供一些链接......
答案 0 :(得分:10)
是的,你可以这样做,你可以像c这样的过程语言模拟OOP概念,如继承和多态。
由于你要求代码示例,这里有一个:
要模拟继承,您需要的只是结构的第一个成员是超类的实例,然后您可以像C ++继承一样转换指向基类和派生类的指针。
struct BaseClass
{
//...
};
struct DerivedClass
{
struct BaseClass super;
//....
};
struct DerivedClass d;
//UpCasting example
struct BaseClass *base_ptr = (struct BaseClass *)&d;
//Downclasting Example
struct DerivedClass *derived_ptr = (struct DerivedClass *)base_ptr;
当然,如果你真的需要OOP,你应该使用OOP语言,而不是以这种方式玩游戏。
答案 1 :(得分:3)
即使在非面向对象的语言(如C)中,也很有可能编写面向对象的代码。以此为例:
typedef struct _Node {
struct _Node* next;
int data;
} Node;
// Constructor
Node* createNode() {
return (Node*)malloc(sizeof(Node));
}
// Getter for data
int getNodeData(Node* node) {
if(node != null) {
return node->data;
}
return -1;
}
等等。当然,这确实需要程序员更多的纪律,但没有什么能阻止他以面向对象的方式表达他的代码。
答案 2 :(得分:3)
考虑一下:如何实现面向对象的语言功能?通常,如果不是总是这样,必须有一些面向对象特性的非面向对象的实现:例如,在C ++中,upcasts / downcasts实际上是指针操作:如果我有一个从多个对象继承的对象,我将它的内存放置得像这样:
->/**********************/
/ PARENT 1 FIELDS /
/**********************/
/ PARENT 2 FIELDS /
/**********************/
/ CHILD SPECIFIC FIELDS/
->
是一个指针:当前它指向对象的前面,所以从这里开始,对象看起来像一个CHILD,它继承了PARENT1和PARENT2。如果我们要将此对象转换为PARENT2,我们只需要更改指针的位置:
/**********************/
/ PARENT 1 FIELDS /
-> /**********************/
/ PARENT 2 FIELDS /
/**********************/
/ CHILD SPECIFIC FIELDS/
使得指针向前的内存布局看起来像PARENT2对象。
对于大多数面向对象的操作,类似的操作也是如此。实现这一点所需要的只是指针,而不是“面向对象”功能本身。因此,在这个实现中,如果你有指针,你可以自己创建面向对象。
一个着名的实例就是在Linux内核中练习。
例如:container_of
宏定义为:
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr);
(type *)( (char *)__mptr - offsetof(type,member) );})
这只是一些指针操作&强制转换为“向上” - 获取父对象。
答案 3 :(得分:3)
也许最着名的例子是GTk图书馆和从中衍生出来的Gnome桌面。
这些是用纯C编写的,但遵循纯粹的OO设计原则。
不难想象。
C ++:
ret = object->method(parm1,parm2);
C with Clunky OO:
ret = method(Objectref,parm1,parm2);
您可以使用此类和类似的习语在C中实现任何OO设计。
在C ++进行标准更改时,他们获得的是性能,兼容性和稳定性。
您失去的是一些编译时验证灵活性。您可以指定特定方法需要“三角形”对象作为第一个参数,但您不能拥有一个方法,该方法将采用通用“形状”对象,您必须接受任何参考值。 另外,你需要多加小心。
讨论了利弊here
答案 4 :(得分:0)
如果问题是“是否可以编写面向对象的代码,即使是非面向对象的语言”,那么答案是肯定的。 例如,原始的C ++编译器被称为cfront,它将C ++作为输入,并输出C.因此,可以在C中表达面向对象的代码,这绝对不是面向对象的语言。 但是,由于没有得到编译器的帮助或支持,因此很少有任何理由这样做,并且存在许多缺点。