1:什么时候用接口,什么时候用抽象类。
回答:
interface 中的方法不能有实现,作用是分类功能,一个类可以实现多个接口.
* 抽象类的作用的定义公共功能。抽象类和其子类是有上下级关系的。同时一个子类只能继承一个父类.
interface中定义的属性一定是public static final的不管你加不加这些; 而抽象类中的属性和类的一样可以通过上述关键字来定义,并不是默认强加的。
接口是一种协定,抽象类则相当于类模板。【姑协定可以有多个,模板不可以】
使用抽象类,而不要使用接口来分离协定与实现。
如果需要提供多态层次结构的值类型,使用接口。
如果一个类型必须实现多个协定,或者协定适用于多种类型,使用接口。
虽然抽象类和接口都支持将协定与实现分离开来,但接口不能指定以后版本中的新成员,而抽象类可以根据需要添加成员以支持更多功能。
优先考虑定义类,而不是接口。
1.抽象类是一个不完全的类,需要进一步专业化.接口只是一个行为的规范或规定;
2.接口基本上不具备继承的任何具体特点,它仅仅承诺了能够调用的方法;
3.一个类一次可以实现若干个接口,但是只能扩展一个父类
4.接口可以用于支持回调,而继承并不具备这个特点.
如果预计要创建组件的多个版本,则创建抽象类。抽象类提供简单易行的方法来控制组件版本。通过更新基类,所有继承类都随更改自动更新。另一方面,接口一旦创建就不能更改。如果需要接口的新版本,必须创建一个全新的接口。
如果创建的功能将在大范围的全异对象间使用,则使用接口。
抽象类应主要用于关系密切的对象,而接口最适合为不相关的类提供通用功能。
如果要设计小而简练的功能块,则使用接口。如果要设计大的功能单元,则使用抽象类。例如:Window窗体可以用抽象类来设计,可以把公有操作和属性放到一个抽象类里,让窗体和对话框继承自这个抽象类,再根据自己的需求进行扩展和完善。打印操作可以作为一个接口提供给每个需要此功能的窗体,因为窗体的内容不同,就要根据他们自己的要求去实现自己的打印功能。打印时只通过接口来调用,而不用在乎是那个窗体要打印。
2:什么事观察者模式,结构图。
观察者模式(Observer)完美的将观察者和被观察的对象分离开。举个例子,用户界面可以作为一个观察者,业务数据是被观察者,用户界面观察业务数据的变化,发现数据变化后,就显示在界面上。面向对象设计的一个原则是:系统中的每个类将重点放在某一个功能上,而不是其他方面。一个对象只做一件事情,并且将他做好。观察者模式在模块之间划定了清晰的界限,提高了应用程序的可维护性和重用性。
观察者模式有很多实现方式,从根本上说,该模式必须包含两个角色:观察者和被观察对象。在刚才的例子中,业务数据是被观察对象,用户界面是观察者。观察者和被观察者之间存在“观察”的逻辑关联,当被观察者发生改变的时候,观察者就会观察到这样的变化,并且做出相应的响应。如果在用户界面、业务数据之间使用这样的观察过程,可以确保界面和数据之间划清界限,假定应用程序的需求发生变化,需要修改界面的表现,只需要重新构建一个用户界面,业务数据不需要发生变化。
“观察”不是“直接调用”
实现观察者模式的时候要注意,观察者和被观察对象之间的互动关系不能体现成类之间的直接调用,否则就将使观察者和被观察对象之间紧密的耦合起来,从根本上违反面向对象的设计的原则。无论是观察者“观察”观察对象,还是被观察者将自己的改变“通知”观察者,都不应该直接调用。【要抽象出来】
实现观察者模式的例子
实现观察者模式有很多形式,比较直观的一种是使用一种“注册——通知——撤销注册”的形式。下面的三个图详细的描述了这样一种过程:
1:观察者(Observer)将自己注册到被观察对象(Subject)中,被观察对象将观察者存放在一个容器(Container)里。
2:被观察对象发生了某种变化(如图中的SomeChange),从容器中得到所有注册过的观察者,将变化通知观察者。
3:观察者告诉被观察者要撤销观察,被观察者从容器中将观察者去除。
观察者将自己注册到被观察者的容器中时,被观察者不应该过问观察者的具体类型,而是应该使用观察者的接口。这样的优点是:假定程序中还有别的观察者,那么只要这个观察者也是相同的接口实现即可。一个被观察者可以对应多个观察者,当被观察者发生变化的时候,他可以将消息一一通知给所有的观察者。基于接口,而不是具体的实现——这一点为程序提供了更大的灵活性。
3:什么时候使用观察者模式。
1) 当一个抽象模型有两个方面,其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。
2) 当对一个对象的改变需要同时改变其它对象,而不知道具体有多少对象有待改变。
3) 当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之,你不希望这些对象是紧密耦合的。
其实观察者模式同前面讲过的桥梁、策略有着共同的使用环境:将变化独立封装起来,以达到最大的重用和解耦。观察者与后两者不同的地方在于,观察者模式中的目标和观察者的变化不是独立的,而是有着某些联系。
4:使用的时候注意啥。
体现了,以来倒置原则,【都依赖高层而不应该依赖具体的实现】
5:uml 图
6: 一个小例子。
using System;
namespace patternDesign_guanchazhe
{
//抽象的主题【被观察者】
interface Subject
{
void attach(Observer o);
void detach(Observer o);
void Notify();
string SubjectState()
{
get;
set;
}
}
//实现了subject 接口的具体的一个被观察者【被观察者】===老板
public class boss : Subject
{
#region Subject 成员
//观察他的一个观察者列表
private IList<Observer> observer = new List<Observer>();
private string action;
public void attach(Observer o)
{
observer.Add(o);
}
public void detach(Observer o)
{
observer.Remove(o);
}
public void Notify()
{
foreach (Observer o in observer)
o.update();
}
public string SubjectState()
{
get {return action;}
set {action=value;}
}
#endregion
}
//抽象的观察者
abstract class Observer
{
public string name;//观察者姓名;
public Subject s; //被观察者 ;
public abstract void update();
public Observer(string name,Subject s){
this.name=name;
this.s=s;
}
}
//一个具体的观察者
public class NBAperson:Observer
{
public NBAperson(string name, Subject s)
: base(name, s)
{
}
public override void update()
{
Console.WriteLine("hei ,{0} the boss is call you ...{1}",name ,s.SubjectState);
}
}
//一个具体的实现。
public class play
{
boss b = new boss();
NBAperson n1 = new NBAperson("fdsfsd", boss);
NBAperson n2 = new NBAperson("fff", boss);
b.attach(n1);
b.attach(n2);
b.SubjectState="fgdfgfd";
b.Notify();
}
}