Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
RE: [aspectj-users] Super calls to inter-type methods

Sorry for the delayed response on this. I appreciate the replies I received (quoted below), but I have problems with each (although I do appreciate them) and was wondering if anybody had any further thoughts on the issue.

I can see how adding in two methods, one that matches the interface signature, and another that is a "default" implementation could solve the problem... unfortunately it a) duplicates the number of methods necessary, kind of a pain since a lot of aj's usefulness to me is in simplifying things and b) it seems kind of sloppy that my choices are either to mixin methods that are not included in the interface, or add the default implementation methods to the interface as well, which makes the interface a lot less readable.

The template method suggestion has the same basic problems, except now I have 3 methods for every 1. I'm sure in some situations that pattern is useful, but if I'm looking at a large interface with a default implementation for most or all methods, where the defaults aren't overridden very often, it could end up as a big mess.

Does anyone have any other ideas? I had thought about using before / after advice on the mixin, rather than doing something in the overridden method along with a super call, but then if the method is overridden again in a subclass, the before / after advice would not occur at the intended time.....

I'm wondering if this is a concern for anyone else. It seems to be a problem especially when an interface contains multiple methods that utilize the same inter-type field. If I want to make a slight modification to one of the methods, adding something either before or after it occurs, I can't make a super call to it, and I can't even cut and paste it without making the inter-type field that's referenced public, which would be "incorrect" in many circumstances.

This seems to me like an issue that others must have dealt with in the past. If anyone who works on the aj internals is listening, is this anything that has ever been discussed before?

Thanks for your time.

I dont think there is a syntax that you can access the injected "public void SelectAction<T>.select(T selection)" method inside StringSelectAction.

The interface method implementation injection just provide a default implementation of that method. What ajc do is actually injecting the select(T selection) method with the default implementation to all classes which are implementors of interface SelectAction.

You can have a clear understanding if you try the following:

a. public class StringSelectAction implements SelectAction<T> { }
b. then compile it with ajc
c. javap StringSelectAction
  javap SelectAction

So, if you really wanna do this, you can
public interface SelectAction<T>{

	public void select(T selection);

}

public aspect SelectAspect{

	private T SelectAction<T>.selection;

	public void SelectAction<T>.defaultSelect(T selection){ //here
		this.selection = selection;
	}

}

then,

public class StringSelectAction implements SelectAction<T>{
public void select(String selection){
	checkPermissions(selection);
	defaultSelect(selection); //here
}
}

--
Dehua Zhang
Sable Research Group, McGill University
Montréal, Québec, Canada
http://www.cs.mcgill.ca/~dzhang25


There's a limited way to do it if you use the Template Method Pattern.
However, it's got "issues", too.

Comments inline:

On Mar 12, 2008, at 11:23 AM, Dave Whittaker wrote:

Hi there.  I'm having trouble figuring out the best method to do
something and I was hoping someone out there with more AspectJ
experience might be able to help.

I am trying to use inter-type declarations on interfaces to simulate
multiple inheritance.  The trouble comes in when I want to override
the inherited method from an interface.  For instance if I have:

public interface SelectAction<T>{

	public void select(T selection);

}

public aspect SelectAspect{

	private T SelectAction<T>.selection;

	public void SelectAction<T>.select(T selection){
		this.selection = selection;
	}

}

Try this instead:

public aspect SelectAspect {
	private T SelectAction<T>.selection;

	// Template Method pattern:
	public void SelectAction<T>.select(T selection) {
		before(selection);
		this.selection = selection;
		after(selection);
	}

	// Must declare these default implementations public:
	public void before(T selection) {}
	public void after(T selection) {}
}



then:

public class StringSelectAction implements SelectAction<T>{...}

Causes StringSelectAction to inherit the select method correctly,
but what if I wanted to override the inherited method and say check
permissions before selecting an object?  I can't have:

public void select(String selection){
	checkPermissions(selection);
	super.select(selection);
}

Instead of overriding "select", override "before":

	public void before(String selection) {
		checkPermissions(selection);
	}



because the select method is not a member of the super class.  Is
there a syntax in AspectJ to indicate I want to call the inherited
method?  If not, what is the best practice for this type of thing?


This avoids having to call super. In fact, I almost always use
Template Method in cases like this, with pure objects, because calling
super is a bit of an "anti-pattern", because it would be easy to do
the wrong thing; (i) forget to call super, (ii) call it at the wrong
time, (iii) change the "contract" of the method unexpectedly, etc.
Template Method helps nail those problems down.

The two big drawbacks of this "trick" are (i) the Eclipse java editor
shows an error indicator on the class name, claiming that it needs to
implement the methods defined by the interface, even though everything
builds fine if you use ajc, (ii) it can be confusing to the person who
gets to maintain the code after you. ;)

dean



Back to the top