As I’ve said before, this doesn’t work. let x: Fruit = Apple(“a”, shape: .medium) let y: Fruit = Apple(“a”, shape: .big) print(x == y) // will print true
If you want == to behave differently for subclasses, it needs to call a method that can be overridden. Static overloads will not produce the same behavior. Jordan > On Sep 2, 2016, at 18:42, Zhao Xin via swift-users <swift-users@swift.org> > wrote: > > The key is how to write the `==` function. It should compare the` > dynamicType`(or `type(of:)` in Swift 3.0) if the class is not a final class. > > func ==(lhs: Fruit, rhs: Fruit) -> Bool { > > print(lhs.hashValue) > print(rhs.hashValue) > > return type(of:lhs) == type(of:rhs) && lhs.name == rhs.name > } > > func ==(lhs: Apple, rhs: Apple) -> Bool { > return type(of:lhs) == type(of:rhs) && lhs.name == rhs.name && lhs.shape > == rhs.shape > } > > func ==(lhs: Banana, rhs: Banana) -> Bool { > return type(of:lhs) == type(of:rhs) && lhs.name == rhs.name && lhs.shape > == rhs.shape > } > > > class Fruit:Hashable { > let name:String > > var hashValue: Int { > return 0 > } > > init(_ name:String = "common fruit") { > self.name = name > } > } > > enum FruitShape:Int { > case small = 1000 > case medium = 2000 > case big = 3000 > } > > class Apple:Fruit { > let shape:FruitShape > > override var hashValue: Int { > return 5 > } > > required init(_ name:String = "common fruit", shape:FruitShape = .medium) > { > self.shape = shape > super.init(name) > } > } > > class Banana:Fruit { > let shape:FruitShape > > override var hashValue: Int { > return 10 > } > > required init(_ name:String = "common fruit", shape:FruitShape = .medium) > { > self.shape = shape > super.init(name) > } > } > > let apple = Apple() > let banana = Banana() > > print(apple == banana) > /* > 5 > 10 > false > */ > > I got the idea from book "Core Java", mine is version 8, the latest is the > version 10. I learnt how to writing Object oriented code from it. I am glad > it is still useful. > > Zhaoxin > > On Sat, Sep 3, 2016 at 9:14 AM, Zhao Xin <owe...@gmail.com > <mailto:owe...@gmail.com>> wrote: > There is no reason to compare the shape, it is a constant in each of > these types. (So I am not sure what your point is.) > > Sorry. The `let shape` should be `var shape`. I just wanted to make the > subclass to be something more than the super class. > > If two values are equal, their hash values should be equal. As long > as your override implementation guarantees this, you can override > hashValue. > > But the question is how? If this must be guaranteed by the subclass, how to > writing the override? Or it just can't be done? > > You should also understand that the ==(Apple, Apple) and ==(Banana, > Banana) are not overrides for ==(Fruit, Fruit), and they would not be > called through dynamic dispatch when you have, for example, two apples > typed as fruits. > > In fact, in my example code, `apple` and `banana` is instance of `Apple` and > `Banana`. They are not using `let apple:Fruit = Apple()`. The `==` used the > `Fruit` version as it was the only appropriate one. My big question is, since > they used the `Fruit` version, and the `Fruit` version of `hashValue` could > guarantee the `hashValue` equality, isn't that enough? > > Zhaoxin > > > On Sat, Sep 3, 2016 at 7:02 AM, Dmitri Gribenko <griboz...@gmail.com > <mailto:griboz...@gmail.com>> wrote: > On Sat, Sep 3, 2016 at 1:31 AM, Zhao Xin via swift-users > <swift-users@swift.org <mailto:swift-users@swift.org>> wrote: > > func ==(lhs: Apple, rhs: Apple) -> Bool { > > return lhs.name <http://lhs.name/> == rhs.name <http://rhs.name/> && > > lhs.shape == rhs.shape > > } > > > > func ==(lhs: Banana, rhs: Banana) -> Bool { > > return lhs.name <http://lhs.name/> == rhs.name <http://rhs.name/> && > > lhs.shape == rhs.shape > > } > > There is no reason to compare the shape, it is a constant in each of > these types. (So I am not sure what your point is.) > > > My question is, apple equals banana, but their hashValues (in their own > > types) don't. What's wrong here? Is that means we shouldn't override > > hashValue in subclass in Swift? > > This means you should not override hashValue in this particular way. > If two values are equal, their hash values should be equal. As long > as your override implementation guarantees this, you can override > hashValue. > > You should also understand that the ==(Apple, Apple) and ==(Banana, > Banana) are not overrides for ==(Fruit, Fruit), and they would not be > called through dynamic dispatch when you have, for example, two apples > typed as fruits. > > Dmitri > > -- > main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if > (j){printf("%d\n",i);}}} /*Dmitri Gribenko <griboz...@gmail.com > <mailto:griboz...@gmail.com>>*/ > > > _______________________________________________ > swift-users mailing list > swift-users@swift.org > https://lists.swift.org/mailman/listinfo/swift-users
_______________________________________________ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users