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 <owenzx@gmail.com <mailto:owenzx@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 <gribozavr@gmail.com <mailto:gribozavr@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 <gribozavr@gmail.com <mailto:gribozavr@gmail.com>>*/
_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users