Zoeken…


Syntaxis

  • naam van de klasse
  • # enkele code die het gedrag van de klas beschrijft
  • einde

Opmerkingen

Klassennamen in Ruby zijn constanten, dus de eerste letter moet een hoofdletter zijn.

class Cat # correct
end  

class dog # wrong, throws an error
end

Een klas maken

U kunt een nieuwe klasse definiëren met behulp van het trefwoord class .

class MyClass
end

Eenmaal gedefinieerd, kunt u een nieuw exemplaar maken met behulp van de .new methode

somevar = MyClass.new
# => #<MyClass:0x007fe2b8aa4a18>

bouwer

Een klasse kan slechts één constructor hebben, dat is een methode die initialize wordt genoemd. De methode wordt automatisch aangeroepen wanneer een nieuwe instantie van de klasse wordt gemaakt.

class Customer
  def initialize(name)
     @name = name.capitalize 
  end
end

sarah = Customer.new('sarah')
sarah.name #=> 'Sarah'

Klasse- en instantievariabelen

Er zijn verschillende speciale variabeletypen die een klasse kan gebruiken om gegevens gemakkelijker te delen.

Instantievariabelen, voorafgegaan door @ . Ze zijn handig als u dezelfde variabele op verschillende manieren wilt gebruiken.

class Person
  def initialize(name, age)
    my_age = age # local variable, will be destroyed at end of constructor
    @name = name # instance variable, is only destroyed when the object is
  end

  def some_method
    puts "My name is #{@name}." # we can use @name with no problem
  end
   
  def another_method
    puts "My age is #{my_age}." # this will not work!
  end
end

mhmd = Person.new("Mark", 23)

mhmd.some_method #=> My name is Mark.
mhmd.another_method #=> throws an error

Klasse variabele, voorafgegaan door @@ . Ze bevatten dezelfde waarden voor alle instanties van een klasse.

class Person
  @@persons_created = 0 # class variable, available to all objects of this class
  def initialize(name)
    @name = name

    # modification of class variable persists across all objects of this class
    @@persons_created += 1
  end  
      
  def how_many_persons
    puts "persons created so far: #{@@persons_created}"
  end 
end
    
mark = Person.new("Mark")
mark.how_many_persons #=> persons created so far: 1
helen = Person.new("Helen")

mark.how_many_persons #=> persons created so far: 2
helen.how_many_persons #=> persons created so far: 2
# you could either ask mark or helen

Globale variabelen, voorafgegaan door $ . Deze zijn overal beschikbaar voor het programma, dus zorg ervoor dat u ze verstandig gebruikt.

$total_animals = 0

class Cat
  def initialize
    $total_animals += 1
  end
end

class Dog
  def initialize
    $total_animals += 1
  end
end

bob = Cat.new()
puts $total_animals #=> 1
fred = Dog.new()
puts $total_animals #=> 2

Toegang krijgen tot instantievariabelen met getters en setters

We hebben drie methoden:

  1. attr_reader : wordt gebruikt om het read van de variabele buiten de klasse toe te staan.
  2. attr_writer : wordt gebruikt om de variabele buiten de klasse aan te passen.
  3. attr_accessor : combineert beide methoden.
class Cat
  attr_reader :age # you can read the age but you can never change it
  attr_writer :name # you can change name but you are not allowed to read
  attr_accessor :breed # you can both change the breed and read it

  def initialize(name, breed)
    @name = name
    @breed = breed
    @age = 2 
  end
  def speak
    puts "I'm #{@name} and I am a #{@breed} cat"
  end
end
 
my_cat = Cat.new("Banjo", "birman")
# reading values:

my_cat.age  #=> 2
my_cat.breed #=> "birman"
my_cat.name #=> Error

# changing values
 
my_cat.age = 3 #=> Error
my_cat.breed = "sphynx" 
my_cat.name = "Bilbo"

my_cat.speak #=> I'm Bilbo and I am a sphynx cat

Merk op dat de parameters symbolen zijn. dit werkt door een methode te maken.

class Cat
  attr_accessor :breed
end

Is in principe hetzelfde als:

class Cat
  def breed
    @breed
  end
  def breed= value
    @breed = value
  end
end

Toegangsniveaus

