/** * Beispiel aus * * - Algorithmen und Datenstrukturen für Dummies * - von Andreas Gogol-Döring und Thomas Letschert * - Verlag Wiley-VCH; Oktober 2019 * - Kapitel 9, Mengen und ihre Speicherung * * @author A. Gogol-Döring, Th. Letschert */ import Foundation struct AuD_09_04_Equals02 { /* Bei einer finalen Klasse, die keine Case-Klasse ist, muss equals und hashCode definiert werden. * Etwa so: */ final class Rabbit_FinalClass: Equatable, Hashable { let name: String let weight: Int init (_ name: String, _ weight: Int) { self.name = name self.weight = weight } static func == (lhs: Rabbit_FinalClass, rhs: Rabbit_FinalClass) -> Bool { lhs.name == rhs.name && lhs.weight == rhs.weight } func hash(into hasher: inout Hasher) { hasher.combine(name) hasher.combine(weight) } } class Rabbit_Base: Equatable, Hashable { let name: String let weight: Int init (_ name: String, _ weight: Int) { self.name = name self.weight = weight } static func == (lhs: Rabbit_Base, rhs: Rabbit_Base) -> Bool { lhs.name == rhs.name && lhs.weight == rhs.weight } func hash(into hasher: inout Hasher) { hasher.combine(name) hasher.combine(weight) } } /* == ist statisch * kann darum nicht übeschrieben werden und es kommt beim Vergleich auf den statischen Typ * der beteiligten Objekte an. (Mit upcast auf den Typ des allgemeinsten der am Vergleich * Beteiligten. -- Das passt zwar zum Substitutiobsprinzip, aber gelegentlich will man * Vergleiche auf Subklassen aber verfeinern. * * Die Hash-Funktion kann (und muss) aber überschrieben werden. */ class Rabbit_Champion: Rabbit_Base { var prizes: Int init (_ name: String, _ weight: Int, _ prizes: Int) { self.prizes = prizes super.init(name, weight) } static func == (lhs: Rabbit_Champion, rhs: Rabbit_Champion) -> Bool { lhs.name == rhs.name && lhs.weight == rhs.weight && lhs.prizes == rhs.prizes } override func hash(into hasher: inout Hasher) { hasher.combine(name) hasher.combine(weight) hasher.combine(prizes) } } static func run() { let rb1: Rabbit_Base = Rabbit_Base("Hugo", 5) let rb2: Rabbit_Base = Rabbit_Champion("Hugo", 5, 1) print ("rb1 == rb2 : \(rb1 == rb2)") // true, OK == kann nicht überschrieben werden, das passt zum Substitutionsprinzip print("rb1.hashValue == rc1.hashValue : \(rb1.hashValue == rb2.hashValue)") // false, Ups_ Gleiches hat unterschiedlichen Hashcode ! } }