Menu
Coddy logo textTech

Identität und Gleichheit

Teil des Abschnitts Objektorientierte Programmierung der Ruby-Journey von Coddy. Lektion 10 von 57.

Eine Variable enthält eine Referenz auf ein Objekt, nicht das Objekt selbst. Wenn du sie einer anderen Variable zuweist, wird die Referenz kopiert, sodass sich beide Namen anschließend auf dasselbe Objekt beziehen:

class Box
  attr_accessor :count

  def initialize
    @count = 0
  end
end

a = Box.new
b = a
b.count += 1
puts a.count

Ausgabe:

1

equal? fragt ab, ob zwei Referenzen auf dasselbe Objekt zeigen, und object_id ist die eindeutige Nummer jedes Objekts. Für deine eigenen Klassen macht == standardmäßig dasselbe, daher sind zwei Objekte mit denselben Werten nicht gleich:

class Point
  attr_reader :x, :y

  def initialize(x, y)
    @x = x
    @y = y
  end
end

a = Point.new(1, 2)
b = Point.new(1, 2)
c = a
puts a == b
puts a.equal?(b)
puts a.equal?(c)
puts a.object_id == c.object_id

Ausgabe:

false
false
true
true

Definiere ==, um nach Wert zu vergleichen. include?, index und delete bei Arrays verwenden ==, daher finden sie dann auch gleiche Objekte. Überprüfe zuerst die Klasse von other, damit der Vergleich mit einer Zahl oder nil false zurückgibt, anstatt einen Fehler zu verursachen:

class Point
  attr_reader :x, :y

  def initialize(x, y)
    @x = x
    @y = y
  end

  def ==(other)
    other.is_a?(Point) && x == other.x && y == other.y
  end
end

a = Point.new(1, 2)
puts a == Point.new(1, 2)
puts a == 5
puts [Point.new(0, 0), Point.new(1, 2)].include?(a)
puts a.equal?(Point.new(1, 2))

Ausgabe:

true
false
true
false

dup erstellt ein neues Objekt mit Kopien der Instanzvariablen. Das Zuweisen eines neuen Werts in der Kopie lässt das Original unverändert, aber ein darin enthaltenes Array oder ein darin enthaltener String wird weiterhin zwischen den beiden geteilt, weil nur die Referenz kopiert wurde:

class Team
  attr_accessor :name, :players

  def initialize(name)
    @name = name
    @players = []
  end
end

a = Team.new("Reds")
b = a.dup
b.name = "Blues"
b.players << "Ada"
puts a.name
p a.players

Ausgabe:

Reds
["Ada"]
challenge icon

Aufgabe

Einfach

Vervollständige die Klasse Point, sodass zwei Punkte mit denselben Koordinaten mit == gleich sind und der Vergleich eines Punkts mit irgendetwas anderem false zurückgibt. to_s gibt (1, 2) zurück.

Der bereitgestellte Code liest Punkte als Zeilen im Format x,y ein. Für jeden Punkt gibt er (1, 2) same as first: true oder false aus. Anschließend erstellt er mithilfe von include? eine Liste unterschiedlicher Punkte und gibt schließlich distinct: 3 sowie aus, ob der erste Punkt dem Text "1,2" entspricht.

Dein Code gehört in point.rb. main.rb enthält den bereitgestellten Eingabe-/Ausgabecode und darf nicht bearbeitet werden.

Probier es selbst

require_relative 'point'

# Bereitgestellter Ein-/Ausgabe-Code: belasse ihn wie er ist
input = []
while (line = gets)
  input << line.chomp
end
points = input.map { |line| Point.new(*line.split(",").map(&:to_i)) }
points.each { |pt| puts "#{pt} same as first: #{pt == points[0]}" }
distinct = []
points.each { |pt| distinct << pt unless distinct.include?(pt) }
puts "distinct: #{distinct.size}"
puts "equals text: #{points[0] == input[0]}"
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-Ruby-Compiler