Ruby heeft drie toegangsniveaus. Ze zijn public , private en protected .

Methoden die de private of protected sleutelwoorden volgen, zijn als zodanig gedefinieerd. Methoden die hieraan vooraf gaan, zijn impliciet public methoden.

Publieke methoden

Een openbare methode moet het gedrag beschrijven van het object dat wordt gemaakt. Deze methoden kunnen buiten het bereik van het gemaakte object worden aangeroepen.

class Cat
  def initialize(name)
    @name = name
  end

  def speak
    puts "I'm #{@name} and I'm 2 years old"
  end
  
  ...
end

new_cat = Cat.new("garfield")
#=> <Cat:0x2321868 @name="garfield">
 
new_cat.speak
#=> I'm garfield and I'm 2 years old

Deze methoden zijn openbare robijnrode methoden, ze beschrijven het gedrag voor het initialiseren van een nieuwe kat en het gedrag van de spreekmethode.

public trefwoord is niet nodig, maar kan worden gebruikt om private of protected te ontsnappen

def MyClass
  def first_public_method
  end

  private

  def private_method
  end

  public

  def second_public_method
  end
end

Privé methoden

Privémethoden zijn niet toegankelijk van buiten het object. Ze worden intern door het object gebruikt. Gebruik opnieuw het kattenvoorbeeld:

class Cat
  def initialize(name)
    @name = name
  end

  def speak
    age = calculate_cat_age # here we call the private method 
    puts "I'm #{@name} and I'm #{age} years old"
  end

  private
     def calculate_cat_age
       2 * 3 - 4 
     end
end

my_cat = Cat.new("Bilbo")
my_cat.speak #=> I'm Bilbo and I'm 2 years old
my_cat.calculate_cat_age #=> NoMethodError: private method `calculate_cat_age' called for #<Cat:0x2321868 @name="Bilbo">

Zoals je hierboven kunt zien in het voorbeeld, de nieuw gecreëerde Cat object heeft toegang tot de calculate_cat_age methode intern. We wijzen de variabele age aan het resultaat van het uitvoeren van de methode private calculate_cat_age die de naam en leeftijd van de kat naar de console afdrukt.

Wanneer wij proberen en bel de calculate_cat_age methode van buiten de my_cat object, krijgen we een NoMethodError want het is privé. Snap je?

Beschermde methoden

Beschermde methoden lijken erg op privémethoden. Ze kunnen niet buiten de instantie van het object worden benaderd op dezelfde manier als privémethoden niet kunnen zijn. Met de self ruby-methode kunnen beschermde methoden echter worden aangeroepen in de context van een object van hetzelfde type.

class Cat
  def initialize(name, age)
    @name = name
    @age = age
  end

  def speak
    puts "I'm #{@name} and I'm #{@age} years old"
  end

  # this == method allows us to compare two objects own ages. 
  # if both Cat's have the same age they will be considered equal.
  def ==(other)
     self.own_age == other.own_age
  end

  protected
     def own_age
        self.age
     end
end

cat1 = Cat.new("ricky", 2)
=> #<Cat:0x007fe2b8aa4a18 @name="ricky", @age=2>

cat2 = Cat.new("lucy", 4)
=> #<Cat:0x008gfb7aa6v67 @name="lucy", @age=4>

cat3 = Cat.new("felix", 2)
=> #<Cat:0x009frbaa8V76 @name="felix", @age=2>

Je kunt zien dat we een leeftijdsparameter aan de kattenklasse hebben toegevoegd en drie nieuwe kattenobjecten met de naam en leeftijd hebben gemaakt. We gaan de methode met own_age gebruiken om de leeftijd van onze own_age te vergelijken.

cat1 == cat2
=> false

cat1 == cat3
=> true

Kijk eens, we waren in staat om de leeftijd van self.own_age op te halen met behulp van de self.own_age beschermde methode en deze te vergelijken met de leeftijd van cat2.own_age door cat2.own_age aan te roepen binnen cat2.own_age .

Typen klassenmethoden

Klassen hebben 3 soorten methoden: instantie, singleton en klassenmethoden.

Instantiemethoden

Dit zijn methoden die kunnen worden aangeroepen vanuit een instance van de klasse.

class Thing
  def somemethod
    puts "something"
  end
end

