As far as I understand, the Object class is the base class for all classes, except for those that allow null. Also, as I understood from the documentation on the dart.dev site, the Null type is outside the Object class hierarchy.
But I can not understand the reason for the following oddity.
For example, the runtimeType getter is defined in the Object class, but this getter is not present in the Null class. At the same time, the documentation https://api.dart.dev/stable/2.18.4/dart-core/Null-class.html states that runtimeType is inherited. But from whom it is not clear? If from type Object?, then why doesn't the Object class indicate that the getter is overridden or inherited https://api.dart.dev/stable/2.18.2/dart-core/Object-class.html. Also in the IDE, when you jump to the getter definition for the variable "Null a = null", it jumps to the getter definition in Object.
This begs the question, is Null a subtype of Object?
I want to understand the relationship between Null, Object.
CodePudding user response:
You're pointing to a slightly sore point in the interaction between the Dart language specification and the platform library sources.
For a long time, null
was a subtype of Object
. With null safety, that became a problem, and it was moved (in the language specification) to be a second class with no superclass, besides Object
.
Both have the same interface members. Both have the same default implementation of some of those (at least operator==
, probably runtimeType
and noSuchMethod
, probably not hashCode
and definitely not toString
... well, not unless the default toString
starts with if (this == null) return "null";
).
The implementations changed the subtyping rules, null
was no longer an Object
, but nobody got around to changing the platform libraries. The Null
type was so heavily special-cased anyway, that the declaration in the platform library source is really more of a placeholder than a real definition.
You can see the current libraries as saying that both Object
and Null
get their members from some magical super-type like Object?
, but that's not a class, so it's not a good explanation.
Or you can say that null
inherits member implementations from Object
, without actually being a subtype of Object
. By magic.
That's probably close to what's actually happening.
A more authorative answer would be that Object
and Null
are both very special classes with no superclass. The "members of Object
" (the five members named above), exist on all Dart objects, and on the Object?
type too (so you can actually call them on Object?
), by decree. The actual implementations of those members on Object
and Null
are provided by the runtime system in some way.
In any case, don't trust the source code to be the whole truth. Those classes are special.
CodePudding user response:
I would like to see a language without any features, logical and easy to understand. Dart is close to this, but so far, as I believe, he has not reached this goal. I don't know where to send emails to dart developers so that they read them. If they see this message, I suggest making the language a little more understandable. Two options are offered.
For the Null type in library files, the same API is specified as in the Object class. At the same time, in the Null type, the documentation does not indicate for any members that they are inherited.
To say that all functions in Object, Null types are inherited from the "Object?" type, which has no special name. In this case, the documentation should indicate that the method is overridden or inherited.