违反接口隔离原则的例子一:
我们假设一个人会开汽车卡车坦克(但是不会开炮),我们先设置以下类
Vehicle类型
interface IVehicle
{
void Run();
}
class Car:IVehicle
{
public void Run()
{
Console.WriteLine("Car is Running");
}
}
class Truck:IVehicle
{
public void Run()
{
Console.WriteLine("Truck is Running");
}
}
Tank类型
interface ITank
{
void Fire();
void Run();
}
class Type99 : ITank
{
public void Fire()
{
Console.WriteLine("Boom!");
}
public void Run()
{
Console.WriteLine("Ka!");
}
}
这时候我们如果要人开Vehicle类的Car或者Truck,那么这个人就不能开Tank。
class Driver
{
private IVehicle _vehicle;
public Driver(IVehicle vehicle)
{
_vehicle = vehicle;
}
public void Drive()
{
_vehicle.Run();
}
}
class Program
{
static void Main(string[] args)
{
var driver = new Driver(new Car());
driver.Drive();
}
}
如果让他开Tank,则他不能开Vehicle
class Driver
{
private ITank _tank;
public Driver(ITank tank)
{
_tank = tank;
}
public void Drive()
{
_tank.Run();
}
}
class Program
{
static void Main(string[] args)
{
var driver = new Driver(new Type99());
driver.Drive();
}
}
仔细看会发现,type99(99式坦克)中的Fire()作为实例方法缺从未被使用过,违背了"类不应该被迫依赖他们不使用的方法"这条原则。
Tank里面有作为Vehicle的Run()方法,和不属于Vehicle的Fire()方法。这使得Tank这个接口太大无法用Vehicle来囊括。
解决方式是把Tank这个接口拆分成两个接口,
分别是作为交通工具的IVehicle和作为武器的IWeapon。
纠正方式:
ITank接口去继承这两个接口,它就是简单的把这两个接口结合起来,这就是一个接口对其他多个接口的继承。
C#中当类和类继承时,只允许存在一个父类(基类),但是当你拿一个类/接口去继承接口的时候,可以有多个父接口(基接口)
interface IVehicle
{
void Run();
}
interface IWeapon
{
void Fire();
}
interface ITank:IVehicle,IWeapon
{
}
class Type99 : ITank
{
public void Fire()
{
Console.WriteLine("Boom!");
}
public void Run()
{
Console.WriteLine("Ka!");
}
}
class Program
{
static void Main(string[] args)
{
var drivercar = new Driver(new Car());
drivercar.Drive();
var drivertruck = new Driver(new Car());
drivertruck.Drive();
var drivertank = new Driver(new Type99());
drivertank.Drive();
}
}
这样就Car,Truck,Tank都可以开了。