接口(interface)
什么是接口
接口是指定一组函数成员而不实现它们的引用类型,接口定义了所有类继承接口时应遵循的语法合同,可以简单理解为一种约定,使得实现接口的类或结构在形式上保持一致,使用接口可以使程序更加清晰和条理化。
接口的定义与实现
//定义了接口1
interface IMyinterface
{
int num { get; set; }
void Method();
}
//定义了接口2
interface IMyinterface2
{
void Method2();
}
//类A继承了接口1,2
class A : IMyinterface2, IMyinterface
{
public void Method2()
{
Console.WriteLine("接口2的方法实现");
}
public void Method()
{
Console.WriteLine("接口1的方法实现");
}
public int num
{
get;
set;
}
}
接口的特点
1.接口成员是不允许有访问权限修饰符
2.接口是不能直接实例化,但是可以间接实例化(用接口创建派生类)
3.继承接口类,必须将接口中的成员全部实现,且成员名和接口中定义的名字保持一致
4.如果一个接口继承了其他接口,那么实现的类就需要实现所有接口成员
接口与抽象类的理解
接口与抽象类区别:
相同点:
1.都可以被继承
2.都不能直接实例化
3.自身不提供代码实现,具体实现在子类中进行
4.派生类中必须实现未实现的方法
不同点:
1.抽象类中可以定义字段,属性,方法的实现,但是接口中只能定义属性,事件,以及方法的声明,不能包含字段
2.单继承类,多继承接口
3.接口具有专一性,而不是多功能,否则会造成接口污染
字符串与字符串变量
字符串通过string创建而字符串变量通过stringbuilder创建
stringbuilder
1.少量字符串操作,且字符串不经常发生变化时,优先使用stirng
2.stringbuilder创建后大小是可以发生变化,但是string大小是不可变的
3.stringbuilder可以自动扩容,且2倍扩容
委托(delegate)
什么是委托
委托是一种引用类型,表示对具有特定参数列表和返回类型的方法的引用。简单的说委托相当于是对具有相同返回类型和参数列表这一类方法进行了封装,由于委托本质是也是一个派生自Delegate类的类,其本质也是类,因此类可以申明在哪里,委托就可以申明在哪里。也可以将通俗的理解为委托就是C++中的函数指针。
委托的定义与实现
委托的定义:访问权限 delegate 返回值类型 委托名(参数类型)
//定义了一个委托
public delegate int Mydelegate(int a);
//定义了一个类
class TestData
{
public int num;
public int AddNum(int a)
{
num += a;
return num;
}
public int MulNum(int a, int b)
{
num *= (a + b);
return num;
}
}
//创建了一个委托
TestData td = new TestData();
td.AddNum(10);
Console.WriteLine(td.num);
//正常委托形式
Mydelegate m1 = new Mydelegate(td.AddNum);
Console.WriteLine(m1(10));
通过匿名函数创建委托
匿名函数
提供了一种传递代码块作为委托参数的技术,匿名函数是没有方法名,只有函数主体,在匿名函数中不需要指定返回值类型,系统会在函数体中通过return语句自动推断
匿名函数只能将方法赋值给委托,通过委托调用该方法
//匿名函数形式
Mydelegate m11 = new Mydelegate(delegate(int a)
{
return a;
});
Console.WriteLine(m11(120));
通过lambda表达式创建委托
//lambda表达式
Mydelegate m12 = new Mydelegate((int a) =>
{
return a;
});
Console.WriteLine(m12(12000));
通过内置委托类型创建委托
三种关键字
Func:有返回值
Action:无返回值
Predicate:返回值为bool(因为Perdicate有返回值且返回值是bool他的功能Func能完全实现,因此Predicate不常用)
//采用系统提供的委托 func
Func<int, int> f1 = new Func<int, int>(delegate(int a)
{
return a;
});
Console.WriteLine(f1(240));
Func<int, int> f2 = new Func<int, int>((int a) =>
{
return a;
});
Console.WriteLine(f2(24000));
//只有一条语句时,在方法体就不需要大括号和return语句,编译器会自动补全
Func<int, int> f3 = new Func<int, int>(a => a);
Console.WriteLine(f2(64000));
//采用系统提供的委托 action
Action<int> a1 = new Action<int>(delegate(int a)
{
Console.WriteLine(a);
});
a1(1000);
Action<int> a2 = new Action<int>((int a) =>
{
Console.WriteLine(a);
});
a2(100000);
多播委托
只有相同类型的委托才可以被合并成为多播委托。
/定义Test类
class Test
{
public void StartBook()
{
Console.WriteLine("打开书本");
}
public void ReadBood()
{
Console.WriteLine("开始读书");
}
}
//定义委托
public delegate void Mydelegate3();
//创建多播委托实例
Test t = new Test();
t.StartBook();
t.ReadBood();
Mydelegate3 m3 = new Mydelegate3(t.StartBook);
Mydelegate3 m4 = new Mydelegate3(t.ReadBood);
//Mydelegate3 m5 = m3 + m4;//多播委托
//m5();
m4 += m3;
m4();
m4 -= m3;
m4();
事件(event)
什么是事件
事件是一种特殊的委托,本质上来讲事件就是委托。如果说委托是对方法的包装,那么事件就是对委托进一步的包装,提升了使用的安全性,事件是安全版的委托。
实例通过事件实现观察者模式,猫叫,老鼠跑,人醒。
public delegate void CatCallEventHandler();
class Cat
{
public event CatCallEventHandler Catcall;
public void OnCatCall()
{
Console.WriteLine("猫叫了一声");
if (Catcall != null)
{
//Catcall();
Catcall.Invoke();//invoke方法是用于多线程环境中跨线程调用委托,主要作用就是将委托的执行转移到与创建委托线程不同的线程上
}
}
}
class Mouse
{
public void MouseRun()
{
Console.WriteLine("老鼠跑了");
}
}
class Person
{
public void WakeUp()
{
Console.WriteLine("人从梦中惊醒");
}
}
//实现
Cat cat = new Cat();
Mouse mouse = new Mouse();
Person person = new Person();
cat.Catcall += new CatCallEventHandler(mouse.MouseRun);
cat.Catcall += new CatCallEventHandler(person.WakeUp);
cat.OnCatCall();