Scrittura del codice OOPS in linguaggio non orientato agli oggetti

2

Stavo leggendo un articolo su Internet mentre mi stavo preparando per l'intervista e ho scoperto la seguente dichiarazione -

Writing object oriented code, even in non-object oriented language?

Questa affermazione è vera ??

Qualcuno può fornire un esempio per giustificare la dichiarazione di cui sopra se qualcuno mi ha fatto questa domanda nell'intervista.

E quando scriviamo il codice orientato agli oggetti nel linguaggio non orientato agli oggetti?

Ho principalmente lavorato in Java. Quindi qualsiasi esempio corrispondente sarà utile.

Grazie in anticipo.

    
posta arsenal 07.04.2013 - 02:26
fonte

2 risposte

8

Sì. I primi compilatori C ++ traducevano il codice in C prima di compilarlo con un normale compilatore C. Oggi, è così che funziona Vala. Vala si basa sul sistema oggetto GLib , che fornisce funzionalità orientate agli oggetti per C, ma è apparentemente piuttosto ingombrante. Vala semplifica il processo.

Come per un esempio, quanto segue sarebbe vagamente equivalente:

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;
}

Quindi per utilizzarlo dovresti fare qualcosa di simile al seguente:

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);

Puoi anche fare ereditarietà, ma è un po 'più complicato e non sono molto fiducioso nelle mie capacità di farlo. Tuttavia, l'approccio di base è qualcosa di simile al seguente (le correzioni sono benvenute):

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... */

Se non mi sbaglio, a causa del modo in cui C organizza i dati, avere un oggetto non puntatore Person come primo attributo di ImportantPerson ti consente anche di fare ciò:

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);

Spero che chiarisca le cose. Come sempre, accolgo con favore correzioni da parte di programmatori esperti.

    
risposta data 07.04.2013 - 03:57
fonte
5

C'è un modo approssimativo di farlo in qualsiasi lingua usando qualcosa come una struttura. Devi solo assicurarti di avere alcune variabili locali per quella struttura e un insieme di funzioni (metodi) che operano su di esse. Dovresti memorizzare le funzioni tramite i puntatori a quelle funzioni e solo l'accesso alle cose tramite una determinata struttura. C'è un ampio libro scritto su come fare una programmazione in ANSI-C come indicato in questo Messaggio Stack overflow .

Gli oggetti di Python sono dizionari di variabili e funzioni in una vena simile. Anche altre lingue usano questo approccio e le lingue che supportano i dizionari possono funzionare in modo simile. Anche le lingue alle quali non si potrebbe fare se si capisce come creare un dizionario al loro interno.

    
risposta data 07.04.2013 - 02:45
fonte

Leggi altre domande sui tag