I was reading some article on the internet as I was preparing for interview and I found out below statement-
Writing object oriented code, even in non-object oriented language?
Is this statement true??
Can anybody provide an example to justify the above statement if somebody asked me this question in the interview.
And when do we write object oriented code in non object oriented language?
I mainly worked in Java. So any example corresponding to that will be helpful.
Thanks in advance.
4
Yes. Early C++ compilers translated the code to C before compiling with a normal C compiler. Today, that’s how Vala works. Vala is based on the GLib Object System, which provides object-oriented features for C, but is apparently quite cumbersome. Vala streamlines the process.
As for an example, the following would be loosely equivalent:
Java:
Person.java:
public class Person {
private String name;
private int age;
public Person(String name, int age) { /* code */ }
int getAge () {
return age;
}
String getName () {
return name;
}
void setAge (int age) {
this.age = age;
}
void setName (String name) {
this.name = name;
}
}
C:
person.h:
/*
This line serves two purposes:
a. Declare the struct without revealing its attributes; this is
called an "opaque struct."
b. Let us use just `Person` instead of `struct Person` to refer to
the struct.
*/
typedef struct Person Person;
/* Constructor */
Person* person_new (const char *name, int age);
/* Destructor -- just a wrapper around free() for simple cases */
void person_free (Person *obj);
/* Other methods */
int person_get_age (const Person *obj);
const char* person_get_name (const Person *obj);
void person_set_age (Person *obj, int age);
void person_set_name (Person *obj, const char *name);
person.c:
#include <stdlib.h>
#include "person.h"
/* Now we define the struct. */
struct Person
{
int age;
char *name;
};
Person* person_new (const char *name, int age)
{
Person *obj = (Person*) malloc (sizeof(Person));
obj->name = name;
obj->age = age;
return obj;
}
void person_free (Person *obj)
{
free (obj);
}
int person_get_age (const Person *obj)
{
return obj->age;
}
const char* person_get_name (const Person *obj)
{
return obj->name;
}
void person_set_age (Person *obj, int age)
{
obj->age = age;
}
void person_set_name (Person *obj, const char *name)
{
obj->name = name;
}
Then to use this you’d do something like the following:
Person *me = person_new ("James Jensen", 27);
printf ("Hi, I'm %s and I'm %i years old.n",
person_get_name (me),
person_get_age (me));
person_free (me);
You can also do inheritance, but it’s quite a bit trickier and I’m not really confident in my abilities to do it. Neverthless, the basic approach is something like the following (corrections welcome):
importantperson.c:
#include <stdlib.h>
#include "person.h"
/* Please just imagine I wrote this. */
#include "importantperson.h"
struct ImportantPerson
{
Person super; /* Note that this is NOT a pointer. */
int importance;
};
ImportantPerson* importantperson_new (const char *name, int age,
int importance)
{
ImportantPerson *obj = (ImportantPerson*) malloc (sizeof(ImportantPerson));
person_set_name(&(obj->super), name);
person_set_age(&(obj->super), age);
obj->importance = importance;
return obj;
}
void importantperson_free (ImportantPerson *obj)
{
free (obj);
}
int importantperson_get_age (ImportantPerson *obj)
{
return person_get_age (&(obj->super));
}
/* ...other getters... */
void importantperson_set_age (ImportantPerson *obj, int age)
{
person_set_age (&(obj->super), age);
}
/* ...other setters... */
If I’m not mistaken, due to the way C organizes data, having a non-pointer Person
object as the first attribute of ImportantPerson
also allows you to do this:
ImportantPerson *me = importantperson_new ("James Jensen", 27, 9001);
/* Now I humble myself a bit... */
Person *p = (Person*) me;
printf ("Hi, my name is %s and I'm %i years old.n",
person_get_name (p),
person_get_age (p));
/*
Now, destructors can be a bit of a problem. If they weren't both just
wrapping free(), this would do the wrong thing:
person_free (p);
*/
importantperson_free (me);
I hope that clears things up. As always, I welcome corrections from more experienced programmers.
2
There’s a rough way to do it in any language using something like a struct. You just need to make sure to have some variables local to that struct and a set of functions (methods) that operate on them. You’d store functions via pointers to those functions and only accessing things via a given struct. There’s an extensive book written on doing such programming in ANSI-C as referenced in this Stack Overflow post.
Python’s objects are dictionaries of variables and functions in a similar vein. Other languages also use this approach and languages that support dictionaries can be made to work similarly. Even languages that don’t could be made to if you figure out how to make a dictionary in them.
1