On 29/04/2013 19:24, Steven D'Aprano wrote:
> On 30/04/13 03:01, Guido van Rossum wrote:
>>> Oh dear, this is actually a mess. I don't want MoreColor.red and
>> Color.red to be distinct objects, but then the isinstance() checks
>> will become confusing. If we don't override isinstance(), we'll
>> get
>>>> not isinstance(Color.red, MoreColor) isinstance(MoreColor.yellow,
>> Color)
>>>> This would be pretty backwards.
>> Why is that backwards? MoreColor is a subclass of Color, so instances
> of MoreColor are instances of Color, but instances of Color are not
> instances of MoreColor. That's normal behaviour for subclasses. (All
> cats are mammals, but not all mammals are cats.)
>Let's say that Color is red, green, or blue.
Let's also say that MoreColor is superset of Color, in other words, any
of Color, plus cyan, magenta, or yellow.
Red is a Color and a MoreColor (member of Color and MoreColor).
Yellow is a MoreColor, but not a Color (member of MoreColor but not
Color).
That's the opposite of the rules of inheritance.
> The only "funny" thing about this is that enumeration values of a
> Enum are only instances of that Enum if they are declared inside that
> Enum, and as far as I'm concerned that's not especially funny at all.
> So:
>> Color declares red, so Color.red is a Color.
>> MoreColor does not declare red, it merely inherits it from Color, so
> MoreColor.red is Color.red which is not a MoreColor.
>>> This leads to a simple rule:
>> Enum values are either instances of the enum they are defined in, or
> instances of the parent class they are inherited from.
>> If the user doesn't like that, they're free to not subclass Enums
> :-)
>>>>> I Ggoogled "enum subclassing" and found this StackOverflow article
>> explaining why you can't subclass enums in Java:
>>http://stackoverflow.com/questions/4604978/subclassing-an-enum>> which refers to this more elaborate answer:
>>http://stackoverflow.com/questions/3427947/enumeration-inheritence-in-java/3428050#3428050>>>> The first link says:
>> "And generally, a proper subclass is a specialization of its
> superclass."
>> and gives the Liskov Substitution Principle as the reason for
> prohibiting subclassing. LSP is a very useful principle, but it is
> not the only model for subclassing. That's why it's called a
> *principle* and not the Liskov Substitution *Law*.
>> (Yes, I stole that from Raymond Hettinger's talk on subclassing at
> PyCon.)
>> I think that the ability to extend enums with new ones, without
> duplicating code, is more important for enums than satisfying LSP.
> The common use-cases for enums do not lend itself to subtyping in the
> Liskov sense.
>> E.g. if I have a function that expects a Color red/blue/green enum,
> and I subclass it to give MoreColor yellow, I can't expect the
> function to suddenly recognise yellow. So I'm not going to use
> subclassing in this case, because it can't work.
>> But I will use subclassing to reuse values: if I have a function that
> expects red/blue/green/yellow, and red/blue/green are already defined
> in Color, I'll want to reuse them rather than duplicate them. Hence I
> will subclass Color specifically to extend it, not to specialise it.
>On the other hand, a function that expects MoreColor should also accept
Color, which is a subset.
>> The second link quotes:
>> "For the most part, extensibility of enums turns out to be a bad
> idea. It is confusing that elements of an extension type are
> instances of the base type and not vice versa."
>> Confusing for who, and why?
>> You're going to confuse *somebody* no matter what you do. Either:
>> - confuse people who try to subclass enums, and can't; or
>> - confuse people who try to subclass enums, and can, but then get
> confused by the result.
>