Programarea în rubin, Partea 3

O metodă este o funcție care descrie răspunsul unui obiect la o cerere primită. Aruncati o privire la apelul metodei de mai jos:

Exemplul arată că pentru un obiect șir se numește o metodă numită lungime.







Din acest exemplu, este clar că decizia cu privire la ce metodă se invocă se ia în timpul execuției și că această alegere depinde de conținutul variabilei. (în primul caz, variabila foo este reprezentată ca o variabilă de șir, în al doilea - ca o matrice).

Cititorul poate avea o întrebare: "Cum este, pentru că lungimea șirului și lungimea matricei sunt tratate diferit?". Nu-ți face griji. Din fericire, Ruby selectează automat metoda potrivită pentru situație. Această caracteristică în programarea orientată pe obiecte se numește polimorfism.

Nu este nevoie să știți cum funcționează această metodă, dar toată lumea ar trebui să știe despre ce metode sunt disponibile pentru obiect. Atunci când se numește o metodă necunoscută, apare o eroare. De exemplu, încercați să apelați metoda "lungime" pentru obiectul "foo", atribuindu-i o valoare de "5".

Am menționat deja un sine special pseudo-variabil. Definește obiectul a cărui metodă a fost numită. Cu toate acestea, indicarea acestei variabile este adesea omisă, de exemplu:

poate fi redus la

Aceste două apeluri sunt identice între ele, doar al doilea mod este o versiune prescurtată a primei.

Lumea reală constă din obiecte care pot fi clasificate. De exemplu, un copil de un an, văzând un câine, se gândește la acesta ca la un "uriaș". În ceea ce privește programarea orientată pe obiecte, "hav-gav" este o clasă. iar obiectul aparținând clasei este o instanță a clasei.

În Ruby, ca și în alte limbi de programare orientate pe obiecte, o clasă este definită mai întâi pentru a descrie comportamentul obiectului și apoi este creată o instanță a clasei - un obiect individual. Acum, să definim clasa.

Declarația de clasă trebuie să înceapă cu clasa de cuvinte cheie și să se termine cu sfârșitul cuvântului cheie. Cuvântul cheie def în acest context începe definirea metodei de clasă.

Deci, am descris o clasă pe nume Dog ", iar acum vom crea un obiect.

Acest cod creează o nouă instanță a clasei Dog și o asociază cu variabila tommy. Noua metodă a oricărei clase creează o nouă instanță a acestei clase. Acum, variabila tommy are proprietățile clasei Dog și poate "bug" (metoda de coacere).

moștenire

Te-ai intrebat vreodata cat de diferiti oameni clasifica obiecte? De exemplu, cum văd un câine? Un matematician poate descrie un câine ca o combinație de numere și figuri geometrice. Fizicianul este rezultatul muncii forțelor naturale și artificiale. Sora mea (biolog) poate reprezenta câinele ca un fel de echipă de câine (canine domesticus). Pentru ea, câinele este o specie de câine, câinele este o specie de mamifere, iar mamiferele sunt mereu animale.

Din aceasta este clar că clasificarea obiectelor are forma unei ierarhii, deși nu întotdeauna. Să vedem cum poate fi implementat acest lucru în Ruby.

Se știe că proprietățile clasei părinte nu sunt întotdeauna moștenite de descendenți. De exemplu, pinguinii nu pot zbura, deși sunt păsări. Cu toate acestea, pinguinii poartă multe alte caracteristici inerente la păsări, de exemplu, ele pun ouă. Cazuri similare pot fi implementate în Ruby, dar le las pe cititori cu ocazia să mă descurc singur.

Când creați o nouă clasă care moștenește caracteristicile clasei părinte, va trebui să definim doar metode care descriu diferențele dintre descendent și părinte. Acesta este unul dintre avantajele programării orientate pe obiecte, care uneori se numește "programare diferențială".

Metode imperative

Am observat deja diferențe în comportamentul instanțelor de clase de copii după suprimarea metodelor din clasa părinte. Uitați-vă la exemplul de mai jos:

În clasa copil care suprascrie metoda clasei părinte, puteți apela metoda parentală originală cu super-cuvântul cheie. Încercați să executați acest cod:







Sper că aceste exemple simple sunt suficiente pentru a înțelege principiile moștenirii și redefinării metodelor.

Mai multe despre metodele

Posibilitatea de a apela o metodă poate fi limitată. Pentru o funcție (definită la nivelul superior), vedeți mai jos:

Dacă definiția funcției este în afara definiției clasei, atunci ea este adăugată ca o metodă a clasei Object. Clasa Object este clasa de bază pentru toate celelalte clase - în Ruby toate clasele sunt descendenți ai clasei Object. Astfel, metoda sqr "poate fi apelată din alte clase.

Acum că orice clasă poate invoca metoda sqr, să încercăm să o numim folosind sinele pseudo-variabilă:

Așa cum am arătat mai sus, apelarea unei funcții cu rezultate de sine într-un mesaj de eroare. Acest mesaj nu este destul de clar (intuitiv), ce înseamnă?

Linia de jos este că funcțiile definite în afara oricărei clase ar trebui să fie numite funcții simple și nu ca metode. Vedeți ce mesaj de eroare primiți când apelați o metodă care nu este definită.

