〇、引言
接口,属于方法的抽象,它只定义方法,而不包含任何实现,既然没有实现,接口存在的意义是什么呢?
接口实际上是一种契约或者约定,例如,插头有三脚的,有两脚的,但他们都有一个相同的功能,就是绝缘与通电,这也是全世界的插头所共同遵守的规则。此时,我可以定义一个约定,说:凡是设计插头的都要遵守以下约定:提供绝缘的办法,提供通电的办法。对应到C#中,就是在接口中定义两个函数,一个为绝缘,一个为通电。所有插头的类都要继承这个接口,这样就会强迫所有类实现绝缘与通电两个方法,而具体如何实现,则因不同插头而不同。
一、接口实现多态。
多态是面向对象编程中十分重要的一个性质,它的设计思想是:只有对象自己知道具体如何执行特定的操作,通过规定 执行这些操作的通用方式,还可以促进了代码重用。例如每种文档都有自己的打印方式,但是不应该定义switch来选择不同的文档不同输出,而应该利用多态性,在基类中设计Print(); 当有需要打印任务时候就调用Print()。
多态可以使用类的继承很容易的实现,但是多态也可以利用接口实现。代码如下:
1、首先定义一个接口,功能是返回一组字符串,代表着信息。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 // <copyright file="IListable.cs" company="TNT"> 2 // Copyright (c) TNT. All rights reserved. 3 // </copyright> 4 // <author>Li Mingjian</author> 5 // <date> 2014-11-14 </date> 6 // <summary>显示一行数据的接口</summary> 7 namespace InterfaceMultiState 8 { 9 using System; 10 using System.Collections.Generic; 11 using System.Linq; 12 using System.Text; 13 14 /// <summary> 15 /// A interface of show a row data 16 /// </summary> 17 /// <see cref=""></see> 18 /// <remarks> 19 /// <c>创建人:Li 20 /// 创建日期:2014-11-14 21 /// 版本:1.0</c> 22 /// </remarks> 23 interface IListable 24 { 25 // 返回一行中的每一列数据 26 string[] Columnvalues 27 { 28 get; 29 } 30 } 31 }
然后,将会继续写两个类:Contact与Publishion,显然一个是关于人员的,一个是关于书籍的,这两个类都继承接口IListable,当需要输出信息时,直接利用接口的多态,将类的实例转型为接口类型,统一输出。接口实例便实现多态,在找对应的输出。
2、定义Contact类,其从抽象类PdaItem抽象而来,同时继承接口IListable:
PdaItem如下:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 // <copyright file="PdaItem.cs" company="TNT"> 2 // Copyright (c) TNT. All rights reserved PdaItem.cs. 3 // </copyright> 4 // <author>Li Mingjian</author> 5 // <date> 2014-11-14 </date> 6 // <summary>联系人抽象类</summary> 7 namespace InterfaceMultiState 8 { 9 using System; 10 using System.Collections.Generic; 11 using System.Linq; 12 using System.Text; 13 14 /// <summary> 15 /// A abstract class of contact or others 16 /// </summary> 17 /// <see cref=""></see> 18 /// <remarks> 19 /// <c>创建人:Li 20 /// 创建日期:2014-11-14 21 /// 版本:1.0</c> 22 /// </remarks> 23 public abstract class PdaItem 24 { 25 /// <summary> 26 /// <c>Initializes a new instance of the PdaItem class.</c> 27 /// </summary> 28 /// <param name="name">The name</param> 29 public PdaItem(string name) 30 { 31 } // PadItem 32 33 /// <summary> 34 /// Gets or sets virtual attribute:Name 35 /// </summary> 36 public virtual string Name { get; set; } 37 } // class 38 } // namespace InterfaceMultiState
Contact类如下:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 // <copyright file="Contact.cs" company="TNT"> 2 // Copyright (c) TNT. All rights reserved Contact.cs. 3 // </copyright> 4 // <author>Li Mingjian</author> 5 // <date> 2014-11-14 </date> 6 // <summary>联系人抽象类</summary> 7 namespace InterfaceMultiState 8 { 9 using System; 10 using System.Collections.Generic; 11 using System.Linq; 12 using System.Text; 13 14 /// <summary> 15 /// A Contact class with set and show member information 16 /// </summary> 17 /// <see cref=""></see> 18 /// <remarks> 19 /// <c>创建人:Li 20 /// 创建日期:2014-11-14 21 /// 版本:1.0</c> 22 /// </remarks> 23 internal class Contact : PdaItem, IListable 24 { 25 /// <summary> 26 /// Initializes a new instance of the Contact class. 27 /// </summary> 28 /// <param name="firsteName">The firstname</param> 29 /// <param name="lastName">The lastname</param> 30 /// <param name="address">The address</param> 31 /// <param name="phone">The phone</param> 32 public Contact(string firsteName, string lastName, string address, string phone) 33 : base(null) 34 { 35 this.FirstName = firsteName; 36 this.LastName = lastName; 37 this.Address = address; 38 this.Phone = phone; 39 } // public Contact() 40 41 /// <summary> 42 /// Gets Header include: First Name. Last Name. Phone. Address 43 /// </summary> 44 public static string[] Headers 45 { 46 get 47 { 48 return new string[] 49 { 50 "First Name ", "Last Name ", 51 "Phone ", 52 "Address " 53 }; // return 54 } 55 } // Headers 56 57 /// <summary> 58 /// Gets or sets firstname 59 /// </summary> 60 public string FirstName { get; set; } 61 62 /// <summary> 63 /// Gets or sets lastname 64 /// </summary> 65 public string LastName { get; set; } 66 67 /// <summary> 68 /// Gets or sets address 69 /// </summary> 70 public string Address { get; set; } 71 72 /// <summary> 73 /// Gets or sets phone 74 /// </summary> 75 public string Phone { get; set; } 76 77 /// <summary> 78 /// Gets information of member 79 /// </summary> 80 public string[] Columnvalues 81 { 82 get 83 { 84 return new string[] 85 { 86 this.FirstName, 87 this.LastName, 88 this.Phone, 89 this.Address 90 }; // return 91 } // get 92 } // Columbalues 93 } // class Contact 94 } // namespace InterfaceMultiState
3、定义publishtion类,继承接口IListable
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 // <copyright file="Publication.cs" company="TNT"> 2 // Copyright (c) TNT. All rights reserved Publication.cs. 3 // </copyright> 4 // <author>Li Mingjian</author> 5 // <date> 2014-11-14 </date> 6 // <summary>联系人抽象类</summary> 7 namespace InterfaceMultiState 8 { 9 using System; 10 using System.Collections.Generic; 11 using System.Linq; 12 using System.Text; 13 14 /// <summary> 15 /// A Publication class with set and show books information 16 /// </summary> 17 /// <see cref=""></see> 18 /// <remarks> 19 /// <c>创建人:Li 20 /// 创建日期:2014-11-14 21 /// 版本:1.0</c> 22 /// </remarks> 23 internal class Publication : IListable 24 { 25 /// <summary> 26 /// Initializes a new instance of the Publication class 27 /// </summary> 28 /// <param name="title">The title of book</param> 29 /// <param name="author">The author</param> 30 /// <param name="year">The year of published</param> 31 public Publication(string title, string author, int year) 32 { 33 this.Title = title; 34 this.Author = author; 35 this.Year = year; 36 } 37 38 /// <summary> 39 /// Gets Header include: Title Author Year 40 /// </summary> 41 public static string[] Headers 42 { 43 get 44 { 45 return new string[] 46 { 47 "Title ", 48 "Author ", 49 "Year" 50 }; // return 51 } 52 } // Headers 53 54 /// <summary> 55 /// Gets or sets title 56 /// </summary> 57 public string Title { get; set; } 58 59 /// <summary> 60 /// Gets or sets author 61 /// </summary> 62 public string Author { get; set; } 63 64 /// <summary> 65 /// Gets or sets year 66 /// </summary> 67 public int Year { get; set; } 68 69 /// <summary> 70 /// Gets information of book 71 /// </summary> 72 public string[] Columnvalues 73 { 74 get 75 { 76 return new string[] 77 { 78 this.Title, 79 this.Author, 80 this.Year.ToString(), 81 }; // return 82 } // get 83 } // Columbalues 84 } // class 85 } // namespace InterfaceMultiState
4、编写一个输出类,用来控制输出,这个类提供了一个对外的静态函数
1 public static void List(string[] headers, IListable[] items)
用来根据传入的参数进行输出,注意第二个参数的类型,是一个接口类型。此类的重点是如何输出items.Columnvalues
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 // <copyright file="ConsoleListControl.cs" company="TNT"> 2 // Copyright (c) TNT. All rights reserved ConsoleListControl.cs. 3 // </copyright> 4 // <author>Li Mingjian</author> 5 // <date> 2014-11-14 </date> 6 // <summary>联系人抽象类</summary> 7 namespace InterfaceMultiState 8 { 9 using System; 10 using System.Collections.Generic; 11 using System.Linq; 12 using System.Text; 13 14 /// <summary> 15 /// out put string[] to console 16 /// </summary> 17 /// <see cref=""></see> 18 /// <remarks> 19 /// <c>创建人:Li 20 /// 创建日期:2014-11-14 21 /// 版本:1.0</c> 22 /// </remarks> 23 internal class ConsoleListControl 24 { 25 /// <summary> 26 /// out put information to console 27 /// </summary> 28 /// <param name="headers">The headers</param> 29 /// <param name="items">A group of item</param> 30 public static void List(string[] headers, IListable[] items) 31 { 32 int[] columWidths = DisplayHeader(headers); 33 34 for (int count = 0; count < items.Length; count++) 35 { 36 string[] values = items[count].Columnvalues; 37 38 DisplayItemsRow(columWidths, values); 39 } // for 40 } // List 41 42 /// <summary> 43 /// out put headers to console 44 /// </summary> 45 /// <param name="headers">The header of one entity</param> 46 /// <returns type="int[]">The columWidth</returns> 47 private static int[] DisplayHeader(string[] headers) 48 { 49 int[] columWidth = new int[headers.Length]; 50 string head = string.Empty; 51 52 for (int count = 0; count < headers.Length; count++) 53 { 54 head += headers[count]; 55 columWidth[count] = headers[count].Length; 56 } // for 57 58 Console.WriteLine(head); 59 60 return columWidth; 61 } // DisplayHeader 62 63 /// <summary> 64 /// out put items' value to console 65 /// </summary> 66 /// <param name="columWidth">The columWidth</param> 67 /// <param name="values">Item values</param> 68 private static void DisplayItemsRow(int[] columWidth, string[] values) 69 { 70 string value = string.Empty; 71 72 for (int count = 0; count < values.Length; count++) 73 { 74 int strLen = values[count].Length; 75 values[count] = values[count].PadRight(columWidth[count]); 76 value += values[count]; 77 } // for 78 79 Console.WriteLine(value); 80 } // DisplayItemsRow 81 } // class 82 }
5、主函数中:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 // <copyright file="Program.cs" company="TNT"> 2 // Copyright (c) TNT. All rights reserved Program.cs. 3 // </copyright> 4 // <author>Li Mingjian</author> 5 // <date> 2014-11-14 </date> 6 // <summary>联系人抽象类</summary> 7 namespace InterfaceMultiState 8 { 9 using System; 10 using System.Collections.Generic; 11 using System.Linq; 12 using System.Text; 13 14 /// <summary> 15 /// A access of the whole project 16 /// </summary> 17 /// <see cref=""></see> 18 /// <remarks> 19 /// <c>创建人:Li 20 /// 创建日期:2014-11-14 21 /// 版本:1.0</c> 22 /// </remarks> 23 public class Program 24 { 25 /// <summary> 26 /// entry of process 27 /// </summary> 28 /// <param name="args">The args</param> 29 private static void Main(string[] args) 30 { 31 Contact[] contacts = new Contact[6]; 32 contacts[0] = new Contact("Dick", "Traci", "123. Main St.", "123-123-1234"); 33 contacts[1] = new Contact("Aick", "Traci", "123. Main St.", "123-123-1234"); 34 contacts[2] = new Contact("Bick", "Traci", "123. Main St.", "123-123-1234"); 35 contacts[3] = new Contact("Cick", "Traci", "123. Main St.", "123-123-1234"); 36 contacts[4] = new Contact("Eick", "Traci", "123. Main St.", "123-123-1234"); 37 contacts[5] = new Contact("Fick", "Traci", "123. Main St.", "123-123-1234"); 38 39 // 将类的实例当作接口类型传入 40 ConsoleListControl.List(Contact.Headers, contacts); 41 42 Publication[] publicatons = new Publication[3]; 43 publicatons[0] = new Publication("HerryPotter", "Luolin", 1998); 44 publicatons[1] = new Publication("XiYou", "WuChengEn", 1326); 45 publicatons[2] = new Publication("DaXue", "Unkonwn", 239); 46 47 // 将类的实例当作接口类型传入,包含了一次隐式转型 48 ConsoleListControl.List(Publication.Headers, publicatons); 49 } // Main 50 } // class 51 } // namespace InterfaceMultiState
注意到里面的:
1 // 将类的实例当作接口类型传入 2 ConsoleListControl.List(Contact.Headers, contacts);
第二个参数是接口类型,显然存在一次转型,而输出的时候确实是按照contact的形式输出的。
输出结果如下: