C#学习笔记(十) 接口

第十五章 接口

  1. 接口:它只是声明了一组函数成员而没有实现,接口的成员只能在类或结构中实现,接口可以帮助我们处理不同结构的类,虽然不同的类具有不同的结构(字段或者方法),但是接口为它们提供了统一的方法,可以让不同结构的类通过这些方法实现自己的功能。
  2. 接口不允许声明数据成员和静态成员,可以在接口中声明方法、属性、事件和索引器。
  3. 接口和接口成员的访问修饰符是不同的,接口可以使用任何形式的访问修饰符如public、internal、protected、private,而接口的成员是隐式的public,不允许有访问修饰符,即便是public也不行。
  4. 接口使用方法示例:
interface IInfo		//声明接口
{
	string GetName();		//只声明方法,没有实现部分
	string GetAge();
}
class CA : IInfo		//声明实现接口的CA类
{
	public string Name;
	public int Age;
	public string GetName (){return Name;}		//在CA类中实现接口的方法
	public string GetAge(){return Age.ToString();}
}
class CB : IInfo		//声明了实现接口的CB类
{
	public string First;
	public string Last;
	public double PersonsAge;
	public string GetName(){return First + " " + Last;}
	public string GetAge(){return PersonsAge.ToString();}
}
class Program
{
	static void PrintInfo(IInfo item)		//传入接口的引用
	{
		Console.WriteLine("Name:{0},Age:{1}",item.GetName(),item.GetAge());
	}
	static void Main()
	{
		CA a = new CA(){Name = "workharding",Age = 25};
		CB b = new CB(){First = "jone",Last = "jon",PersonsAge = 18};
		PrintInfo(a);		//对象的引用自动转换为它们实现的接口的引用
		PrintInfo(b);
	}
}

执行结果:

在这里插入图片描述

  1. Sort方法对整型数组元素排序很有效,但对类的对象不怎么管用,原因在于整型数组使用IComparable接口,而类没有直接使用它所以不能用,IComparable接口的声明为public interface IComparable{int CompareTo(object obj);}只有一个方法声明,如果类对象想使用Sort方法,需要在类中实现IComparable接口的成员。
  2. 示例:
class Myclass : IComparable		//类实现引用
{
	public int TheValue;
	public int CompareTo(object obj)		//实现方法
	{
		Myclass mc =(Myclass)obj;
		if(this.TheValue>mc.TheValue) return 1;		//当前的值大于参数的值,返回正数
		if(this.TheValue<mc.TheValue) return -1;
		return 0;
	}
}
class Program
{
	static void PrintOut(string s,Myclass[] mc)
	{
		Console.WriteLine(s);
		foreach(var m in mc)
			Console.WriteLine("{0}",m.TheValue);
		Console.WriteLine(" ");
	}
	static void Main()
	{
		var myInt = new []{25,64,89,36,56};
		Myclass[] mcArr = new Myclass[5];		//创建Myclass对象的数组
		for(int i =0;i<5;i++)
		{
			mcArr[i] = new Myclass();
			mcArr[i].TheValue = myInt[i];
		}
		PrintOut("Initial Order: ",mcArr );
		Array.Sort(mcArr);
		PrintOut("Sorted Order: ",mcArr );
	}
}

执行结果:

在这里插入图片描述

  1. 声明接口:通过上述示例,大致明白了声明接口的过程,需要有关键字interface,接口名必须以大写I开头。
  2. 实现接口:格式是类名:接口名,若有多个接口,之间用逗号隔开,若是派生类,则基类必须在接口之前,还是以逗号间隔,接口成员的实现必须在类中。
  3. 简单接口示例:
//简单接口
using System;

namespace test24
{
    interface IIfc1
    {
        void PrintOut(string s);
    }
    class Myclass : IIfc1
    {
        public void PrintOut(string s)
        {
            Console.WriteLine("Calling through: {0}",s);
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Myclass mc = new Myclass();
            mc.PrintOut("hello everyone!");
        }
    }
}

结果显示“Calling through: hello everyone!”

  1. 接口是引用类型:我们不能直接通过类对象成员访问接口,我们可以把类对象引用强制转换为接口类型来获取接口的引用,通过接口应用,可以调用接口的方法。
  2. 接口引用类型示例:
 interface  IIfc1
 {
 	void PrintOut(string s);
 }
