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> 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> > wrote: > >> On Sat, Sep 3, 2016 at 1:31 AM, Zhao Xin via swift-users >> <swift-users@swift.org> wrote: >> > func ==(lhs: Apple, rhs: Apple) -> Bool { >> > return lhs.name == rhs.name && lhs.shape == rhs.shape >> > } >> > >> > func ==(lhs: Banana, rhs: Banana) -> Bool { >> > return lhs.name == 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>*/ >> > >
_______________________________________________ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users