Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Having trouble extracting a common interface

I would like to create a calculator application that can switch between different number bases. As far as entering digits is concerned, I was thinking the following would be a flexible api:

public interface ICalculator
{
    string Enter(INumberElement element);
}

public class BaseTenCalculator : ICalculator
{
    public string Enter(INumberElement element)
    {
        ...
    }
}

public class BaseTwoCalculator : ICalculator
{
    public string Enter(INumberElement element)
    {
        ...
    }
}

My problem is that for the BaseTenCalculator, I would like a method

Enter(BaseTenNumberElement element)

and for a BaseTwoCalculator, I would like a method

Enter(BaseTwoNumberElement element)

to make sure only valid digits for that number base get entered. However, the only way I can think of enforcing this constraint is downcasting the 'element' argument in the two different implementations, and throwing an exception if INumberElement is not of the correct type. I feel like this is 'wrong', and I'm missing something. Is there another way? Is it even possible to create a common interface for two different number base calculators?

like image 502
jmrah Avatar asked Mar 18 '14 00:03

jmrah


2 Answers

    public interface ICalculator<in T> where T : INumberElement
    {
        string Enter(T element);
    }

    public class BaseTenCalculator : ICalculator<BaseTenNumberElement> 
    {
        public string Enter(BaseTenNumberElement element)
        {
            throw new NotImplementedException();
        }
    }

    public class BaseTwoCalculator : ICalculator<BaseTwoNumberElement>
    {
        public string Enter(BaseTwoNumberElement element)
        {
            throw new NotImplementedException();
        }
    }
like image 170
DeveloperGuo Avatar answered Oct 15 '22 22:10

DeveloperGuo


I think you're thinking of the problem incorrectly. A number is a number regardless of base. Base is only a visible representation of the number. A good example to work from might be BigInteger. It has a constructor: BigInteger(String val, int radix), and a function: toString(int radix). All the work of representing the number is done the same. The only thing that differs is parsing from a string representation into the number, and then getting back out into a number format in a particular base.

You could create a multi-base calculator by using BigInteger or BigDecimal underneath and just using a base selection to set the radix value to parse or print the number(s). You'd also want to limit the input buttons (assuming you're using buttons), but that's really just a counting problem.

like image 36
user1676075 Avatar answered Oct 15 '22 20:10

user1676075