Menu
CoddyTech

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. Wird sie einer anderen Variable zugewiesen, wird die Referenz kopiert, sodass beide Namen dann auf dasselbe Objekt verweisen:

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, ob zwei Referenzen auf dasselbe Objekt verweisen, und object_id ist die eindeutige Nummer jedes Objekts. Bei deinen 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 ==, sodass sie dann auch gleiche Objekte finden. Prüfe zuerst die Klasse von other, damit der Vergleich mit einer Zahl oder nil false zurückgibt, anstatt einen Fehler auszulösen:

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. Wenn du der Kopie einen neuen Wert zuweist, bleibt das Original unverändert. Ein darin enthaltenes Array oder eine Zeichenkette wird jedoch weiterhin von beiden gemeinsam genutzt, da 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 allem anderen 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, speichert dann mithilfe von include? eine Liste verschiedener 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 kann nicht bearbeitet werden.

Probier es selbst

require_relative 'point'

# Vorgegebener Ein-/Ausgabecode: unverändert lassen
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