Metodele definite ca funcții simple ar trebui să fie numite funcții simple, similare cu funcțiile C ++, chiar și într-o clasă.

Domeniul de aplicare al metodei poate fi limitat la cuvintele cheie "public" și "privat", unde publicul - definește metodele publice ale clasei și privat - ascuns, care poate fi apelat numai din alte metode ale clasei.

Din acest exemplu, totul ar trebui să fie clar.

Metode singleton

Comportamentul specimenului este determinat de apartenența sa la o anumită clasă, dar uneori devine necesar să se atribuie un obiect unei anumite personalități specifice. În majoritatea limbajelor de programare, va trebui să creați o clasă separată pentru aceasta. Ruby vă permite, de asemenea, să adăugați o metodă specifică unui anumit exemplu (obiect) fără gesturi inutile.

În cazul în care t1 și t2 aparțin aceleiași clase și totuși, de exemplu, t2, dimensiunea metodei "este redefinită, oferind individualitatea sa. O astfel de metodă specifică se numește o metodă singleton.

Ca exemplu de aplicare a unei singure metode, puteți aduce butoanele în fereastra programului cu o interfață grafică, în care fiecare buton trebuie să își execute acțiunile făcând clic. Putem suprascrie metoda care măsoară apăsarea fiecăruia dintre butoanele disponibile.

Modulele din Ruby sunt foarte asemănătoare cu clasele, dar sunt folosite pentru a grupa clasele conexe într-un singur loc. Iată trei diferențe principale între modulele din clase:

  1. Modulele nu au instanțe de module.
  2. Modulele nu pot avea module copii.
  3. Modulele sunt definite de modul. end.

Aproximativ, există două motive principale pentru utilizarea modulelor. Primul este de a colecta metode și constante într-un singur loc. De exemplu:

Operatorul. "indică faptul că constanta este definită în modulul sau clasa corespunzătoare. Pentru a accesa metode sau constante în mod direct,

Un alt motiv este modulul "mixin". Semnificația acestui termen este destul de complexă pentru înțelegere, așadar să ne ocupăm mai mult de el.

Unele limbi orientate pe obiecte permit moștenire din mai multe clase de părinți, această posibilitate se numește moștenire multiplă. Ruby este privat în mod deliberat de această ocazie. În schimb, permite amestecarea cu modulul.

După cum sa menționat mai sus, modulul seamănă mult cu o clasă. Metodele sau constantele dintr-un modul nu pot fi moștenite, dar pot fi adăugate la alte module sau clase utilizând directiva include. Astfel, conectarea modulului la definiție adaugă (îmbină) proprietățile modulului cu proprietățile clasei sau modulului.

Modulele de amestecare pot fi văzute în biblioteca standard, în cazul în care, ca urmare a „amestec“ de module cu o clasă care are metode de fiecare „se întoarce fiecare element, acesta din urmă are la metodele sale de eliminare de sortare“, găsiți“, etc ..

Între mai multe moșteniri și "amestecare" există următoarele diferențe:

  • Un modul nu poate avea o instanță a unui modul, doar clasele abstracte au această caracteristică.
  • Modulul stochează relația instanțelor sub forma unui copac.

Aceste diferențe interzic relațiile complexe dintre clase, simplitatea este în centrul problemei. Din acest motiv, Ruby nu suportă mai multe moșteniri. În limbile care suportă mai multe moșteniri, ar putea fi o situație în care clasele au mai mulți strămoși, iar relațiile dintre instanțele de clase creează o rețea complicată. Situația este prea complicată pentru creierul uman, cel puțin - pentru mine.

Pe de altă parte, confuzia reprezintă toate acestea, pur și simplu "o colecție de proprietăți specifice din tot ce a fost adăugat".

Chiar și în limbile cu moștenire multiplă, se consideră că este mai bine să se extindă clasele folosind confuzie, decât să se dezvolte relații complexe de moștenire. În Ruby, această idee a fost avansată în continuare, înlocuind ideea de moștenire multiplă.

Obiecte procedurale

Imaginați-vă că scrieți un program care procesează unele semnale. Familiar cu aceasta, va intelege intreaga farmec a transferului procedurii sub forma unui argument pentru metoda (care se ocupa cu procesarea semnalului).

Obiectele de procedură sunt create utilizând metoda built-in proc. Codul executabil este scris în paranteze curbate. Apelul la execuție se face prin apelarea unui obiect procedural. Vezi mai jos:

Programatorii C vor găsi o asemănare între obiectele procedurale și indicatorii funcției.

concluzie

Această parte este finală din serie. Scopul seriei a fost de a oferi informațiile inițiale despre programare în Ruby. Acum sunt prea ocupat cu proiectul meu de diplomă de a aloca timp pentru un studiu mai aprofundat al lui Ruby. Dar în viitor, cât mai curând posibil, voi continua acest lucru.

Hiran Ramankutty

Sunt student al ultimului an al Colegiului Guvernamental de Informatică din Trichur, India. În plus față de Linux, sunt foarte încântat să studiez fizica.







Trimiteți-le prietenilor: