什么是接口和抽象类:
- 接口和抽象类都是“软件工程产物”
- 具体类->抽象类->接口:越来越抽象,内部实现的东西越来越少
- 抽象类是未完全实现逻辑的类(可以有字段和非public成员,它们代表了“具体逻辑”)
- 抽象类为复用而生:专门作为基类来使用,也具有解耦功能
- 封装确定的,开放不确定的,推迟到合适的子类中去实现
- 接口是完全为实现逻辑的”类“(”纯虚类“;只有函数成员;成员全部为public)
- 接口为解耦而生:”高内聚,低耦合“,方便单元测试
- 接口时一个”协约“,遭遇为工业生产所熟知(有分工必有协作,有协作必有协约)
- 它们都不能实例化,只能用来声明变量,引用具体类的实例
抽象类:
基类必须使用关键字abstract修饰,子类重写方法要用override,例子:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication7
{
class Program
{
static void Main(string[] args)
{
Vehicle v = new car();
v.Run();
}
}
abstract class Vehicle
{
public void Stop()
{
Console.WriteLine("Stopped!");
}
public void Fill()
{
Console.WriteLine("Pay and fill....");
}
public abstract void Run();
}
class car : Vehicle
{
public override void Run()
{
Console.WriteLine("Car is Runing....");
}
}
class Truck : Vehicle
{
public override void Run()
{
Console.WriteLine("Truck is Runing....");
}
}
}
添加接口:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication7
{
class Program
{
static void Main(string[] args)
{
Vehicle v = new car();
v.Run();
}
}
interface IVeicleBase
{
void Stop();
void Fill();
}
abstract class Vehicle : IVeicleBase
{
public void Stop()
{
Console.WriteLine("Stopped!");
}
public void Fill()
{
Console.WriteLine("Pay and fill....");
}
abstract public void Run();
}
class car : Vehicle
{
public override void Run()
{
Console.WriteLine("Car is Runing....");
}
}
class Truck : Vehicle
{
public override void Run()
{
Console.WriteLine("Truck is Runing....");
}
}
}
接口 要求 为纯虚函数,关键字为interface 而且接口函数的方法只写void Stop()就好了,没必要写其他修饰,写会报错的。
接口与单元测试
- 接口的产生:自底向上(重构),自顶向下(设计)
- C#中接口的实现(隐式,显式,多接口)
- 语言面对设计的内建支持:依赖反转,接口隔离,开/闭原则....
依赖类示例:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication7
{
class Program
{
static void Main(string[] args)
{
Engine engine = new Engine();
Car car = new Car(engine);
car.Run(3);
Console.WriteLine(car.Speed);
}
}
class Engine
{
public int RPM { get; private set; }
public void Work(int gas)
{
this.RPM = 1000 * gas;
}
}
class Car
{
private Engine _engine;
public Car(Engine engine)
{
_engine = engine;
}
public int Speed { get; private set; }
public void Run(int gas)
{
_engine.Work(gas);
this.Speed = _engine.RPM / 100;
}
}
}
使用接口实现松耦合
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication7
{
class Program
{
static void Main(string[] args)
{
var user = new PhoneUser(new NokiaPhone());
user.UserPhone();
var user1 = new PhoneUser(new EricssonPhone());
user1.UserPhone();
}
}
interface Iphone
{
void Dail();
void PickUp();
void Receive();
void send();
}
class PhoneUser
{
private Iphone _phone;
public PhoneUser(Iphone phone)
{
_phone = phone;
}
public void UserPhone()
{
_phone.Dail();
_phone.PickUp();
_phone.Receive();
_phone.send();
}
}
class NokiaPhone : Iphone
{
public void Dail()
{
Console.WriteLine("Nokia calling....");
}
public void PickUp()
{
Console.WriteLine("Hello! This is Tim!");
}
public void Receive()
{
Console.WriteLine("Nokia message ring....");
}
public void send()
{
Console.WriteLine("Hello");
}
}
class EricssonPhone : Iphone
{
public void Dail()
{
Console.WriteLine("Ericsson calling....");
}
public void PickUp()
{
Console.WriteLine("Hello! This is Tim!");
}
public void Receive()
{
Console.WriteLine("Ericsson message ring....");
}
public void send()
{
Console.WriteLine("Ericsson");
}
}
}