abstract class declaring a derived class as a return

I almost had a bit of a problem when turning an interface into an abstract class. Basically I wanted it to provide an implementation (which is why I changed it to abstract), however since it was mutable and therefore returning itself the abstract class caused problems for any code that implemented the derived class.

abstract class Abstract {
	public Abstract mutableMethod (){
		return createInstance ().doSomething();
	}
}

abstract class Derived extends Abstract {
	public Derived doSomething (){
		...
	}
}

class Main {
	void poorMethod (){
		// problem !!!
		Derived derived = new Derived().doSomething();
	}
}

However using templates you can eliminate this problem without overriding every method or making main look weirder in any way.

abstract class Abstract <DerivedClass extends Abstract> {
	public DerivedClass mutableMethod (){
		return createInstance ().doSomething();
	}
}

abstract class Derived extends Abstract <Derived> {
	public Derived doSomething (){
		...
	}
}

class Main {
	void poorMethod (){
		// no more problem !!!
		Derived derived = new Derived().doSomething();
	}
}

note that you cannot namely instantiate an abstract-class, but you must use a non-abstract extending class or an anonymous instanciation… :wink:

Yes, that was the aim. Basically it is for an implementation of a tone generator - at first I had a oscillator interface. As soon as I created another waveform it was more than obvious to keep a majority of the implementation in the oscillator since very little is going to change between the sub classes other than what it thinks is at a particular phase.

In fact the only abstract methods in Oscillator are getAmplitude and createInstance. createInstance is there so that the abstract Oscillator can still provide implementations to mutable methods. Also I amended the example so that you can not later create an error by doing something like “class Derived extends Abstract”.

Disclaimer: this is not for anything sound related, other than the fact that you could use some principles. It’s for a game involving waves!

Hi,

I have been using this pattern for year, and there is something you need to realize:

It is not because you write :

public abstract class X<C extends X> {…}

… that you should suppose that X will always be used like that:

public class A extends X {…}

It could also be used like that:

public class B extends X {…}