foo = Thing.new # create an instance of the class
foo.somemethod # => something

Klasse methode

Dit zijn statische methoden, dat wil zeggen dat ze op de klasse kunnen worden aangeroepen, en niet op een instantie van die klasse.

class Thing
  def Thing.hello(name)
    puts "Hello, #{name}!"
  end
end

Het is gelijk aan self in plaats van de klassennaam. De volgende code is gelijk aan de bovenstaande code:

class Thing
  def self.hello(name)
    puts "Hello, #{name}!"
  end
end

Roep de methode op door te schrijven

Thing.hello("John Doe")  # prints: "Hello, John Doe!"

Singleton-methoden

Deze zijn alleen beschikbaar voor specifieke instanties van de klasse, maar niet voor iedereen.

# create an empty class
class Thing
end

# two instances of the class
thing1 = Thing.new
thing2 = Thing.new

# create a singleton method
def thing1.makestuff
  puts "I belong to thing one"
end

thing1.makestuff # => prints: I belong to thing one
thing2.makestuff # NoMethodError: undefined method `makestuff' for #<Thing>

Zowel de singleton als de class methode worden eigenclass es genoemd. Kortom, wat ruby doet, is het creëren van een anonieme klasse die dergelijke methoden bevat, zodat het de instanties die worden gemaakt niet verstoort.

Een andere manier om dit te doen is door de constructeur class << . Bijvoorbeeld:

# a class method (same as the above example)
class Thing
  class << self # the anonymous class
    def hello(name)
      puts "Hello, #{name}!"
    end
  end
end

Thing.hello("sarah") # => Hello, sarah!

# singleton method

class Thing
end

thing1 = Thing.new

class << thing1
  def makestuff
    puts "I belong to thing one"
  end
end

thing1.makestuff # => prints: "I belong to thing one"

Creëren van dynamische klassen

Klassen kunnen dynamisch worden aangemaakt door Class.new .

# create a new class dynamically
MyClass = Class.new

# instantiate an object of type MyClass
my_class = MyClass.new

In het bovenstaande voorbeeld wordt een nieuwe klasse gemaakt en toegewezen aan de constante MyClass . Deze klasse kan worden geïnstantieerd en gebruikt zoals elke andere klasse.

De methode Class.new accepteert een Class die de superklasse van de dynamisch gecreëerde klasse wordt.

# dynamically create a class that subclasses another
Staffy = Class.new(Dog)

# instantiate an object of type Staffy
lucky = Staffy.new
lucky.is_a?(Staffy) # true
lucky.is_a?(Dog)    # true

De methode Class.new accepteert ook een blok. De context van het blok is de nieuw gecreëerde klasse. Hiermee kunnen methoden worden gedefinieerd.

Duck = 
  Class.new do
    def quack
      'Quack!!'
    end
  end

# instantiate an object of type Duck
duck = Duck.new
duck.quack # 'Quack!!'

Nieuw, toewijzen en initialiseren

In veel talen worden nieuwe exemplaren van een klasse gemaakt met een speciaal new trefwoord. In Ruby wordt new ook gebruikt om instanties van een klasse te maken, maar het is geen trefwoord; in plaats daarvan is het een statische / klassenmethode, niet anders dan andere statische / klassenmethoden. De definitie is ruwweg deze:

class MyClass
   def self.new(*args)
     obj = allocate
     obj.initialize(*args) # oversimplied; initialize is actually private
     obj
   end
end

allocate voert de echte 'magie' uit van het creëren van een niet-geïnitialiseerde instantie van de klasse

Merk ook op dat de retourwaarde van initialize wordt genegeerd en in plaats daarvan obj wordt geretourneerd. Dit maakt meteen duidelijk waarom u uw initialisatiemethode kunt coderen zonder dat u zich zorgen hoeft te maken dat u self aan het einde terugkeert.

De 'normale' new methode die alle klassen uit Class werkt zoals hierboven, maar het is mogelijk om het opnieuw te definiëren zoals u wilt, of om alternatieven te definiëren die anders werken. Bijvoorbeeld:

class MyClass
  def self.extraNew(*args)
    obj = allocate
    obj.pre_initialize(:foo)
    obj.initialize(*args)
    obj.post_initialize(:bar)
    obj
  end
end


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow