The Object Oriented Paradigm; Classes and Objects

De la WikiLabs
Jump to navigationJump to search

Notions About Programming Paradigms

Since the invention of computing machines, the struggle for performance and technological advance has been fought on two fronts: on one hand by improving hardware performance by increasing clock frequency, the number of cores, the size of available physical memory and the complexity of the instruction set, and on the other hand, by finding new methods for efficiently programming the algorithms. By new methods we don't only mean new programming languages, although, if we follow their evolution over time, we will see a significant increase, in both numbers and variety. Why are new programming languages still being created, if there already is such a large number of them? There are several reasons, but the main one is that new functionality appears and it needs to be expressed in ways that we don't yet have (for example, SIMD - Single Instruction Multiple Data - accelerators are difficult to use in the C, because the language does not have support for vector data types). However, new programming languages are also triggered by something else: the invention of new programming paradigms.

The programming paradigm refers to the way an algorithm is described. Surely, by description, we don't mean the way the additions or multiplications are done, or the language itself, but a higher level. For example, how the data is structured, how this structures and the program behavior interacts, and so on. There is a relatively small number of programming paradigms, and we will name some examples, but it is important to note that it can't be stated that one is better than the other, but, just like in the case of programming languages, each is optimal for a certain class of applications.

Imperative Procedural Programming

Imperative programming describes an algorithm at an instruction level, which modifies the state of the program. Procedural programming structures these instructions into distinct sequences, called procedures or functions (not to be confused with functional programming), which work with global data structures, which are visible to all procedures, or local data structures, only visible to the procedure in which they are declared. As an example of a procedural programming language, we have the original C language (not C++). Programs written in C are built of functions (which can take arguments, compute and return data) and global data.


Programarea procedurală se folosește pe scară largă în programare la nivel foarte jos (kernel, sistem de operare, embedded), deoarece C-ul oferă control absolut asupra resurselor hardware, și se potrivește foarte bine cu modul în care procesorul execută programul. Pe de altă parte, în cazul aplicațiilor la nivel înalt, cum ar fi editoare de text, aplicații client - server, simulatoare, programe de sinteză, etc., acolo unde se scrie o cantitate enormă de algoritmi, faptul că programarea procedurală nu oferă o structurare a datelor și o legătură între date și procedurile care le folosesc, o face foarte greu de folosit. În aceste cazuri apar probleme de securitate, probleme de memorie, probleme de mentenanță și dezvoltare ulterioară, etc.

Programarea declarativă funcțională

Programarea funcțională se referă la stilul și limbajele de programare în care computația se tratează evaluând expresii matematice. Spre deosebire de programarea imperative, unde apar stări și variabile, programarea funcțională pe bazează pe un sistem formal numit lambda-calcul, care descrie un program sub forma compunerii unor funcții matematice.


Unul din primele limbaje funcționale este Lisp.

Programarea orientată obiect

Programarea orientată obiect are ca punct de plecare programarea procedurală, în sensul că se bazează tot pe noțiunile de stare și variabile, dar introduce o serie de concepte care ajută la structurarea programelor:

  • clase și obiecte;
  • încapsulare;
  • polimorfism;
  • moștenire.

Majoritatea acestor noțiuni vor fi prezentate în pagina noțiuni avansate de programare obiect-orientată;

Tipuri de date

Structura în C

Plecând de la limbajul C, ne amintim că acesta pune la dispoziție o serie de tipuri de date primitive, incluse în standardul limbajului. Ca exemple, avem: int, long, char, double, etc. În plus, există posibilitatea de a crea structuri compuse folosind cuvântul cheie struct. O structură în C este compusă din una sau mai multe variabile care pot fi ori de tip primitiv, ori alte structuri.


În continuare avem un exemplu de definiție a unor structuri în C.

struct string{
    char* str;
    unsigned length;
};

struct person{
    struct string *first_name;
    struct string *last_name;
    unsigned age;
    float height;
    float weight;
};

Se vede că structura person conține pointeri la două structuri de tip string. Relația este descrisă de schema bloc următoare (cu exemple de valori pentru variabilele primitive):

Schema bloc pentru relația dintre structurile string și person

În continuare, vom da un exemplu de utilizare a acestor structuri:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int main(){
    //make a default string with no content and length = 30
    struct string * some_string = (struct string*)malloc(sizeof(struct string));
    unsigned default_length = 30;
    some_string->length = default_length;
    some_string->str = (char*)malloc(default_length * sizeof(char));
    strcpy(some_string->str, "Vasile");

    //make a person structure in which all strings refer to the default empty string
    struct person* new_person = (struct person*)malloc(sizeof(struct person));
    new_person->first_name = some_string;
    new_person->last_name = some_string;
    new_person->age = 29;
    new_person->height = (float)1.7;
    new_person->weight = 68.9F;

    printf("Persoana se numeste %s %s, are varsta de %d ani, inaltimea %f si greutatea %f\n", new_person->first_name->str, 
        new_person->last_name->str,
        new_person->age,
        new_person->height,
        new_person->weight);

    return 0;
}

În acest exemplu, schema bloc este diferită dintr-un punct de vedere esențial: ambii pointeri de tip string sunt referință la aceeași adresă, respectiv la același string. Astfel, dacă se modifică new_person->first_name, atunci implicit se modifică și new_person->last_name (de fapt este aceeași structură):

Schema bloc pentru relația dintre structurile string și person cu același pointer pentru nume


Pentru a face un rezumat, structura, in C, este un tip de dată compusă din tipuri primitive, sau alte structuri. Analog cu orice alt tip de dată, se pot defini variabile de tipul structurii, așa cum se pot defini variabile de tip primitiv. Limitarea fundamentală a structurilor este că acestea nu pot conține decât date, nu și funcții. Astfel se introduce noțiunea de clasă.

Clasa și obiectul

Atenție: Clasa este o structură care poate conține variabile, numite câmpuri ale clasei, și funcții, numite metode are clasei. Câmpurile și metodele sunt membrii clasei.


Atenție: Metodele unei clase acționează asupra câmpurilor clasei.


Atenție: Clasa este un tip de dată. Datele de tipul clasei se numesc obiecte. Obiectele sunt instanțe ale clasei. Astfel, când se creează un obiect nou, se mai spune că se instanțiază un obiect de tipul clasei respective.