Abstract functions in child classes
Timon Gehr
timon.gehr at gmx.ch
Fri Dec 2 12:06:55 PST 2011
On 12/02/2011 09:05 PM, Timon Gehr wrote:
> On 12/02/2011 08:10 PM, Adam wrote:
>>
>>> A second possible use case:
>>>
>>> class C(T): T{
>>> // some declarations
>>> }
>>
>>> Now you really want that template to be instantiable with T being
>> either
>>> an abstract or a concrete class. Anything else is bound to become
>>> extremely annoying.
>>
>> Could you expand on this case a bit? I'm not sure I follow the point
>> one way or another.
>
> This is an useful pattern. I don't have a very useful example at hand,
> but this one should do. It does similar things that can be achieved with
> traits in Scala for example.
>
>
> import std.stdio;
> abstract class Cell(T){
> abstract void set(T value);
> abstract const(T) get();
> private:
> T field;
> }
>
> class AddSetter(C: Cell!T,T): C{
> override void set(T value){field = value;}
> }
> class AddGetter(C: Cell!T,T): C{
> override const(T) get(){return field;}
> }
>
> class DoubleCell(C: Cell!T,T): C{
> override void set(T value){super.set(2*value);}
> }
>
> class OneUpCell(C: Cell!T,T): C{
> override void set(T value){super.set(value+1);}
> }
>
> class SetterLogger(C:Cell!T,T): C{
> override void set(T value){
> super.set(value);
> writeln("cell has been set to '",value,"'!");
> }
> }
>
> class GetterLogger(C:Cell!T,T): C{
> override const(T) get(){
> auto value = super.get();
> writeln("'",value,"' has been retrieved!");
> return value;
> }
> }
>
> class ConcreteCell(T): AddGetter!(AddSetter!(Cell!T)){}
> class OneUpDoubleSetter(T): OneUpCell!(DoubleCell!(AddSetter!(Cell!T))){}
> class DoubleOneUpSetter(T): DoubleCell!(OneUpCell!(AddSetter!(Cell!T))){}
> void main(){
> Cell!string x;
> x = new ConcreteCell!string;
> x.set("hello");
> writeln(x.get());
>
> Cell!int y;
> y = new SetterLogger!(ConcreteCell!int);
> y.set(123); // prints: "cell has been set to '123'!
>
> y = new GetterLogger!(DoubleCell!(ConcreteCell!int));
> y.set(1234);
> y.get(); // prints "'2468' has been retrieved!"
>
> y = new AddGetter!(OneUpDoubleSetter!int);
> y.set(100);
> writeln(y.get()); // prints "202"
>
> y = new AddGetter!(DoubleOneUpSetter!int);
> y.set(100);
> writeln(y.get()); // prints "201"
>
> // ...
> }
Oh, forgot to mention: This would not compile, if an explicit 'abstract'
declaration on template class definitions was required.
More information about the Digitalmars-d-learn
mailing list