6

Is it possible for a method to know the type of the method it is called under? So for example in the following object orientated psuedo code:

Instance io = new InstanceSubclass();
io.doStuff();

Is there a language that allows doStuff() to know that it was called as an Instance?

The question arose out of the fact the Java does not provide any kind of support for interface name clashes, for example if you create a class that implements interfaces A and B that both have a method signature such as void doWork() would it be possible for the body of doWork() to do something similar to the following :

public void doWork() {
    Class<?> context = getMethodCallContext();
    if(context == InterfaceA.class) {
        doAsInterfaceA();
    }
    else if(context == InterfaceB.class) {
        doAsInterfaceB();
    }
    else {
        // Shenanigans and error handling
    }
}

I am not planning to write any code that takes advantage of this feature as to do so reeks of an anti-pattern waiting to happen, I only want to know if it CAN be done, if so which languages permit it?

4 Answers 4

3

In C# you just do:

 void InterfaceA.doWork()
 {
 }

 void InterfaceB.doWork()
 {
 }

So there are no real shenanigans involved.

The calling function needs to identify which doWork() is intended:

Instance io = new InstanceSubclass();
((InterfaceA)io).doStuff();

See this page for more details.

8
  • There is a catch: these methods cannot be public. The above function definitions would not compile.
    – Mike Nakis
    Commented Jan 2, 2012 at 8:39
  • True... but the effective accessibility still seems to be public. Any pointers as to why this is, @MikeNakis ?
    – Peter K.
    Commented Jan 2, 2012 at 14:16
  • @PeterK.: I think the accessibility of explicitly implemented interface methods will be the same as the accessibility of the interface itself. iirc Commented Jan 2, 2012 at 14:21
  • @qes: Thanks! Implementing a "private interface" seems like an oxymoron somehow, though. :-)
    – Peter K.
    Commented Jan 2, 2012 at 14:23
  • @PeterK.: They would be internal, and that would simply be a contract you want a class to implement, but not expose outside the assembly. Maybe not so common in a standard LOB app, but if its a component library meant for use by others its much more common to use internal interfaces for .. well .. internal details ;-) Commented Jan 2, 2012 at 14:28
5

What you described is achievable via Aspect-Oriented Programming (AOP). It won't be as straightforward as in your example, but you can get the requested behaviour.

AOP has implementations in different languages; AspectJ being one of the most mature one. I will give you an example using AspectJ even though I don't want to go to in too much detail.

To implement the behaviour:

1) Create a pointcut that will intercept all the calls to the public void doWork() method.
[pointcut conflictingMethodIsExecuted(): execution(public void doWork()]

2) Create an advice around this pointcut. Within the advice, you can get the context; just as you have specified in your example. The JoinPoint will serve you that information.
[joinPoint.getThis() // returns the context]

3) With that information, the advice sets a certain parameter and lets the public void doWork() run. The method takes a look at that parameter and decides what to do.

I assume the question was a bit theoretical so this answer also goes along the same line. I can provide more details about the solution in AspectJ if you choose to take this path.

0
1

I don't see an interface method name clash here. There would be a clash in the case of multiple inheritance, but that is a different class relationship.

In your example you have two interfaces both of which require that you implement a void doWork method with no parameters. What the method needs to do should be independent of which Interface is used to call the method. If there is a conflict, then it lies in the interface specification, or the design of the class to use the two interfaces with differing expectations of the doWork method.

More complicated method signatures could result in methods with the same name but differing signatures, in which case the signature would be used to differentiate between the two methods.

0

You can get exactly this effect in Java by overloading a method:

  public void doStuff(InterfaceA object) {
    // stuff for InterfaceA
  }

  public void doStuff(InterfaceB object) {
    // stuff for InterfaceB
  }

And call it as follows:

  if (object instanceof InterfaceA) {
    doStuff((InterfaceA)object)
  } 
  else if (object instanceof InterfaceB) {
    doStuff((InterfaceB)object);
  }

This is also pretty performant: all the calls will be statically determined by the compiler so you really only have the instanceof / casting overhead (which is pretty minimal).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.