Tożsamość i równość
Część sekcji Programowanie obiektowe ścieżki Ruby w Coddy. Lekcja 10 z 57.
Zmienna przechowuje referencję do obiektu, a nie sam obiekt. Przypisanie jej do innej zmiennej kopiuje referencję, więc obie nazwy odnoszą się wtedy do tego samego obiektu:
class Box
attr_accessor :count
def initialize
@count = 0
end
end
a = Box.new
b = a
b.count += 1
puts a.countWynik:
1equal? sprawdza, czy dwa odwołania wskazują na ten sam obiekt, a object_id to unikalny numer każdego obiektu. W przypadku własnych klas == domyślnie działa tak samo, więc dwa obiekty o tych samych wartościach nie są równe:
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_idWynik:
false
false
true
trueZdefiniuj ==, aby porównywać wartości. Metody include?, index i delete dla tablic używają ==, więc znajdują też równe obiekty. Najpierw sprawdź klasę other, aby porównanie z liczbą lub nil zwracało false zamiast powodować błąd:
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))Wynik:
true
false
true
falsedup tworzy nowy obiekt z kopiami zmiennych instancji. Przypisanie nowej wartości w kopii nie zmienia oryginału, ale tablica lub ciąg znaków znajdujący się wewnątrz nadal jest współdzielony przez oba obiekty, ponieważ skopiowane zostało tylko odwołanie:
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.playersWynik:
Reds
["Ada"]Wyzwanie
ŁatwyUzupełnij klasę Point, aby dwa punkty o tych samych współrzędnych były równe przy użyciu ==, a porównanie punktu z czymkolwiek innym zwracało false. to_s zwraca (1, 2).
Dostarczony kod odczytuje punkty z wierszy w formacie x,y. Dla każdego punktu wypisuje (1, 2) same as first: true lub false, następnie tworzy listę różnych punktów przy użyciu include?, a na końcu wypisuje distinct: 3 i informację, czy pierwszy punkt jest równy tekstowi "1,2".
Twój kod umieść w pliku point.rb. Plik main.rb zawiera dostarczony kod wejścia/wyjścia i nie można go edytować.
Spróbuj swoich sił
require_relative 'point'
# Dostarczony kod wejścia/wyjścia: pozostaw go bez zmian
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]}"
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Klasy i obiekty
Praca z plikamiDefiniowanie klasZmienne instancjiMetody i selfto_s i inspectPowtórzenie – karta biblioteczna4Hermetyzacja
Metody prywatneMetody chronionePrywatne setteryOchrona stanuPowtórzenie – automat vendingowy7Polimorfizm i typowanie kacze
PolimorfizmTypowanie kaczeMetody abstrakcyjnecase i klasyPowtórzenie – metody płatności10Wzorce projektowe, część 2
Delegowanie z ForwardableWzorzec dekoratoraWzorzec budowniczegoWzorzec stanu2Metody dostępowe i self
Gettery i setteryWłasne setteryself w metodachTożsamość i równośćPowtórzenie – lista kontaktów5Dziedziczenie
PodklasyNadpisywanie metodWywoływanie superis_a? i przodkowiePowtórka – lista płac pracowników8Metody specjalne
Równość i hashMetody operatorówIndeksowanie i dodawanieWłasne kolekcjePowtórka – ułamki11Projekt: Zarządzanie biblioteką
Książki i czytelnicyWypożyczanie książekPoćwicz samodzielnie: Kompilator Ruby online