How to dynamically call class virtual method dynamically

John Colvin john.loughran.colvin at gmail.com
Tue Apr 1 02:12:37 PDT 2014


On Tuesday, 1 April 2014 at 07:31:43 UTC, Frustrated wrote:
> Basically in programming to interfaces I need to decide to call 
> a virtual method of an object if it exists else call a final 
> method in the interface:
>
> interface A
> {
>     static final void foo() { ... }
> }
>
> class B : A
> {
>     void bar() { ... }     // optional
> }
>
> class C : B
> {
>     void bar() { ... }     // optional
> }
>
> void main()
> {
>     A a = new B;  // or new C;
>
>     // if a.bar exists call it, else call foo
>     // code should work independent of the classes. (there 
> might be more)
> }
>
> The point of the code is simply to allow the class to implement 
> bar optionally but provide default behavior with foo. I need a 
> way to dynamically determine if bar exists and fall back on 
> foo. This should be possible.
>
> e.g., suppose
>
> class B : A { }
>
> then I would like to b.bar() to actually call A.foo() (since 
> bar doesn't exist in b).
>
> I guess the exist way would be to create an opDispatch and have 
> it call foo if bar is passed. This works great and does 
> everything I need it to except requires adding the code in the 
> class which I can't have. Also I'm not sure how it would work 
> with virtual methods.
>
> I've tried using hasMember but since my object is cast to a 
> type of Object it never works.

The traditional OO approach would probably be this:

import std.stdio;
class A
{
	static final void foo() { writeln("A.foo"); }
	void bar() { foo(); }
}
class B : A
{
	override void bar() { writeln("B.bar"); }     // optional
}
class C : A {}
void main()
{
	A a0 = new B;  // or new C;
	A a1 = new C;  // or new C;
	a0.bar();  //B.bar
	a1.bar();  //A.foo
}

Also, bear in mind that polymorphism is one-way: you can call 
base class methods through an inherited class reference, but not 
the other way around.

interface A {}
class B : A
{
     void bar() {}
}
void main()
{
     A a = new B;
     a.bar(); // Error: no property 'bar' for type 'A'
}


More information about the Digitalmars-d-learn mailing list