Suche…


Syntax

  • Klassenname
  • #einiger Code, der das Klassenverhalten beschreibt
  • Ende

Bemerkungen

Klassennamen in Ruby sind Konstanten, daher sollte der erste Buchstabe ein Großbuchstabe sein.

class Cat # correct
end  

class dog # wrong, throws an error
end

Eine Klasse erstellen

Sie können eine neue Klasse mit dem Schlüsselwort class .

class MyClass
end

Nach der Definition können Sie eine neue Instanz mit der .new Methode .new

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

Konstrukteur

Eine Klasse kann nur einen Konstruktor haben, dh eine Methode namens initialize . Die Methode wird automatisch aufgerufen, wenn eine neue Instanz der Klasse erstellt wird.

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

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

Klassen- und Instanzvariablen

Es gibt verschiedene spezielle Variablentypen, mit denen eine Klasse Daten leichter austauschen kann.

Instanzvariablen mit vorangestelltem @ . Sie sind nützlich, wenn Sie dieselbe Variable in verschiedenen Methoden verwenden möchten.

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

Klassenvariable, vorangestellt mit @@ . Sie enthalten in allen Instanzen einer Klasse die gleichen Werte.

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 Variablen, denen $ vorangestellt ist. Diese stehen überall im Programm zur Verfügung, stellen Sie also sicher, dass Sie diese sinnvoll einsetzen.

$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

Zugriff auf Instanzvariablen mit Gettern und Setters

Wir haben drei Methoden:

  1. attr_reader : attr_reader das read der Variablen außerhalb der Klasse.
  2. attr_writer : attr_writer verwendet, um die Variable außerhalb der Klasse zu attr_writer .
  3. attr_accessor : kombiniert 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

Beachten Sie, dass die Parameter Symbole sind. Dies funktioniert durch Erstellen einer Methode.

class Cat
  attr_accessor :breed
end

Ist im Grunde dasselbe wie:

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

Zugriffsebenen

Ruby hat drei Zugriffsebenen. Sie sind public , private und protected .

Methoden, die den private oder protected Schlüsselwörtern folgen, sind als solche definiert. Methoden, die davor kommen, sind implizit public Methoden.

Öffentliche Methoden

Eine öffentliche Methode sollte das Verhalten des erstellten Objekts beschreiben. Diese Methoden können außerhalb des Bereichs des erstellten Objekts aufgerufen werden.

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

Diese Methoden sind öffentliche Ruby-Methoden. Sie beschreiben das Verhalten beim Initialisieren einer neuen Katze und das Verhalten der Speak-Methode.

public Schlüsselwort ist nicht erforderlich, kann jedoch zum protected private oder protected

def MyClass
  def first_public_method
  end

  private

  def private_method
  end

  public

  def second_public_method
  end
end

Private Methoden

Private Methoden sind nicht außerhalb des Objekts verfügbar. Sie werden intern vom Objekt verwendet. Wieder mit dem Katzenbeispiel:

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">

Wie Sie im obigen Beispiel sehen können, hat das neu erstellte Cat-Objekt intern Zugriff auf die Methode calculate_cat_age . Wir weisen die Variable age dem Ergebnis der Ausführung der privaten calculate_cat_age Methode zu, die den Namen und das Alter der Katze an die Konsole ausgibt.

Wenn wir versuchen, die calculate_cat_age Methode außerhalb des my_cat Objekts my_cat , erhalten wir einen NoMethodError da er privat ist. Kapiert?

Geschützte Methoden

Geschützte Methoden sind privaten Methoden sehr ähnlich. Sie können nicht auf dieselbe Weise wie private Methoden außerhalb der Instanz des Objekts aufgerufen werden. Mit der self Ruby-Methode können geschützte Methoden jedoch im Kontext eines Objekts desselben Typs aufgerufen werden.

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>

Sie können sehen, dass wir der Klasse cat einen Altersparameter hinzugefügt und drei neue Katzenobjekte mit Namen und Alter erstellt haben. Wir werden die own_age protected-Methode own_age , um das Alter unserer own_age zu vergleichen.

cat1 == cat2
=> false

cat1 == cat3
=> true

Sehen Sie sich das an, wir konnten das Alter von self.own_age mit der geschützten Methode self.own_age und mit dem Alter von cat2.own_age vergleichen, indem Sie cat2.own_age in cat1 aufrufen.

Klassenmethoden-Typen

Klassen haben drei Arten von Methoden: Instanz-, Singleton- und Klassenmethoden.

Instanzmethoden

Dies sind Methoden, die von einer instance der Klasse aus aufgerufen werden können.

class Thing
  def somemethod
    puts "something"
  end
end

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

Klassenmethode

Dies sind statische Methoden, dh sie können für die Klasse und nicht für eine Instanziierung dieser Klasse aufgerufen werden.

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

Es ist gleichbedeutend mit self anstelle des Klassennamens. Der folgende Code entspricht dem obigen Code:

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

Rufen Sie die Methode durch Schreiben auf

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

Singleton-Methoden

Diese stehen nur bestimmten Instanzen der Klasse zur Verfügung, jedoch nicht allen.

# 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>

Sowohl die singleton und class Methoden aufgerufen eigenclass es. Grundsätzlich ist das Erstellen von anonymen Klassen, die solche Methoden enthalten, so dass Ruby die erstellten Instanzen nicht beeinträchtigt.

Eine andere Möglichkeit dazu ist der Konstruktor der class << . Zum Beispiel:

# 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"

Dynamische Klassenerstellung

Klassen können durch die Verwendung von Class.new dynamisch erstellt werden.

# create a new class dynamically
MyClass = Class.new

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

Im obigen Beispiel wird eine neue Klasse erstellt und der Konstante MyClass zugewiesen. Diese Klasse kann wie jede andere Klasse instanziiert und verwendet werden.

Die Class.new Methode akzeptiert eine Class die zur Oberklasse der dynamisch erstellten Klasse wird.

# 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

Die Class.new Methode akzeptiert auch einen Block. Der Kontext des Blocks ist die neu erstellte Klasse. Dadurch können Methoden definiert werden.

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

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

Neu, zuteilen und initialisieren

In vielen Sprachen werden neue Instanzen einer Klasse mit einem speziellen new Schlüsselwort erstellt. In Ruby wird new auch zum Erstellen von Instanzen einer Klasse verwendet, es ist jedoch kein Schlüsselwort. Stattdessen handelt es sich um eine statische / Klassenmethode, die sich nicht von anderen statischen / Klassenmethoden unterscheidet. Die Definition ist ungefähr so:

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

allocate führt die eigentliche "Magie" der Erstellung einer nicht initialisierten Instanz der Klasse aus

Beachten Sie auch, dass der Rückgabewert von initialize verworfen wird und stattdessen obj zurückgegeben wird. Dadurch wird sofort klar, warum Sie Ihre initialize-Methode codieren können, ohne sich am Ende das self zu müssen.

Die 'normale' new Methode, die alle Klassen von Class funktioniert wie oben, aber es ist möglich, sie nach Belieben neu zu definieren oder Alternativen zu definieren, die anders funktionieren. Zum Beispiel:

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
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow