<p>In some languages, all classes have an implicit superclass. For example, <code>Object</code> in Java/Python and <code>Any</code> in Kotlin. All classes that the user defines automatically are subclasses of this superclass. Oftentimes, this class has many methods that are also inherited by all other classes that are useful for the user, such as some sort of <code>toString()</code> or <code>hash()</code>.</p>
<p>What are the benefits or drawbacks associated with this approach for the user or language designer (including for the standard library)?</p>

<object-oriented><classes>
What are the advantages/disadvantages of making every class an instance of an Object superclass?
CC BY-SA 4.0
2023-07-07T22:49:09.640Z
Nitpick: it is the objects (instances) which are "instances of" some "superclass" object type. Classes may *have* a superclass, but they don't generally *instantiate* it. In most languages, they don't instantiate anything at all, and indeed aren't themselves objects. In a language like Python, the distinction between the `object` type and the `type` type is essential.
Karl Knechtel
<h2>Drawback: Universal cluttered namespace</h2>
<p>With all classes as subclasses of common type <em>with</em> methods then that means all classes will always have these methods, even where they are invalid in some contexts.</p>
<p>This means you have less control at what the methods your objects will have, and will make any integration with other languages or ABI more difficult as result.</p>
<p>Some of these universal methods have very integrated runtime semantics, and will impose very visible costs on your users, if no downright bugs.</p>
<hr />
<p>Note that I'm not arguing against having top or bottom types, but against having implemented methods on these top/bottom types. <code>null</code> with implemented methods is a strange thing, as for all objects in existence having the same methods.</p>

CC BY-SA 4.0
2023-07-07T22:08:41.537Z
2023-08-04T12:20:00.877Z
2023-08-04T12:20:00.877Z
André L F S Bacci
CC BY-SA 4.0
2023-08-09T16:47:03.273Z
"null with implemented methods is a strange thing" ... ISTR at least one language whose equivalent of null was a standard object that was defined as accepting any method call with an implementation that just throws an exception, which doesn't seem entirely unreasonable.  Perhaps this was Smalltalk?
occipita
CC BY-SA 4.0
2023-08-09T20:38:21.327Z
Asking a reference that identifies an apple if it is should be viewed as encapsulating the same information as a reference that identifies an orange shouldn't be viewed as an error.  Instead, it should simply yield the answer "no, it doesn't".
supercat
<p>This 'super' superclass can define methods that may be important or beneficial for all other classes to implement.</p>
<p>These may be commonly used operations. For example, printing to the standard output via a <code>print()</code> function may need the object to define a <code>toString()</code> method to ensure that any type of object can be printed.</p>
<p>Another type of method that could be encouraged in this way is a <code>hash()</code> function, so things like <code>HashMaps</code> can work properly.</p>

CC BY-SA 4.0
2023-07-07T15:46:47.750Z
2023-07-07T15:46:47.750Z
FireTheLost
CC BY-SA 4.0
2023-07-07T16:31:17.613Z
Functions like toString() and hash() can also be automatically generated without any Object superclass, for example Haskell does it using a `deriving` keyword.
Eldritch Conundrum
CC BY-SA 4.0
2023-07-07T16:45:15.950Z
This is one place where Rust's traits really shine IMO; you can implement them onto anything, and even create blanket implementations to implement them on _everything_, but you can also choose not to implement a trait like `Display` or `Hash` if it wouldn't make sense for your class (whereas making `hash` a method on the superclass of everything takes away your ability to remove that option if it would be meaningless)
rydwolf
CC BY-SA 4.0
2023-07-11T08:08:21.027Z
C++ has `operator<<(std::ostream&, T)` and `std::hash<T>` for these cases as _opt-in_ functionality, without needing a universal base class, and that seems to work reasonably well.  It might be considered an advantage that types for which those aren't useful can cause compile-time diagnostics rather than meaningless results.
Toby Speight
CC BY-SA 4.0
2023-08-09T16:53:06.327Z
I think having `hashCode()` in Java is a serious misfeature.  There should have been an interface, because as things stand it is impossible to know for sure whether an object can be correctly used as a key in a `HashMap` (I would argue that using object identity is not correct behaviour in most circumstances, and it should be explicitly called out when it is used).
occipita
CC BY-SA 4.0
2023-08-09T20:44:52.613Z
@occipita: The problem with `hashCode` and `equals` is that they can have two different meanings: will two object references encapsulate the same state if no references are exposed to code that might mutate them, and will they encapsulate the same state forever even if references are exposed?  Objects which are "attached" to other entities should often use reference equality for both, immutable objects should use value equality for both, and things like arrays should use value equality for the first but reference equality for the second.
supercat
<h1>Ignoring Static Types</h1>
<p>Static typing is nice. But sometimes it gets in your way. Sometimes you really, genuinely do know nothing about an object, other than that it exists. Maybe you just deserialized it from some framework, or maybe some external third-party API returned it. However you ended up with it, you know nothing about it yet. That's an <code>Object</code>. Your next step might be to attempt some downcasts or try to identify the object's actual, runtime type in some other way. Or maybe you're just the middleman, transmitting some object you know nothing about from a frontend to a backend.</p>
<p>Yes, it's ugly and messy to do things this way. But programming is ugly and messy sometimes. In this sense, you can think of &quot;upcast to <code>Object</code>&quot; as being a marginally safer <code>void*</code>.</p>