class Myclass:IIfc1		//实现接口
{
	public void PrintOut(string s)		//实现接口成员
	{
		Console.WriteLine("Calling through: {0}",s);
	}
} 
class Program
{
	static void Main()
	{
		Myclass mc = new Myclass();		//创建类对象
		mc.PrintOut("more hardworking,more luckier");
		IIfc1 fc = (IIfc1)mc;		//将类对象的引用强制转换为接口引用
		fc.PrintOut("加油");
		
	}
}

执行结果:

在这里插入图片描述

  1. 接口与as运算符:如果我们把类对象的引用强制转换为没有实现的接口的引用,会引发异常,而如果使用as运算符,则不会引发异常。as运算符如强制类型转换,只是不会抛出异常,而是返回null,它返回引用,可以放在赋值语句右边,赋值给目标类型的变量,在使用时,要判断返回引用类型是否为空。
Myclass mc = new Myclass();
IIfc1 fc = mc as IIfc1;		//as运算符的使用
if(fc!=null)
{
	Console.WriteLine("That's right!");	
}
  1. 实现多个接口:如果要实现多个接口,则在基类列表中依次列出,逗号隔开,在类中要实现所有接口的成员;如果有多个要实现的接口具有相同的成员,只需要实现一个成员就可以满足要求;实现多个接口的引用方式如同实现单一接口的引用一样,可以通过强制类型转换,也可以通过as运算符实现。
interface  If1
{
	void Print1(string s1);
}
interface If2
{
	void Print2(string s2);
}

class Myclass1 : If1,If2
{
	public void Print1(string s1)
	{
		Console.WriteLine("Print1:{0}",s1);
	}
	public void Print2(string s2)
	{
		Console.WriteLine("Print2:{0}",s2);
	}
}
class Program
{
	static void main()
	{
		Myclass1 mc1 = new Myclass1();
		mc1.Print1("自动化1401班,加油!");
		mc1.Print2("越努力,越幸运!");
		Console.WriteLine("。。。。。。。。。。。。。。。。。。。。。。。");
		If1 fc1 = mc1 as If1;
		If2 fc2 = mc1 as If2;
		if((fc1!=null)&&(fc2!=null))
		{
			fc1.Print1("加油,2019!");
			fc2.Print2("奋斗!2019!");
		}
	}
}

执行结果:

在这里插入图片描述

  1. 在派生成员中实现接口:此时,就是在基类中实现接口的方法,在派生类中实现接口,示例:
interface Ifc
{
	string  Print1();
}
class Myclass2		//在基类中实现接口的方法
{
	public string name;
	public string Print1()
	{
		return name;
	}
}
class Myderived : Myclass2,Ifc
{ }
class Program
{
	static void main()
	{
		Myderived myc = new Myderived();
		myc.name = "加油啊,每一个追梦人!";
		Console.WriteLine(myc.Print1());
	}
}

执行结果:

在这里插入图片描述

  1. 显示接口成员实现:所谓的显示接口成员实现,只不过在类中声明接口成员时,要使用接口名点成员名的方式,为了突出该成员来自于哪个接口,此时接口成员的实现已经不属于类级别的实现,需要强制类型转换。在多个接口成员实现中运用更好,下面是单一接口的显示接口成员实现。
interface Ifc3
{
	void GetName();
	void GetAge();
}
class Mybaseclass:Ifc3
{
	public string name;
	public int age;
	void Ifc3.GetName()		//没有修饰符
	{
		Console.WriteLine("你的名字:{0}",name);
	}
	void Ifc3.GetAge()
	{
		Console.WriteLine("你的年龄:{0}",age);
	}
}
class Program
{
	static void Main()
	{
		Mybaseclass mybcl = new Mybaseclass();
		mybcl.name  = " Janms";
		mybcl.age = 25;
		Ifc3 ifc3 = (Ifc3)mybcl;
		ifc3.GetName();
		ifc3.GetAge();
	}
}

执行结果:

在这里插入图片描述

  1. 接口作为一种引用类型,当然也可以继承,一个接口可以继承多个接口,在基接口列表中以逗号隔开,最终的接口会包含它声明的所有接口和所有基接口的成员,当然在类中要实现所有接口成员;不同的类也可以实现同一个接口,实现的过程是独立的。
interface Ifc3
{
	void GetName();
	void GetAge();
}
interface Ifc
{
	string  Print1();
}
interface Ifc5 :Ifc3,Ifc		//接口继承
{ }
class Myclass: Ifc5
{
	...		//实现接口的所有成员,移植上面的示例代码即可
}
class Myclass1: Ifc5不同的类实现同一接口
{
	...		//实现接口的所有成员,赋予不同的功能即可
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值