-
接口的使用。接口是一组方法的声明,方法实现在继承类中实现。
-
接口与抽象类的区别:
抽象类是对类抽象,提取出共有的特性。继承抽象类的类 属于(is)《= 抽象类;
类实现接口,只是代表此类具有接口声明的方法。是一种can-do的关系 -
接口的的特点:interface
a. 如果基类实现了接口,则继承类继承这个实现。
b. 实现接口的类,必须实现这个接口实现的所有方法
c. 接口可以包含事件,方法,属性
d. 接口不包含实现的方法
e. 类或结构可以实现多个接口
代码示例:
using System;
namespace classTest018
{
/// <summary>
/// 测试接口与抽象类使用
/// </summary>
class Animal//基类
{
public virtual void Eat()//virtual--可以重写的方法
{
Console.WriteLine("动物觅食!!");
}
public virtual void Walk()
{
Console.WriteLine("动物行走!!");
}
public virtual void Voice()
{
Console.WriteLine("动物的叫声!!");
}
}
interface IShow //接口声明
{
void Show();
}
class dog : Animal, IShow//派生类
{
public override void Voice()
{
Console.WriteLine("小狗的叫声:汪汪汪");
}
public override void Eat()
{
base.Eat();//调用基类方法
Console.WriteLine("小狗爱吃骨头");
}
public override void Walk()
{
base.Walk();//调用基类方法
Console.WriteLine("小狗跑的很快");
}
void IShow.Show()//实现接口成员
{
Console.WriteLine("小狗会表演魔术!");
}
}
//当两个接口中定义相同的方法时,继承类可通过显示实现接口,来调用方法。
interface IChineseGreetings
{
void SayHello();
}
interface IAmericanGreetings
{
void SayHello();
}
class speaker : IChineseGreetings, IAmericanGreetings
{
void IChineseGreetings.SayHello()//显式实现接口。
{
Console.WriteLine("你好");
}
void IAmericanGreetings.SayHello()//显示实现接口
{
Console.WriteLine("hello!");
}
}
#region
interface Ifc1
{
void print(string s);
}
interface Ifc2
{
void print(string s);
}
class MyClassT : Ifc1, Ifc2
{
public void print(string s)//实现接口
{
Console.WriteLine("调用了接口的盛名放:{0}", s);
}
}
#endregion
interface IliveBirth//接口
{
string BabyCalled();
}
class Program
{
static void Main(string[] args)
{
dog puppy = new dog();
puppy.Eat();
puppy.Walk();
puppy.Voice();
IShow show = (IShow)puppy; //先将类对象转为接口对象,再调用接口方法。
show.Show();
speaker sayer = new speaker();
IChineseGreetings chg = (IChineseGreetings)sayer;//显示调用接口
chg.SayHello();
IAmericanGreetings ag = (IAmericanGreetings)sayer;
ag.SayHello();
MyClassT ct = new MyClassT();
Ifc1 cti = ct as Ifc1; //将类对象 转为接口对象。
if (cti != null)
cti.print("interface1");//调用方法
Ifc2 ct2 = ct as Ifc2; //将类对象,转为接口对象。
ct2.print("interface2");
Console.ReadKey();
}
}
}
二、 在接口中属性与事件成员
- 类继承两个接口,且每个接口都具有相同名称的事件时,至少要为其中一个事件提供显式接口实现。
- 为事件编写显式接口实现时,还必须编写 add 和 remove 事件访问器。 通常这些访问器由编译器提供,但在这种情况下编译器不提供它们。
- 通过提供自己的访问器,可以指定两个事件是由类中的同一个事件表示,还是由不同事件表示。
代码示例:
using System;
namespace classTest016
{
interface IEmployee //接口中定义属性
{
//定义可读可写属性
string Name
{
get;
set;
}
//定义只读属性
int Counter
{
get;
}
}
public class Employee : IEmployee //继承接口
{
public static int numberOfEmployees;
private string name;
public string Name //可读可写的属性
{
get
{
return name;
}
set
{
name = value;
}
}
private int counter;
public int Counter // read-only instance property
{
get
{
return counter;
}
}
public Employee() //构造函数
{
counter = ++numberOfEmployees;
}
}
class TestEmployee
{
static void Main()
{
System.Console.Write("请输入员工人数: ");
Employee.numberOfEmployees = int.Parse(System.Console.ReadLine());
Employee e1 = new Employee();
System.Console.Write("输入新员工的名字: ");
e1.Name = System.Console.ReadLine();
System.Console.WriteLine("The employee information:");
System.Console.WriteLine("Employee 人数: {0}", e1.Counter);
System.Console.WriteLine("Employee 名字: {0}", e1.Name);
Shape shape = new Shape();
Subscriber1 sub = new Subscriber1(shape);
Subscriber2 sub2 = new Subscriber2(shape);
Console.WriteLine("触发事件");
shape.Draw();
Console.ReadLine();
}
}
// 两个接口中定义-- 相同的事件
public interface IDrawingObject //接口中定义事件
{
event EventHandler OnDraw; //定义事件
}
public interface IShape //
{
event EventHandler OnDraw;
}
// Base class event publisher inherits two
// interfaces, each with an OnDraw event
// 事件发布类,继承两个接口,
public class Shape : IDrawingObject, IShape
{
//定义两个事件分别用于实现接口中的事件
event EventHandler PreDrawEvent;
event EventHandler PostDrawEvent;
//创建锁
object objectLock = new Object();
#region 显式注册 接口 IDrawingObject中的event
event EventHandler IDrawingObject.OnDraw
{
add
{
lock (objectLock)
{
PreDrawEvent += value;
}
}
remove
{
lock (objectLock)
{
PreDrawEvent -= value;
}
}
}
#endregion
//显示注册 接口IShape中的event
event EventHandler IShape.OnDraw
{
add
{
lock (objectLock)
{
PostDrawEvent += value;
}
}
remove
{
lock (objectLock)
{
PostDrawEvent -= value;
}
}
}
// For the sake of simplicity this one method
// implements both interfaces.
public void Draw() //实现两个接口
{
PreDrawEvent.Invoke(this, EventArgs.Empty);
Console.WriteLine("触发IShape.Ondraw事件 ");
// Raise IShape's event after the object is drawn.
PostDrawEvent.Invoke(this, EventArgs.Empty);
}
}
public class Subscriber1 //事件订阅类
{
// References the shape object as an IDrawingObject
//引用IDrawingObject对象
public Subscriber1(Shape shape)
{
IDrawingObject d = (IDrawingObject)shape;
d.OnDraw += d_OnDraw;
}
void d_OnDraw(object sender, EventArgs e) //
{
Console.WriteLine("Sub1 receives the IDrawingObject event.");
Console.WriteLine("订阅者1 收到了IDrawingObject的event");
}
}
// References the shape object as an IShape
public class Subscriber2
{
public Subscriber2(Shape shape)
{
IShape d = (IShape)shape;
d.OnDraw += d_OnDraw;
}
void d_OnDraw(object sender, EventArgs e)
{
Console.WriteLine("Sub2 receives the IShape event.");
}
}
}