CC BY-SA 4.0
2023-07-11T03:51:56.333Z
2023-07-11T03:51:56.333Z
Silvio Mayolo
CC BY-SA 4.0
2023-07-11T12:56:03.513Z
"Oftentimes, this class has many methods". Your answer is about top types, but the question is about top types _with methods_.
André L F S Bacci
# What are the advantages/disadvantages of making every class an instance of an Object superclass?
Posted by: username_0 on 2023-07-07
In some languages, all classes have an implicit superclass. For example, `Object` in Java/Python and `Any` in Kotlin. All classes that the user defines automatically are subclasses of this superclass. Oftentimes, this class has many methods that are also inherited by all other classes that are useful for the user, such as some sort of `toString()` or `hash()`.

What are the benefits or drawbacks associated with this approach for the user or language designer (including for the standard library)?
**Tags:** object-oriented classes
> **Comments:**
> **username_1**: Nitpick: it is the objects (instances) which are "instances of" some "superclass" object type. Classes may *have* a superclass, but they don't generally *instantiate* it. In most languages, they don't instantiate anything at all, and indeed aren't themselves objects. In a language like Python, the distinction between the `object` type and the `type` type is essential.  
---
## 3 answers
### Answer by username_2 on 2023-07-07. Score: 7
## Drawback: Universal cluttered namespace

With all classes as subclasses of common type *with* methods then that means all classes will always have these methods, even where they are invalid in some contexts.

This means you have less control at what the methods your objects will have, and will make any integration with other languages or ABI more difficult as result.

Some of these universal methods have very integrated runtime semantics, and will impose very visible costs on your users, if no downright bugs.

---

Note that I'm not arguing against having top or bottom types, but against having implemented methods on these top/bottom types. `null` with implemented methods is a strange thing, as for all objects in existence having the same methods.
> **Comments:**
> **username_3** (2023-08-09): "null with implemented methods is a strange thing" ... ISTR at least one language whose equivalent of null was a standard object that was defined as accepting any method call with an implementation that just throws an exception, which doesn't seem entirely unreasonable.  Perhaps this was Smalltalk?  
> **username_4** (2023-08-09): Asking a reference that identifies an apple if it is should be viewed as encapsulating the same information as a reference that identifies an orange shouldn't be viewed as an error.  Instead, it should simply yield the answer "no, it doesn't".  
---
### Answer by username_0 on 2023-07-07. Score: 6
This 'super' superclass can define methods that may be important or beneficial for all other classes to implement.

These may be commonly used operations. For example, printing to the standard output via a `print()` function may need the object to define a `toString()` method to ensure that any type of object can be printed.

Another type of method that could be encouraged in this way is a `hash()` function, so things like `HashMaps` can work properly.
> **Comments:**
> **username_5** (2023-07-07): Functions like toString() and hash() can also be automatically generated without any Object superclass, for example Haskell does it using a `deriving` keyword.  
> **username_6** (2023-07-07): This is one place where Rust's traits really shine IMO; you can implement them onto anything, and even create blanket implementations to implement them on _everything_, but you can also choose not to implement a trait like `Display` or `Hash` if it wouldn't make sense for your class (whereas making `hash` a method on the superclass of everything takes away your ability to remove that option if it would be meaningless)  
> **username_7** (2023-07-11): C++ has `operator<<(std::ostream&, T)` and `std::hash<T>` for these cases as _opt-in_ functionality, without needing a universal base class, and that seems to work reasonably well.  It might be considered an advantage that types for which those aren't useful can cause compile-time diagnostics rather than meaningless results.  
> **username_3** (2023-08-09): I think having `hashCode()` in Java is a serious misfeature.  There should have been an interface, because as things stand it is impossible to know for sure whether an object can be correctly used as a key in a `HashMap` (I would argue that using object identity is not correct behaviour in most circumstances, and it should be explicitly called out when it is used).  
> **username_4** (2023-08-09): @occipita: The problem with `hashCode` and `equals` is that they can have two different meanings: will two object references encapsulate the same state if no references are exposed to code that might mutate them, and will they encapsulate the same state forever even if references are exposed?  Objects which are "attached" to other entities should often use reference equality for both, immutable objects should use value equality for both, and things like arrays should use value equality for the first but reference equality for the second.  
---
### Answer by username_8 on 2023-07-11. Score: 6
# Ignoring Static Types

Static typing is nice. But sometimes it gets in your way. Sometimes you really, genuinely do know nothing about an object, other than that it exists. Maybe you just deserialized it from some framework, or maybe some external third-party API returned it. However you ended up with it, you know nothing about it yet. That's an `Object`. Your next step might be to attempt some downcasts or try to identify the object's actual, runtime type in some other way. Or maybe you're just the middleman, transmitting some object you know nothing about from a frontend to a backend.

Yes, it's ugly and messy to do things this way. But programming is ugly and messy sometimes. In this sense, you can think of "upcast to `Object`" as being a marginally safer `void*`.
> **Comments:**
> **username_2** (2023-07-11): "Oftentimes, this class has many methods". Your answer is about top types, but the question is about top types _with methods_.  
---
