Click here to Skip to main content
15,887,776 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I'm still pretty new to using interfaces and I'm unsure if I'm using interfaces as they are intended. What should I do if I have properties in my interfaces that won't be used by the implementing class? What if I have I functionality that is generic - should I rather be using a base class or be implementing multiple interfaces? I'm really just asking for someone to confirm whether or not I'm on the right track here, because I feel like I'm missing something simple.

An example below:
C#
interface IPrinter
{
	string IPAddress { get; set; }
	
	void Print();
}

public class EthernetPrinter : IPrinter
{
	public string IPAddress { get; set; } // IPAddress
	public void Print() { Console.WriteLine("Printing over ethernet"); }
}

public class SerialPrinter : IPrinter
{
	public string IPAddress { get; set; } // Not going to be used. 
	public int CommPort { get; set; } // this is the actual property I need.
	public void Print() { Console.WriteLine("Printing serially"); }
}


And then use it like this. But aren't I supposed to be getting away from if statements with OO programming?

C#
IPrinter printer;

if (someSetting == "UseEthernet")
    printer = new EthernetPrinter() { IPAddress = "1.1.1.1" };
else
    printer = new SerialPrinter() { CommPort = 1 };

printer.Print();


What I have tried:

But then I see that I could be extracting the interfaces a little bit further to use the connection for other devices, but this doesn't feel much better.
C#
interface IDataSender
{
	void SendData();
}
interface ISerialDataSender : IDataSender
{
	int CommPort { get; set;}
}

interface IEthernetSender : IDataSender
{
	string IPAddress { get; set;}
}

interface IPrinter
{
	void Print();
}

public class EthernetPrinter : IPrinter, IEthernetSender
{
	// this looks good
	public string IPAddress { get; set; }
	public void Print() { Console.WriteLine("Printing over ethernet"); }
	
	// but this feels like this should be in some other class 
	//as this could be pretty generic to any ethernet device.
	public void SendData() 	{ }
}

public class SerialPrinter : IPrinter, ISerialDataSender
{
	// once again, this seems correct
	public int CommPort { get; set; }
	public void Print() { Console.WriteLine("Printing serially"); }

	// but this doesn't.
	public void SendData() {}

}
Posted
Updated 15-Nov-18 1:12am

An interface is just a guarantee that the class implements the properties\methods on the interface, there is nothing stopping the class using other properties and methods though. So I'd reduce your IPrinter interface to just the Print method.

interface IPrinter
{
	void Print();
}

public class EthernetPrinter : IPrinter
{
	public string IPAddress { get; set; }
	public void Print() { Console.WriteLine("Printing over ethernet"); }
}

public class SerialPrinter : IPrinter
{
	public int CommPort { get; set; }
	public void Print() { Console.WriteLine("Printing serially"); }
}


Your existing code will still work

IPrinter printer;

if (someSetting == "UseEthernet")
    printer = new EthernetPrinter() { IPAddress = "1.1.1.1" };
else
    printer = new SerialPrinter() { CommPort = 1 };

printer.Print(); // no matter what branch the "if" takes above you know that the object referenced by "printer" has a Print method and that's all you need to know


As for your "if" method, if you google the factory pattern that will show you how you can deal with that. You'll still have the "if" but it will be hidden inside a factory class which will leave your main code looking cleaner.
 
Share this answer
 
Quote:
What should I do if I have properties in my interfaces that won't be used by the implementing class?

You can't, that's the whole point.

Interfaces can't declare any concrete objects at all: all they can do is declare items which must be implemented by the class that inherits the interface. If you try to declare a property in your interface and give it any "real" definition:
public class EthernetPrinter : IPrinter
    {
    public string IPAddress { get; set; } // IPAddress
    public void Print() { Console.WriteLine("Printing over ethernet"); }
    }
Then you will get a compilation error.
If you fail to implement the property in derived classes, you will get a compilation error then as well.

If you need concrete objects, then you use an Abstract class instead.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900