Java 非面向对象语言中的面向对象代码

Java 非面向对象语言中的面向对象代码,java,c++,c,oop,Java,C++,C,Oop,这句话是真的吗 编写面向对象的代码,即使是在非面向对象语言中 有人能举个例子吗。。或者提供一些链接…是的,您可以这样做,您可以用过程语言(如c)模拟OOP概念,如继承和多态 因为您需要一个代码示例,所以这里有一个: 模拟继承,你需要的是结构的第一个成员是超类的一个实例,然后你可以像C++继承一样,把指针指向基础和派生类。 struct BaseClass { //... }; struct DerivedClass { struct BaseClass

这句话是真的吗

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


有人能举个例子吗。。或者提供一些链接…

是的,您可以这样做,您可以用过程语言(如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语言,而不是以这种方式玩。

即使使用非面向对象语言(如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;
}
等等。当然,这对程序员来说确实需要更多的纪律,但没有什么能阻止他以面向对象的方式表达代码。

如果问题是“即使是在非面向对象语言中也可以编写面向对象的代码”,那么答案是肯定的。 例如,原来的C++编译器被称为cFAX,它以C++作为输入,输出C,因此可以用C语言来表达面向对象的代码,这绝对不是面向对象语言。
但是,很少有任何理由这样做,也有许多缺点,因为您没有得到编译器的帮助或支持。

考虑一下:面向对象语言功能是如何实现的?如果不是经常的话,必须有面向对象的特性的非面向对象的实现:例如,在C++中,UpcCase/DecCasts实际上是指针操作:如果我有一个继承多个对象的对象,那么我将它的内存放在这样:

->/**********************/
  / PARENT 1 FIELDS      /
  /**********************/
  / PARENT 2 FIELDS      /
  /**********************/
  / CHILD SPECIFIC FIELDS/
->
是一个指针:当前它指向对象的前面,因此从这里看,对象看起来像一个子对象,它继承自PARENT1和PARENT2。如果要将此对象强制转换为PARENT2,则只需更改指针的位置:

    /**********************/
    / PARENT 1 FIELDS      /
 -> /**********************/
    / PARENT 2 FIELDS      /
    /**********************/
    / CHILD SPECIFIC FIELDS/
这样从指针开始的内存布局看起来像PARENT2对象

对于大多数面向对象的操作,也存在类似的操作。实现这一点所需的只是指针,而不是“面向对象”特性本身。因此,在这个实现中,如果您有指针,您可以自己创建面向对象

一个著名的例子是linux内核中的实践

例如:宏的
容器定义为:

#define container_of(ptr, type, member) ({ \
                const typeof( ((type *)0)->member ) *__mptr = (ptr); 
                (type *)( (char *)__mptr - offsetof(type,member) );})

它只需执行一些指针操作并强制转换为“向上转换”——获取父对象。

也许最著名的例子是GTk库和由此派生的Gnome桌面

这些都是用纯C编写的,但是遵循了纯OO设计原则

这并不难想象

C++:

C和笨重的OO:

ret = method(Objectref,parm1,parm2);
您可以使用此习惯用法和类似习惯用法在C中实现任何OO设计

当C++经历标准变化时,它们的性能、兼容性和稳定性。 您失去的是一些编译时验证灵活性。您可以指定一个特定的方法需要一个“三角形”对象作为第一个参数,但您不能有一个方法将采用通用的“形状”对象,您必须接受任何参考值。 另外,你需要多加小心


有一个关于利弊的讨论

这个句子在语法上不正确,所以它的正确与否是没有意义的。。。查看GTK源代码或旧的Xt工具包。这两个都是用C写的。这个(非)问题更适合你。你能用代码找到任何例子吗。。。或者一些引用…?只要您的语言是图灵完整的,您就可以首先在其中编写代码,比如Java,然后使用您的框架。当然,这件事的难易程度取决于具体的语言,但这总是可能的。@Raihan Jamal:更新了答案以回答您的问题。您知道,不仅仅是编译器关心OOP。一种OOP lite(OO减去对封装和继承的编译器支持)可能非常有用。考虑ADTs,API就像GTK+,甚至Win32。当你可以认为你传递的东西是不透明的,并且只需使用一些定义良好的函数来修改它并查询它的状态,那就是面向对象的。许多人会认为多态性,包括虚拟函数,对于面向对象的东西来说是必需的。你所描述的工具是有用的,但是如果你真的想写面向对象的代码,如果可以的话,使用面向对象的语言要容易得多?Win32的窗口过程(包括更改它以对窗口进行子类化的能力)?等等?我想,你可能会不情愿地说,有些Win32的东西有点面向对象。尽管如此,考虑到在OO语言和用C编写Win32 API调用之间的选择,我知道我会选择哪一种。几乎所有的Win32在很大程度上都是面向对象的。你有一个HDC,你可以在上面画画——不管你是在屏幕上画画,还是在打印页面上画画,甚至是在生成一个图元文件。调用
WaitForMultipleObjects
,您不必关心这些句柄是否指向进程、套接字、事件对象等。可以通过向控件发送消息来操纵控件,并处理许多标准消息。当然,C++可以使它更容易。但是C++中所有可能的东西都是可能的,甚至可以很容易,C中所有缺少的是编译器的强制执行。
ret = method(Objectref,parm1,parm2);