Expert wanna be
Expert wanna be

Reputation: 10624

C#, Using Interface

I'm trying to use Interface class and I have a question about Interface method parameters.

I have an Interface class to make child class use specific method. but the child classes need different number of parameters for the method.

Example,

public interface IPayment
{
  void MakePayment();
}

and define the MakePayment method in child classes.

public class PayPay : IPayment
{
  public void MakePayment(string a); // it needs only one parameter
}

public class Google : IPayment
{
  public void MakePayment(string a, int b); // it needs two parameters.
}

Like above case, How can I modify my interface class?

Thank you!

Upvotes: 2

Views: 3395

Answers (7)

phoog
phoog

Reputation: 43046

Do your PayPay and Google classes represent the data necessary to describe a payment? Normally, a Payment class should represent a payment. If the class's job is to process payments, it should probably have a name like PaymentProcessor, and its interface something like IPaymentProcessor (or indeed IPaymentService, or something similar).

If the payment classes represent actual payments, then the class should not need any parameters to its MakePayment() method; instead, it would rely on the instance data to describe the payment being made.

Alternatively, you could have something like this (still using Payment to describe the payment itself):

interface IPaymentProcessor<T> where T : IPayment
{
    void ProcessPayment(T payment);
}
class PayPayPaymentProcessor : IPaymentProcessor<PayPay>
{
    void ProcessPayment(PayPay payment) { /* some implementation here */ }
}
class PayPayPaymentProcessor : IPaymentProcessor<Google>
{
    void ProcessPayment(Google payment) { /* some implementation here */ }
}

I would probably name the classes PayPayPayment and GooglePayment so the names more clearly represent the type:

class PayPayPaymentProcessor : IPaymentProcessor<PayPayPayment>
{
    void ProcessPayment(PayPayPayment payment) { /* some implementation here */ }
}
class PayPayPaymentProcessor : IPaymentProcessor<GooglePayment>
{
    void ProcessPayment(GooglePayment payment) { /* some implementation here */ }
}

Note that this is very similar to the approach other suggested of using a PaymentParameters class, but it adheres more closely to the single responsibility principle. In Brian Cauthon's answer, the PaymentParameters class has to hold the union of all possible parameters for any type of payment; here, the parameter types can (and should) be specific to the needs of the payment they represent.

Upvotes: 4

Brian Cauthon
Brian Cauthon

Reputation: 5534

Change your interface to use a PaymentParameters class that contains all the parameters each different service might need.

public interface IPayment 
{ 
   void MakePayment(PaymentParameters p);   
} 

public class PaymentParameters{
    public string A { get; set; }
    public int B { get; set; }
}

Your Google and PayPay implementations will use only the needed parameters from PaymentParameters.

Upvotes: 6

Glen J Fergo
Glen J Fergo

Reputation: 134

Straight from MSDN -

An interface contains only the signatures of methods, delegates or events

The signature of a method consists of the name of the method and the type and kind (value, reference, or output) of each of its formal parameters, considered in the order left to right

If you don't provide the implementation for the method (including the type and kind of each parameter), then you haven't really 'implemented' the Interface.

Good luck! :)

Glen

Upvotes: 0

Baptiste Pernet
Baptiste Pernet

Reputation: 3384

Well, the principe of the interface is to not know about the implementation. So the caller of the interface won't know if it is a Google of PayPay sub class and will always call the same method.

But if you have more complex parameters, you should use IPaymentParameters and a method with this prototype

public interface IPayment
{
     void MakePayment(IPaymentParameters parameters);
}

And two implementations GooglePayementParameters and PayPayPaymentParameters

Upvotes: 5

Tomtom
Tomtom

Reputation: 9394

If you use .NET 4.0 than you can give your Interface-Method default-values

public interface ITest{
void Function(stirng s1, string s2 = "");
}

Upvotes: 1

daryal
daryal

Reputation: 14919

You can either define two interfaces, or use the following;

public interface IPayment
{
    void MakePayment(string a, int b=0);
}

When you only pass the string parameter, the method will set b to 0; you can just ignore it.

Upvotes: 3

Francis P
Francis P

Reputation: 13655

A clean method could be to simply use a PaymentParameters class and use a single method called public void MakePayment(PaymentParameters params);

Upvotes: 8

Related Questions