不明白接口到底有什么用途。
只讨论接口的方法,假设c#同样支持类的多继承(当然这个假设是错误的),目的是排除接口的多继承特点。
首先继承类必须实现接口的方法,在编译的时候必须去实现结构。那么可以在类中直接声明一个接口。
我实在搞不明白其中的机制。
只讨论接口的方法,假设c#同样支持类的多继承(当然这个假设是错误的),目的是排除接口的多继承特点。
首先继承类必须实现接口的方法,在编译的时候必须去实现结构。那么可以在类中直接声明一个接口。
我实在搞不明白其中的机制。
我声明一个IUser这样的接口,只有一个方法就是获取用户名称
public interface IUser
{
string getUserName();
}
业务逻辑在使用时只对接口进行操作string UserName=user.getUserName();(user是IUser类型)
好,假设我当前要实现的是对SqlServer进行操作读取用户名称
public class SqlUser:IUser
{
public string getUserName(){....}
}
如果有一天要换成Oracle的话怎么办呢?如果是你的业务逻辑在调用用户名称都是针对接口编程的话,那么很简单,你只要加一个实现类和更改你的配置即可
public class OracleUser:IUser
{
public string getUserName(){....}
}
你的业务逻辑一字也不用动。
这个IUser接口完全可以用虚类来代替. (这样和用interface有什么区别吗?? )public abstract class IUser
{
public abstract string getUserName();
}
public class SqlUser:IUser
{
public string getUserName(){....}
}
public class OracleUser:IUser
{
public string getUserName(){....}
}
(难道效果不同吗? 不可能~!~)
interface从名字去理解,是界面的意思,你可以理解成两个互不相关的东西的一个中介,
,所以也叫借口,从本质上说,真的和多重继承没有什么关系(个人理解)
你可以当作一种协议,任何实现了一个interface的类,都可以当作实现了一个协议
你调用interface的方法的时候,不要考虑具体是什么,而只要理解这个协议是什么。
举一个简单的应用你开发了一个类库,你要使用一些资源比方说LOG用的,但是
你不知道这个东西发布出去,用户会用在什么地方,你要想在内部实现你的
logic,这个logic又要调用外部的资源(这个资源又是调用你的人实现)
,一个非常地好的办法就是你define一个
interface,调用你的方法的程序必须实现这个interface,OK,这时候你就建立了
从内部到外部的一个调用,而不用管最终用户到底是怎么实现这个interface的。从本质上说调用接口的方法应该是最快的。
interface UI
{
void show();
}interface IUser
{
string getUserName();
}Abstract absUser:UI,IUser
{
//实现它们
}那么,给UI部分使用 (UI类型)userUi.Show();他并不知道有 getUserName这个方法。
给功能 的部分 (IUser类型) user.getUserName();他不用关心有UI这个接口和去show()这只是一个小例子,当然有更好的方法去解决这些问题,如果深入些可以看看Ecilpse的无限扩展,用到其它的方法解决。
{
// 表示一本书
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();
}
}
}
在上面的代码,由其是Main方法的实现,这样写有什么好处?