设计模式零(面向对象基础)
本内容参考大话设计模式记录
对象:一切事物皆对象。类:对对象进行的抽象。实例:类的一个具体实体。
方法重载:方法名相同但是参数类型或者个数不同的方法。
面向对象的三大特性:继承,封装,多态
继承:子类继承父类后具有父类的保护和公有的一些方法,属性等并且能扩充自己。对于父类的构造函数只能调用不能继承。当对象与对象的关系是is-a时候用继承,当关系式has-a我们应该用组合或者聚合(桥接模式)。
封装:一个类在其内部拥有自己的方法,字段完成一些操作而不需要其他类,内部变化对于外面是不清楚的,只是提供一个接口。
多态:子代父完成一些操作(用到Virtual和Override),也就是依赖倒置原则的核心。(也就是调用的父类的方法,但是执行的是子类的函数实体),但是有个缺点就是,子类的扩展不能使用。
重构:对现有代码优化,把重复出现的部分抽取出来。(模板方法模式,提取抽象类等方法)
抽象类:对类的抽象。(类是对对象的抽象,接口是对方法的抽象,代理也是对方法的抽象),当我们发现我们创建的类不需要去实例化的时候我们可以把它设计为抽象类,注意的是抽象类必须被子类重写的,抽象类尽可能的拥有多的共同代码,尽量少的数据。
接口:把一些特定的方法或者属性进行抽象。
接口和抽象类的区别:一个类可以继承多个接口,但只能继承一个抽象类。抽象类可以给出一些成员的实现,而接口不能。抽象类的抽象成员可以被子类部分实现,而接口需要完全实现。抽象类是对对象的整体抽象,接口是对对象的局部抽象(方法和属性)。对于行为跨越不同的类对象的时候我们应该用接口,对于一些相似的对象我们用抽象类。从设计的角度分析,抽象类是从子类中发现公共的部分,泛化出父类,然后子类继承父类。而接口是根本就不知道子类的存在,方法如何实现还不确定,预先定义。(抽象是自底而上,接口是自顶而下)。
集合:数组(分配空间固定,易于读取,不利于更改)。ArrayList易于更改,可以添加不同类型的数据(导致它是不安全类型),但是对于数据的操作的时候大量用到了装箱和拆箱的操作,占用了大量的空间和时间。注意:它的一个操作将带动所有的其他成员发生变化。比如我们要连续删除前2个成员要用:ArrayList.Remove(0);ArrayList.Remove(0);而不是ArrayList.Remove(0);ArrayList.Remove(1);
泛型:为了解决ArrayList的装箱和拆箱带来性能上的问题。(我觉得泛型就是通过参数预先给不同的数据先制定需要存储一个单位的空间),用IList<T> Lists=new List<T>解决。它的好处在于解决了类型安全和装箱拆箱操作。
事件与委托:委托是函数的封装或者说是函数的另外一种表现形式。而事件则是委托的一种特殊形式,委托是一种引用方法的类型,一旦委托分类方法成功,那么委托和方法具有相同的行为。而事件是说在发生其它类或对象关注的事情时,类或对象可以通过事件通知他们。
下面代码展示怎样在类中建立委托,事件,并且在实例后怎样给事件赋值(事件的触发是类内部触发的,外部只需要给事件赋值就行了,一般在内部触发先要判断事件是否为空,然后调用)
namespace 动物练习
{
class Program
{
static void Main(string[] args)
{
Cat cat = new Cat("Tom");
Mouse mouse1 = new Mouse("Jerry");
Mouse mouse2 = new Mouse("Jack");
cat.CatShout += new Cat.CatShoutEventHandler(mouse1.Run);
cat.CatShout += new Cat.CatShoutEventHandler(mouse2.Run);
cat.Shout();
Console.Read();
}
}
//无参数委托事件
class Cat
{
private string name;
public Cat(string name)
{
this.name = name;
}
public delegate void CatShoutEventHandler();
public event CatShoutEventHandler CatShout;
public void Shout()
{
Console.WriteLine("喵,我是{0}.", name);
if (CatShout != null)
{
CatShout();
}
}
}
class Mouse
{
private string name;
public Mouse(string name)
{
this.name = name;
}
public void Run()
{
Console.WriteLine("老猫来了,{0}快跑!", name);
}
}
带参数的事件
namespace 动物练习
{
class Program
{
static void Main(string[] args)
{
Cat cat = new Cat("Tom");
Mouse mouse1 = new Mouse("Jerry");
Mouse mouse2 = new Mouse("Jack");
cat.CatShout += new Cat.CatShoutEventHandler(mouse1.Run);
cat.CatShout += new Cat.CatShoutEventHandler(mouse2.Run);
cat.Shout();
Console.Read();
}
}
//有参数委托事件
class Cat
{
private string name;
public Cat(string name)
{
this.name = name;
}
public delegate void CatShoutEventHandler(object sender, CatShoutEventArgs args);
public event CatShoutEventHandler CatShout;
public void Shout()
{
Console.WriteLine("喵,我是{0}.", name);
if (CatShout != null)
{
CatShoutEventArgs e = new CatShoutEventArgs();
e.Name = this.name;
CatShout(this, e);
}
}
}
public class CatShoutEventArgs : EventArgs
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
}
class Mouse
{
private string name;
public Mouse(string name)
{
this.name = name;
}
public void Run(object sender, CatShoutEventArgs args)
{
Console.WriteLine("老猫{0}来了,{1}快跑!", args.Name, name);
}
}
}