de Nishant Mishra
Conţinut
- 1 O introducere în programarea orientată pe obiecte cu Ruby
O introducere în programarea orientată pe obiecte cu Ruby

În calitate de student la informatică, petrec mult timp învățând și jucându-mă cu limbi noi. Fiecare limbă nouă are ceva unic de oferit. Acestea fiind spuse, majoritatea începătorilor își încep călătoria de programare fie cu limbaje procedurale, cum ar fi C, fie cu limbaje orientate obiect, cum ar fi JavaScript și C ++.
Prin urmare, este logic să parcurgeți elementele de bază ale programării orientate pe obiecte, astfel încât să puteți înțelege conceptele și să le aplicați limbajelor pe care le învățați cu ușurință. Vom folosi limbajul de programare Ruby ca exemplu.
Poate te întrebi, de ce Ruby? Pentru că este „conceput pentru a face fericiți programatorii” și, de asemenea, pentru că aproape totul în Ruby este un obiect.
Obținerea unui sentiment al paradigmei orientate pe obiecte (OOP)
În POO, identificăm „lucrurile” pe care le gestionează programul nostru. Ca oameni, ne gândim la lucruri ca la obiecte cu atribute și comportamente și interacționăm cu lucruri pe baza acestor atribute și comportamente. Un lucru poate fi o mașină, o carte și așa mai departe. Astfel de lucruri devin clase (planurile obiectelor), iar noi creăm obiecte din aceste clase.
Fiecare instanță (obiect) conține variabile de instanță care sunt starea obiectului (atribute). Comportamentele obiectelor sunt reprezentate prin metode.
Să luăm exemplul unei mașini. O mașină este un lucru care ar face din ea o clasă. Un tip specific de mașină, spunem că BMW este un obiect din clasa Mașină. atribute / proprietăți unui BMW, cum ar fi culoarea și numărul modelului, pot fi stocate în variabile de instanță. Și dacă doriți să efectuați o operație a obiectului, cum ar fi conducerea, atunci „conduce” descrie un comportament care este definit ca un metodă.
O lecție rapidă de sintaxă
- Pentru a termina o linie într-un program Ruby, un punct și virgulă (;) este opțional (dar în general nu este utilizat)
- Indentarea cu 2 spații pentru fiecare nivel imbricat este încurajată (nu este necesară, așa cum este în Python)
- Fără acolade
{}
sunt utilizate, iar Sfârșit cuvântul cheie este folosit pentru a marca sfârșitul unui bloc de control al fluxului - Pentru a comenta, folosim
#
simbol
Modul în care obiectele sunt create în Ruby este prin apelarea unui nou metoda pe o clasă, ca în exemplul de mai jos:
class Car def initialize(name, color) @name = name @color = color end
def get_info "Name: #{@name}, and Color: #{@color}" endend
my_car = Car.new("Fiat", "Red")puts my_car.get_info
Pentru a înțelege ce se întâmplă în codul de mai sus:
- Avem o clasă numită
Car
cu două metode,initialize
șiget_info
. - Variabilele de instanță din Ruby încep cu
@
(De exemplu@name
). Partea interesantă este că variabilele nu sunt declarate inițial. Ele apar în existență atunci când sunt utilizate pentru prima dată și apoi sunt disponibile pentru toate metodele de instanță ale clasei. - Apelarea la
new
metoda cauzeazăinitialize
metodă de invocare.initialize
este o metodă specială care este utilizată ca constructor.
Accesarea datelor
Variabilele de instanță sunt private și nu pot fi accesate din afara clasei. Pentru a le accesa, trebuie să creăm metode. Metodele de instanță au acces public în mod implicit. Putem limita accesul la aceste metode de instanță, așa cum vom vedea mai târziu în acest articol.
Pentru a obține și modifica datele, avem nevoie de metode „getter” și respectiv „setter”. Să ne uităm la aceste metode luând același exemplu de mașină.
class Car def initialize(name, color) # "Constructor" @name = name @color = color end
def color @color end
def color= (new_color) @color = new_color endend
my_car = Car.new("Fiat", "Red")puts my_car.color # Red
my_car.color = "White"puts my_car.color # White
În Ruby, „getter” și „setter” sunt definite cu același nume ca variabila de instanță cu care avem de-a face.
În exemplul de mai sus, când spunem my_car.color
, apelează de fapt color
metoda care la rândul său returnează numele culorii.
Notă: Acordați atenție modului în care Ruby permite un spațiu între color
și este egal cu semnarea în timp ce utilizați setterul, chiar dacă numele metodei este color=
Scrierea acestor metode getter / setter ne permite să avem mai mult control. Dar, de cele mai multe ori, obținerea valorii existente și setarea unei noi valori este simplă. Deci, ar trebui să existe o modalitate mai ușoară în loc să definiți de fapt metodele getter / setter.
Modul mai ușor
Prin utilizarea attr_*
în schimb, putem obține valoarea existentă și putem seta o nouă valoare.
-
attr_accessor
: pentru getter și setter atât -
attr_reader
: doar pentru getter -
attr_writer
: doar pentru setter
Să ne uităm la această formă luând același exemplu de mașină.
class Car attr_accessor :name, :colorend
car1 = Car.newputs car1.name # => nil
car1.name = "Suzuki"car1.color = "Gray"puts car1.color # => Gray
car1.name = "Fiat"puts car1.name # => Fiat
În acest fel putem sări peste definițiile getter / setter.
Vorbind despre cele mai bune practici
În exemplul de mai sus, nu am inițializat valorile pentru @name
și @color
variabile de instanță, ceea ce nu este o bună practică. De asemenea, deoarece variabilele de instanță sunt setate la zero, obiectul car1
nu are niciun sens. Este întotdeauna o practică bună să setați variabile de instanță folosind un constructor, ca în exemplul de mai jos.
class Car attr_accessor :name, :color def initialize(name, color) @name = name @color = color endend
car1 = Car.new("Suzuki", "Gray")puts car1.color # => Gray
car1.name = "Fiat"puts car1.name # => Fiat
Metode de clasă și variabile de clasă
Deci metodele de clasă sunt invocate pe o clasă, nu pe o instanță a unei clase. Acestea sunt similare cu static metode în Java.
Notă: self
în afara definiției metodei se referă la obiectul clasei. Variabilele de clasă încep cu @@
Acum, există de fapt trei moduri de a defini metodele de clasă în Ruby:
În interiorul definiției clasei
- Folosind cuvântul cheie self cu numele metodei:
class MathFunctions def self.two_times(num) num * 2 endend
# No instance createdputs MathFunctions.two_times(10) # => 20
2. Folosind <<
; de sine
class MathFunctions class << self def two_times(num) num * 2 end endend
# No instance createdputs MathFunctions.two_times(10) # => 20
În afara definiției clasei
3. Utilizarea numelui clasei cu numele metodei
class MathFunctionsend
def MathFunctions.two_times(num) num * 2end
# No instance createdputs MathFunctions.two_times(10) # => 20
Moștenirea clasei
În Ruby, fiecare clasă moștenește implicit din clasa Object. Să vedem un exemplu.
class Car def to_s "Car" end
def speed "Top speed 100" endend
class SuperCar < Car def speed # Override "Top speed 200" endend
car = Car.newfast_car = SuperCar.new
puts "#{car}1 #{car.speed}" # => Car1 Top speed 100puts "#{fast_car}2 #{fast_car.speed}" # => Car2 Top speed 200
În exemplul de mai sus, SuperCar
clasa suprascrie speed
metoda care este moștenită de la Car
clasă. Simbolul &
lt; denotă moștenire.
Notă: Ruby nu acceptă moștenirea multiplă, astfel încât sunt utilizate în schimb mix-in-uri. Le vom discuta mai târziu în acest articol.
Module în Ruby
Un modul Ruby este o parte importantă a limbajului de programare Ruby. Este o caracteristică majoră a limbajului orientată spre obiecte și acceptă moștenirea multiplă indirect.
Un modul este un container pentru clase, metode, constante sau chiar alte module. La fel ca o clasă, un modul nu poate fi instanțiat, dar are două scopuri principale:
- Spațiu de nume
- Mix-in
Module ca spațiu de nume
O mulțime de limbaje precum Java au ideea structurii pachetelor, doar pentru a evita coliziunea între două clase. Să analizăm un exemplu pentru a înțelege cum funcționează.
module Patterns class Match attr_accessor :matched endend
module Sports class Match attr_accessor :score endend
match1 = Patterns::Match.newmatch1.matched = "true"
match2 = Sports::Match.newmatch2.score = 210
În exemplul de mai sus, așa cum avem două clase numite Match
, putem diferenția între ele și preveni coliziunea prin simpla încapsulare a acestora în diferite module.
Module ca Mix-in
În paradigma orientată obiect, avem conceptul de interfețe. Mix-in oferă o modalitate de a partaja codul între mai multe clase. Nu numai asta, putem include și module încorporate precum Enumerable
și ușurează-ne sarcina. Să vedem un exemplu.
module PrintName attr_accessor :name def print_it puts "Name: #{@name}" endend
class Person include PrintNameend
class Organization include PrintNameend
person = Person.newperson.name = "Nishant"puts person.print_it # => Name: Nishant
organization = Organization.neworganization.name = "Routech"puts organization.print_it # => Name: Routech
Mix-urile sunt extrem de puternice, deoarece scriem codul o singură dată și apoi le putem include oriunde, după cum este necesar.
Domeniul de aplicare în Ruby
Vom vedea cum funcționează domeniul de aplicare pentru:
- variabile
- constante
- blocuri
Domeniul de aplicare al variabilelor
Metodele și clasele definesc un nou domeniu de aplicare pentru variabile, iar variabilele de domeniu extern nu sunt reportate în domeniul de aplicare interior. Să vedem ce înseamnă asta.
name = "Nishant"
class MyClass def my_fun name = "John" puts name # => John end
puts name # => Nishant
Exterior name
variabil și interior name
variabile nu sunt aceleași. Exterior name
variabila nu este transferată la domeniul interior. Asta înseamnă că, dacă încercați să-l imprimați în sfera interioară fără a o defini din nou, ar fi aruncată o excepție – nu există o astfel de variabilă
Domeniul de aplicare al constantelor
Un domeniu interior poate vedea constante definite în domeniul exterior și poate, de asemenea, să le suprascrie constantele exterioare. Dar este important să ne amintim că, chiar și după înlocuirea valorii constante din domeniul interior, valoarea din domeniul exterior rămâne neschimbată. Să o vedem în acțiune.
module MyModule PI = 3.14 class MyClass def value_of_pi puts PI # => 3.14 PI = "3.144444" puts PI # => 3.144444 end end puts PI # => 3.14end
Domeniul de aplicare al blocurilor
Blocurile moștenesc domeniul de aplicare exterior. Să o înțelegem folosind un exemplu fantastic pe care l-am găsit pe internet.
class BankAccount attr_accessor :id, :amount def initialize(id, amount) @id = id @amount = amount endend
acct1 = BankAccount.new(213, 300)acct2 = BankAccount.new(22, 100)acct3 = BankAccount.new(222, 500)
accts = [acct1, acct2, acct3]
total_sum = 0accts.each do |eachAcct| total_sum = total_sum + eachAcct.amountend
puts total_sum # => 900
În exemplul de mai sus, dacă folosim o metodă pentru a calcula total_sum
, total_sum
variabila ar fi o variabilă total diferită în interiorul metodei. De aceea, uneori, folosirea blocurilor ne poate economisi mult timp.
Acestea fiind spuse, o variabilă creată în interiorul blocului este disponibilă numai pentru bloc.
Controlul accesului
Când proiectați o clasă, este important să vă gândiți cât de mult din ea veți expune lumii. Acest lucru este cunoscut sub numele de Incapsulare, și de obicei înseamnă ascunderea reprezentării interne a obiectului.
Există trei niveluri de control al accesului în Ruby:
- Public – nu se impune controlul accesului. Oricine poate apela la aceste metode.
- Protejat – poate fi invocat de obiecte ale claselor definitorii sau ale subclaselor sale.
- Privat – nu poate fi invocat decât cu un receptor explicit.
Să vedem un exemplu de încapsulare în acțiune:
class Car def initialize(speed, fuel_eco) @rating = speed * comfort end
def rating @rating endend
puts Car.new(100, 5).rating # => 500
Acum, întrucât detaliile despre modul în care este calculată evaluarea sunt păstrate în cadrul clasei, o putem schimba în orice moment, fără nicio altă modificare. De asemenea, nu putem seta ratingul din exterior.
Vorbind despre modalitățile de specificare a controlului accesului, există două dintre acestea:
- Specificarea publică, protejată sau privată și totul până la următorul cuvânt cheie control acces va avea acel nivel de control acces.
- Definiți metoda în mod regulat, apoi specificați nivelurile de acces publice, private și protejate și enumerați metodele separate prin virgulă (,) sub acele niveluri folosind simbolurile metodei.
Exemplu de prima cale:
class MyClass private def func1 "private" end protected def func2 "protected" end public def func3 "Public" endend
Exemplu de a doua cale:
class MyClass def func1 "private" end def func2 "protected" end def func3 "Public" end private :func1 protected :func2 public :func3end
Notă: se utilizează cel mai mult controalele de acces public și privat.
Concluzie
Acestea sunt elementele de bază ale programării orientate pe obiecte în Ruby. Acum, cunoscând aceste concepte, puteți merge mai adânc și le puteți învăța construind lucruri interesante.
Nu uitați să bateți din palme și să urmăriți dacă v-a plăcut! Ține pasul cu mine Aici.
#introducere #în #programarea #orientată #obiecte #Ruby
O introducere în programarea orientată pe obiecte cu Ruby