Inheritance and arrays

Arafel er.krali at gmail.com
Mon Jul 3 11:37:38 UTC 2023


That's very clearly an implementation detail leaking: the semantics of 
the language shouldn't depend on how interfaces and classes are implemented.

So then I need to do something like:

```d
ii = cc.map!(a => cast (I) a).array;
```

(I just tested it and it works)

Any reason why it can't be done internally by the language?

I find it most unexpected and confusing and, assuming it won't change 
anytime soon, I think it should at the very least be **clearly** 
documented. And the cast forbidden, since it can't possible work between 
classes and interfaces.

Honestly, this severely limits the usefulness of interfaces, and for 
hierarchies of classes it might be much better to switch to abstract 
classes.

BTW, even for (abstract) classes you need a cast:

```d
import std;

abstract class I {
     abstract void foo();
}
class C : I {
     this(int i) {
         this.i = i;
     }
     override void foo() {
         writeln("In foo: ",i);
     }
     int i;
}

void main() {
     I i;
     C c = new C(1);
     i = c; // Works

     I[] ii;
     C[] cc;
     cc ~= c;
     i.foo();
     // ii = cc; // Doesn't work: Error: cannot implicitly convert 
expression `cc` of type `C[]` to `I[]`
     ii = cast (I[]) cc; // Compiles, apparently works
     //ii = cc.map!(a => cast(I) a).array;
     ii[0].foo();
}
```

Shouldn't `ii = cc` work in this case?

On 3/7/23 12:06, FeepingCreature wrote:
> On Monday, 3 July 2023 at 09:50:20 UTC, Arafel wrote:
>> Hi!
>>
>> I am a D user coming from java, rather than from C/C++ (although 
>> obviously also have some exposure to them), and thus apparently one of 
>> the few people here who likes OO (within reason, of course).
>>
>> So while I appreciate the fact that D closely follows java's design, I 
>> wonder why there is no implicit inheritance for arrays (also the same 
>> applies to AAs):
>>
>> ```d
>> interface I {}
>> class C : I {}
>>
>> void main() {
>>     I i;
>>     C c = null;
>>     i = c; // Works
>>
>>     I[] ii;
>>     C[] cc = null;
>>     // ii = cc; // Doesn't work: Error: cannot implicitly convert 
>> expression `cc` of type `C[]` to `I[]`
>>     ii = cast (I[]) cc; // Works, but why do I need to cast?
>> }
>> ```
>>
> The `cast` version "works", but will crash at runtime.
> 
> In D, as opposed to Java, a reference to an object has a *different 
> pointer value* than a reference to the interface-typed version of that 
> object. This is necessary for efficient compiled virtual method calls on 
> the interface. But for the same reason, you cannot reinterpret an array 
> of objects to an array of interfaces; even if you can implicitly convert 
> each object to that interface, there's a difference between 
> automatically rewriting a value and automatically rewriting every 
> element of an array: one is O(1), the other is O(n) and incurs a GC 
> allocation.



More information about the Digitalmars-d-learn mailing list