面向对象的代码,采用非面向对象的语言

时间:2011-08-05 05:53:03

标签: java c++ c oop

这句话是真的吗?

  

编写面向对象的代码,即使是非面向对象的语言。

任何人都可以举个例子......或提供一些链接......

5 个答案:

答案 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中表达面向对象的代码,这绝对不是面向对象的语言。 但是,由于没有得到编译器的帮助或支持,因此很少有任何理由这样做,并且存在许多缺点。