www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Dlang Polymorphism doesn't work as expected.

reply Enjoys Math <enjoysmath gmail.com> writes:
I have the following MWE:

```
import std.exception;
import std.stdio;

abstract class B
{
    B opCall() {
       throw new Exception("NotImplemented");
    }
}

class A : B
{
    override B opCall() {
       return new A();
    }
}

int main() {
    B a = new A();
    a();
    readln();
    return 0;
}

```

But B.opCall() gets called!   I thought polymorphism was cool 
until now....

How can I get this to work the way I expected it to?  Would an 
abstract method in base do it?
Sep 04 2022
next sibling parent reply Enjoys Math <enjoysmath gmail.com> writes:
On Sunday, 4 September 2022 at 17:36:24 UTC, Enjoys Math wrote:
 I have the following MWE:

 ```
 import std.exception;
 import std.stdio;

 abstract class B
 {
    B opCall() {
       throw new Exception("NotImplemented");
    }
 }

 class A : B
 {
    override B opCall() {
       return new A();
    }
 }

 int main() {
    B a = new A();
    a();
    readln();
    return 0;
 }

 ```

 But B.opCall() gets called!   I thought polymorphism was cool 
 until now....

 How can I get this to work the way I expected it to?  Would an 
 abstract method in base do it?
Okay... now the MWE works as I expected polymorphism to work, but my complicated library is not doing it right... :\
Sep 04 2022
parent reply Enjoys Math <enjoysmath gmail.com> writes:
On Sunday, 4 September 2022 at 17:38:54 UTC, Enjoys Math wrote:
 On Sunday, 4 September 2022 at 17:36:24 UTC, Enjoys Math wrote:
 I have the following MWE:

 ```
 import std.exception;
 import std.stdio;

 abstract class B
 {
    B opCall() {
       throw new Exception("NotImplemented");
    }
 }

 class A : B
 {
    override B opCall() {
       return new A();
    }
 }

 int main() {
    B a = new A();
    a();
    readln();
    return 0;
 }

 ```

 But B.opCall() gets called!   I thought polymorphism was cool 
 until now....

 How can I get this to work the way I expected it to?  Would an 
 abstract method in base do it?
Okay... now the MWE works as I expected polymorphism to work, but my complicated library is not doing it right... :\
Here is a link to the library on github. Please help me solve this!! :D https://github.com/enjoysmath/diagram-chaser
Sep 04 2022
parent reply Enjoys Math <enjoysmath gmail.com> writes:
On Sunday, 4 September 2022 at 17:43:33 UTC, Enjoys Math wrote:
 On Sunday, 4 September 2022 at 17:38:54 UTC, Enjoys Math wrote:
 On Sunday, 4 September 2022 at 17:36:24 UTC, Enjoys Math wrote:
 I have the following MWE:

 ```
 import std.exception;
 import std.stdio;

 abstract class B
 {
    B opCall() {
       throw new Exception("NotImplemented");
    }
 }

 class A : B
 {
    override B opCall() {
       return new A();
    }
 }

 int main() {
    B a = new A();
    a();
    readln();
    return 0;
 }

 ```

 But B.opCall() gets called!   I thought polymorphism was cool 
 until now....

 How can I get this to work the way I expected it to?  Would 
 an abstract method in base do it?
Okay... now the MWE works as I expected polymorphism to work, but my complicated library is not doing it right... :\
Here is a link to the library on github. Please help me solve this!! :D https://github.com/enjoysmath/diagram-chaser
Simply git clone it and run from main.d or hit debug in VisualD to see my problem. It's calling the base class method which throws a NotImplemented exception, but it should be calling one of the derived subclasses. I will keep coding on it and update the code, but if I get it fixed, I'll post an update here.
Sep 04 2022
parent Enjoys Math <enjoysmath gmail.com> writes:
On Sunday, 4 September 2022 at 17:50:10 UTC, Enjoys Math wrote:
 On Sunday, 4 September 2022 at 17:43:33 UTC, Enjoys Math wrote:
 On Sunday, 4 September 2022 at 17:38:54 UTC, Enjoys Math wrote:
 On Sunday, 4 September 2022 at 17:36:24 UTC, Enjoys Math 
 wrote:
 [...]
Okay... now the MWE works as I expected polymorphism to work, but my complicated library is not doing it right... :\
Here is a link to the library on github. Please help me solve this!! :D https://github.com/enjoysmath/diagram-chaser
Simply git clone it and run from main.d or hit debug in VisualD to see my problem. It's calling the base class method which throws a NotImplemented exception, but it should be calling one of the derived subclasses. I will keep coding on it and update the code, but if I get it fixed, I'll post an update here.
Fixed. I was simply not implementing anything in the subclass.
Sep 04 2022
prev sibling parent rikki cattermole <rikki cattermole.co.nz> writes:
This appears to be working correctly.

You override the implementation of opCall in A, so when you called 
opCall, it called the implementation of it in A. B's opCall never landed 
in the vtable.

It does in fact return an A object.

```d
import std.stdio;

abstract class B
{
    B opCall() {
       throw new Exception("NotImplemented");
    }
}

class A : B
{
    override B opCall() {
       return new A();
    }
}

int main() {
    B a = new A();

    auto got = a();
    assert(got !is null);
    writeln(got);

    return 0;
}
```
Sep 04 2022