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

Reply via email to