面象对象的基本原则就是针对抽象编程,而不是针对实现编程,为了取得更大的灵活性.
而java,C#等面向对象语言支持抽象的机制为 抽象类和接口,接口拥有更大的灵活性.
我举一个小例子,不太完善,希望能给你一些启发.
比如我们要做一个购书系统,购书后,需要进行打折,我们就来实现打折这一部分:
using System;
namespace InterfaceSample
{
// 表示一本书
class Book
{
// 书名
public string Name;
// 价格
public decimal Money;
}
//书价打折接口(接口就像一个协议,你不用知道协议后面是什么,只需要知道它遵守了这个协 议),在这里,我们只知道这个接口会进行 打折计算
interface IBookMoneyComputer
{
//计算书价
/// <param name="books">要计算价格的书目</param>
/// <param name="totalMoney">书的总价格(打折前的)</param>
decimal Compute(Book[] books, decimal totalMoney);
}
//我们来实现两个打折器(构造两个类来实现IBookMoneyComputer接口)------------------
// 总价打折器,只要书总价超过500, 我们就给它减去100
class TotalMoneyComputer : IBookMoneyComputer
{
public decimal Compute(Book[] books, decimal totalMoney)
{
if (totalMoney > 500)
return totalMoney - 100;
return totalMoney;
}
}
// 书类别打折器,只要有一本书名为"DotNet",我们就给总价减去50
class BookTypeComputer : IBookMoneyComputer
{
public decimal Compute(Book[] books, decimal totalMoney)
{
foreach (Book book in books)
{
if (book.Name == "DotNet")
return totalMoney - 50;
}
return totalMoney;
}
}
//----------------------------------------------------------------
class Class1
{
// 静态方法,接受一个book数组,和一个打折器,注意,我们这个参数是接口类型
static decimal ComputeMoney(Book[] books, IBookMoneyComputer computer)
{
//注意,这里的计算打折前的总价程序不需要进行抽象
decimal totalMoney = 0m;
foreach (Book book in books)
{
totalMoney += book.Money;
}
//用接口类型进行打折,这样有很大的灵活性,可以随时更改打折策略
return computer.Compute(books, totalMoney);
}
/// 应用程序的主入口点。
[STAThread]
static void Main(string[] args)
{
//我们来购造三本书
Book book1 = new Book();
book1.Name = "aaa";
book1.Money = 200;
Book book2 = new Book();
book2.Name = "bbb";
book2.Money = 400;
Book book3 = new Book();
book3.Name = "DotNet";
book3.Money = 200;
//可以分别运行两种打折策略来进行打折
Console.WriteLine(ComputeMoney(new Book[] { book1, book2, book3 }, new TotalMoneyComputer()));
Console.WriteLine(ComputeMoney(new Book[] { book1, book2, book3 }, new BookTypeComputer()));
Console.Read();
}
}
}
----------------------------
给不是你设计得程序调用。
----------------------------
比如一个方法里面有读数据库的需要,传入参数为IDataReader接口
实际调用时,可以传入SqlDataReader对象,也可以传入OracleDataReader对象
数据库由SQLserver变为Oracle,此方法不需要作任何修改
------------------------------------------------
如果直接在类中硬编码ConvertToInt 则对其产生依赖
假定ConvertToInt()是复杂业务逻辑经常可变
实现了该接口的类在定义 ConvertToInt时 与实际调用不发生耦合
ItoInt ii = new ItoIntImplOne();
ii.ConvertToInt();
与
ItoInt ii = new ItoIntImplTwo();
ii.ConvertToInt();
区别在于你接口变量 指向了哪个引用
再结合控制反转容器 则变为
ItoInt ii = AppContext.getBean("ItoIntImpl");
ii.ConvertToInt();
就将可能产生的变化不通过hardcode的形式写在程序里而放在配置文件中
光为了用而用接口是没有意义的,有良好的程序层次划分才能享受到面向接口编程带来的好处咯
----------------------------------------------------------------
接口就好比电源插头,只要你支持这个接口,就是你有这个的电源插头,你就可以插到任何插排上,而不管你这个东西是电视、冰箱、还是电脑,都可以用。
--------------------------------------------------------
代码规范化,不会出现一样的功能有几种命名,还有就是间接地实现了多继承
---------------------------------------------------------------
一般情况下接口是应该和其相关类分开在不同的应用程序域中保证用户只是在使用自定义类的一个代理,很好的保证了代码的封装性,另外接口是可以多重继承的
--------------------------------------------
接口是对业务逻辑的抽象,类是业务规则的一种实现,是具体化。一个类可以实现多种业务规则,也就是多个接口。将接口和类分离,是为了适应业务的变化
------------------------------------------
个人认为接口的好处就是 便于重用
其实有些东西或许并没有你想象的那么复杂,现实生活中接口的例子也很多,例如插座,不管是电视机,还是冰箱,微波炉的插头都是可以插上去的,因为插头的规格是统一的(也就是接口),家电只要遵循插头的规格,就可以接到插座上去
------------------------------------------
接口在重用,便利,规范,多态等方便都有很好的用处,但这要有经验才会体会的深刻...
除非了这些,我举一个具体的:
现在的软件不是一个人完成的,大家都知道
所以程序员中就有软件架构师,软件工程师,普通程序员等(随便分一下类的)
总之,有层次...
那么,软件架构师,软件工程师等就会设计软件的整个架构和(或)类设计等等
这样,只要定义接口,扔给下面的人去做具体的实现就可以了...