site-www
site-www copied to clipboard
Glossary entries for "Subtype" and "Subclass"
Fixes #4784
Sparked from this comment.
Yes - there are many subtype relations which are not subclass relations. If we're talking about classes, it's essentially the difference between
implementsandextends.If
class Foo implements Bar, thenFoois a subtype ofBar, but not a subclass. Ifclass Foo extends Bar, thenFoois both a subtype and a subclass ofBar.
I tried to explain the difference while still having them make sense as stand alone glossary entries. I'm not really sure I captured the nuance. @fishythefish since you gave the preliminary explanation, and @johnpryan since you asked the question, would you mind evaluating this? Are these definitions useful?
Based on the definitions I added in this PR, I'm now unsure about some of the uses of subclass vs. subtype in the main Class Modifiers page. E.g. This use of "subclasses" under final seems like it could be incorrect?:
The
finalmodifier encompasses the effects ofbase, and therefore any subclasses must also be markedbase,final, orsealed.
- Either because
finalprevents bothimplementsandextends, so it should be "...any subtypes..."? - Or, is it deliberate because maybe only subclasses (declared with
extendson thefinalsuperclass) need to be markedbase,finalorinterface, but not subtypes (declared withimplementson thefinalsuperclass)?
I'm probably overthinking it; any thoughts are appreciated!
(Ignore the empty glossary page, we're working on filling it out and standardizing its use.)
ToDo:
- If approved, add links to these definitions from class-modifiers.md
I'm not so worried about the category mismatch: In every situation where we wish to topicalize implementation inheritance (that is, we're considering class B extends A {...} and the question is "how come myA.foo() runs some code in the body of B?"), it is most likely implied by the context that we are talking about inherited implementations, and hence about classes and subclass relationships.
With that in mind, I tend to think that it's OK to categorize subtype relationships into (1) "subclass" relationships, established by extends S with M1 .. Mk (or, as a special case extends S), and (2) every other relationship which is included in the subtype relation (so Object? <: dynamic even though none of them is a class, and int Function() is a subtype of num Function() even though there is no syntax in the program specifying any such relationship, but also MyMixin on SomeClassOrMixin and MyClass implements SomeOtherType, and the relationship between a type variable X and and its bound, e.g., between two type variables X and Y when X is declared as X extends Y).
If we wish to target subtype relationships that are specifically created by an implements clause (as in MyClass implements SomeOtherType), we will probably have to talk about the syntax explicitly (saying things like "assume class C implement B {}", or at least "assume that class C implements class B").
I added a couple of comments in the files, too.
Agreed - I'm generally not too worried about the category mismatch either, and the intended meaning has been clear in almost every conversation that I've had.
Maybe another way to phrase my concerns is that there are essentially two audiences: those wondering about subtyping generally (or using this as a reference to e.g. read a feature specification), and those wondering about interface inheritance specifically (especially if they're coming from another (object-oriented) language, e.g. Java).
IMO, since this is a general-purpose glossary for Dart, we should mainly target the former. I think it would be okay to then mention that implements (and extends, with, etc.) gives us one special case of subtyping. I would just be careful about implying that this kind of subtyping is first-class and every other subtyping relationship is some kind of side effect.
IMO, since this is a general-purpose glossary for Dart, we should mainly target the former. I think it would be okay to then mention that implements (and extends, with, etc.) gives us one special case of subtyping.
Great insight, I was operating under the impression that implements was the point of "subtype" myself.
I think that we could mention implements and link to its language tour content, and maybe mention there that it creates a subtype relationship, and any other elaboration needed for that one case.
Visit the preview URL for this PR (updated for commit 344c8288826f4434b928705f74a2eca2b82fe164):
https://dart-dev--pr4958-subtype-subclass-iwh6vcvk.web.app
@eernstg I'm definitely still going to go through and incorporate the comments before merging, but thanks for the approval! Appreciate all the explanations here, tricky stuff indeed :)
@fishythefish @leafpetersen @eernstg I rewrote both sections, taken basically word for word from the comments here (thank you all!)
If anyone wants to take another look that would be greatly appreciated!
Here are the staged sections: https://dart-dev--pr4958-subtype-subclass-iwh6vcvk.web.app/resources/glossary#subclass