Jon
Jon

Reputation: 71

Passing an interface in Parameters C#

image


interface IBankAccount
{
    void PayIn(decimal amount);
    bool Withdraw(decimal amount);
    decimal Balance { get; }
}

interface ITransferBankAccount : IBankAccount
{
    bool TranferTo(IBankAccount destination, decimal amount);
}

class CurrentAccount : ITransferBankAccount
{    
    public bool TranferTo(IBankAccount destination, decimal amount)
    {
        bool result;
        result = Withdraw(amount);
        if (result)
        {
            destination.PayIn(amount);
        }
        return result;
    }      

    public decimal Balance
    {
        get
        {
            throw new NotImplementedException();
        }
    }

    public void PayIn(decimal amount)
    {
        throw new NotImplementedException();
    }

    public bool Withdraw(decimal amount)
    {
        throw new NotImplementedException();
    }

Demo Code showing This technique Thanks in Advance

Upvotes: 3

Views: 13346

Answers (3)

Christos
Christos

Reputation: 53958

You achieve to implement a principle that says

Program to an interface, not an implementation.

This has been introduced by GoF in their seminal book called Design Patterns. The benefits of adhering to such a practice are the following:

  • clients remain unaware of the specific types of objects they use, as long as the object adheres to the interface
  • clients remain unaware of the classes that implement these objects; clients only know about the abstract class(es) defining the interface

Based on the example you have posted we have two interfaces:

interface IBankAccount
{
    void PayIn(decimal amount);
    bool Withdraw(decimal amount);
    decimal Balance { get; }
}

interface ITransferBankAccount : IBankAccount
{
    bool TranferTo(IBankAccount destination, decimal amount);
}

The interface IBankAccount is composed from two methods and one property that each bank account should have (at least in the perspective of the author of this interface and the problem she/he tried to solve).

Specifically, we should be able to deposit money (PayIn) and withdraw money (Withdraw) from a bank account and last but not least to read the account's balance Balance.

Regarding the second interface, ITransferBankAccount this exhibits a behavior that only some accounts may have. This behavior is to transfer money. We could assume that there are two kinds of bank accounts those from which you can transfer money from one bank account to another and those that you can't, you can only deposit/withdraw from that specific bank account. It's just an assumption tied to this specific problem that Author of theses interfaces she/he tried to solve,

Even before we proceed to the CurrentAccount the benefits of interfaces are evident in the second interface !

We define a behavior, those of transferring money and we don't require the TranferTo method has as it's first parameter a custom type like CurrentAccount or another type. We just require that the first parameter of this method should implement the interface IBankAccount. Just this ! This is enough for us to transfer some money, since we can deposit money to an account by using the PayIn method.

Why the latter is important?

For instance let that we have 3 bank accounts A, B, C. Furthermore, let's assume that the account B and account C are different in terms of business. For instance whenever account B receives an amount of money we should do some extra actions if we compare it with account C. Definetely that means that in order to model this we should have two different classes. BankAccount_B and BankAccount_C. In addition to this let's suppose that whenever we Withdraw money from A to any other account we have to get a specific fee and apply some extra logic. That definitely means that bank account A should be modelled using another class. Let's call it BankAccount_A.

If we suppose that all these classes BankAccount_A, BankAccount_B and BankAccount_C implement the interface IBankAccount and the class BankAccount_A implements the interface ITransferBankAccount, then your can write code like this:

var bankAccountA = new BankAccount_A();

// Deposit $100 in Bank Account A
bankAccountA.PayIn(100);

var bankAccountB = new BankAccount_B();
var bankAccountC = new BankAccount_C();

// Transfer $ 60  to bank account B from A
bankAccountA.TransferTo(bankAccountB, 60);

// Transfer $ 40  to bank account B from A
bankAccountA.TransferTo(bankAccountC, 40);

Suppose that now you didn't have followed this principle and you wanted to implement the above functionality. In this case you should have defined two methods in class BankAccount_A. One for transferring money to bank accounts that are created using the BankAccount_B and one another for transferring money to bank accounts that are created using the BankAccount_C. And what about if you had another requirement for another account D in the future ? You should define another method etc...And this time you should violate one of the principles of SOLID, the Open/Closed principle, software entities … should be open for extension, but closed for modification. Had we used the interface we had been closed for modification :).

Upvotes: 7

geoyws
geoyws

Reputation: 3687

Basically, you can pass in any class that conforms to that interface.

Upvotes: 4

Zohar Peled
Zohar Peled

Reputation: 82524

Well, I was going to comment on Christos's answer but it's getting too long so I'll post this as a supplement answer:

To answer the question one must first understand what an interface is. Most developers will tell you that an interface is a contract for a class. If you ask them what that actually means, I'm not sure most of them will be able to explain it to a person that doesn't already have at least a basic understanding of object oriented programming.

So, what is a better explanation of an interface?
IMHO, an interface is best explained literaly - It's a list of guaranteed ways one can interact with an instance of a class that's implementing this interface. It's not a complete list - since nothing is stopping that class to add functionality such as method and properties beyond that interface, but - and that's the important part - it's guaranteed that each method, property, event or indexer on the interface is actually included in the class.

Why is that so important and how does it makes your life as a programmer better?
It's important since it means you can use interfaces instead of concrete implementations.
Why would you want to do that?

  • Because it enables you to expose as little information as possible to anyone that's using your method.
  • Because it means that everything implementing the interface can use this method (and as you can see from the explanation of interfaces, it is guaranteed to compile), meaning less limitation of using said method
  • Because whoever use your method doesn't need to know about concrete implementations. It only need to know the interface in order to use your method.
  • Because if your method was accepting class A as a parameter, and later on decided to add class B that will also use this method, you would have to write another method accepting B as a parameter. By using an interface as an argument for your method, all you need to do is have both A and B implement the same interface (and that could be a completely different implementation), and then simply pass A or B, since the both Are, by polymorphism, that interface.

Upvotes: 6

Related Questions