Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change parameter type when implementing an abstract method

Is there some way to define an abstract type as a parameter in an abstract method, and when that method is implemented in a derived class, you change the type of the method to accept a derived type?

Code:

public abstract class ProductBase
{
}

public class SomeProduct
    : ProductBase
{

}

public abstract class A
{
    protected abstract void addProduct(ProductBase p);
}

// This works
public class B : A
{        
    protected override void addProduct(ProductBase p)
    {
        // Do some work
    }
}

// This is what I'd like to do
public class C : A
{
    // Compiler error here because I have accepted a SomeProduct and not a ProductBase
    protected override void addProduct(SomeProduct p)
    {
        // Do some work on the specialisation - I can use the SomeProduct directly
    }
}

In my head, it makes some kind of sense. An abstract class indicating there is a method which derived classes must implement, but they can change the type of object passed in as a parameter, so long as it is from the same inheritance chain...

What I have ended up doing, is to remove the abstract method AddProduct from the abstract class, and instead just implementing it in the derived class anyway, but there's then no contract for other classes in the future that they must create their own implementation of AddProduct. And it doesn't feel right.

I hope this makes sense. Apologies if this is a duplicate question but I couldn't find anything by searching.

Thanks,
bgs264

like image 956
bgs264 Avatar asked Jun 13 '12 12:06

bgs264


1 Answers

You can make your A class to generic and use the generic argument in your addProduct method:

public abstract class A<TProduct> where TProduct : ProductBase 
{
    protected abstract void addProduct(TProduct p);
}

public class B : A<ProductBase>
{        
    protected override void addProduct(ProductBase p)
    {
    }
}

public class C : A<SomeProduct>
{
    protected override void addProduct(SomeProduct p)
    {
    }
}
like image 73
nemesv Avatar answered Sep 22 '22 12:09

nemesv