
2008年7月21日
●接口声明了一组相关的方法,在所有类之外
●抽象类是一种不完整的类定义,其中有些方法虽已声明,但没有定义
从概念上说,接口定义了独立于类层次结构的应用编程接口(API).实际上,接口可以用于非OO的编程模型中,例如COM或CORBA这样的基于组件的模型.但是,您要将重点放在面向对象环境中的接口使用上,在这里它们也是很有用的.接口是终极封装,因为它们隐藏了实现这些方法的类的所有细节,只暴露出使用的接口.它们在只支持单继承(类只能从一个基类继承)的语言中尤其重要(实际上是必要的).如果一个类通过接口来展现它的成员函数,那么我们称它"实现"了这个接口.
和接口不一样,抽象类是一个类:它可以拥有数据成员,可以是其他类的子类.但是和具体类(非抽象类)不同,它的某些行为故意留给其子类来定义.因此抽象类不能够实例化,只有具体类才能创建实例.
接口几乎等价于没有任何数据成员和方法定义的抽象类.在C++中,这就是您定义接口的方法:声明一个没有数据成员,只有纯虚函数的类.像下面的例子这样:
Class StatusCallback
{
public:
virtual void updateStatus(int oState,int nState) = 0;
}
然后,类可以从它派生,从而"实现"这个接口:
Class MyClass:SomeOtherClass,StatusCallback
{
public:
void updateStatus(int oState,int nState)
{
if(nState > oState)
{
......//do stuff
}
}
}
在Java中,接口通过interface关键字来定义:
public interface StatusCallback
{
void updateStatus(int oState,int nState);
}
然后接口由一个类来实现:
public class MyClass implements StatusCallback
{
public void updateStatus(int oState,int nState)
{
......//do stuff
}
......//do stuff
}
在既支持接口又支持抽象类的语言中,您常会看到一种模式,即通过一个抽象类来提供一个接口的"缺省实现".例如,下面的接口:
public interface XMLReader
{
public XMLObject fromString(String str);
public XMLObject fromReader(Reader in);
}
可能有这样的缺省实现:
public abstract class XMLReaderImpl
{
public XMLObject fromString(String str)
{
fromString(new StringReader(str));
}
public abstract XMLObject fromReader(Reader in);
}
于是,需要实现XMLReader的程序员可以选择从XMLReaderImpl派生一个子类(也可能作为一个嵌套的类),只实现一个方法,而非两个方法.
posted @
2008-07-21 19:15 肖斌 阅读(157) |
评论 (0) |
编辑

2008年1月17日
在操作系统中,死锁是很敏感的问题,很多意外的发生和死锁有着直接的关系,而死锁产生的原因有大概四种,我想了想,与其从如何解决死锁开始学习死锁,不如从制造死锁开始学习死锁.以下是我利用Monitor.Enter()制造的第一种死锁情况:
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.IO;
class Program
{
static void Main(string[] args)
{
Add add1 = new Add ();
Thread thread1 = new Thread (new ThreadStart (add1 .ThreadProc));
Thread thread2 = new Thread(new ThreadStart(add1.ThreadProc));
thread1.Start();
thread2.Start();
thread1.Join();
thread2.Join();
Console.WriteLine(add1.Result);
Console.ReadLine();
}
}
class Add
{
protected int a = 0;
protected void Update()
{
Monitor.Enter(this);
a++;
}
public int Result
{
get
{
return a;
}
}
public void ThreadProc()
{
for (int n = 0; n < 10; n++)
{
Update();
}
}
}
原理其实很简单,就是在进程thread1进行时占用a的使用权(通过Monitor.Enter(this)实现),然后故意不使用Monitor.Exit(this)释放使用权,这样,进程thread2在进行时需要使用a,但是,由于a已经进入了Monitor类的保护区,造成进程thread2无法访问,必须等待的状况,而同时,由于缺少了Monitor.Exit()的实现,a的使用权是不会被释放的,进程thread2一直等待,造成了死锁deadlock.
posted @
2008-01-17 16:35 肖斌 阅读(42) |
评论 (1) |
编辑

2008年1月16日
特性(Attributes)感觉就象是一个帽子,它的使用和被它标注的元素(可以是类,方法或者字段)没有很大的关系,主要功能似乎只是用来描述被标注的元素.
举例解释的话可能会有一点好,但是,不知道是否贴切:一个Class或者是Function在创作后需要知道编写它的作者的一些信息,比如名字,年龄,擅长,或者联系电话什么的,但是,这些东西无法在Class里面写入,因此,可以用特性来帮忙.
我们将作者的所有信息写入到一个Class里面(一般情况下建议用属性(Property)和构造函数来输入一些信息),然后将其标注为特性类:
class MyAttributes : Attributes
{}
然后将其标注在需要使用的元素上面,我们这里暂时描述Class:
[MyAttributes()]
public class A
{}
这样,一个特性的创建和使用便完成了.
如何让代码知道我们的特性存在呢?关键就需要创建一个搜索特性的Class,这个类的目的是查找指定的类,看它是否具备了指定的特性,如果是,则完成相关操作,如果不是,就报错误或者执行其它的操作(甚至不做任何操作).
因此,使用特性的步骤总共为四个步骤:
1.创建一个特性类;
2.将特性类和相关的元素联系起来;
3.创建一个搜索类.
4.利用搜索类进行搜索后执行相关的操作.
以下是个人实验的代码:
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.IO;
class Program
{
static void Main(string[] args)
{
Type t = typeof(Show); //将Show类的类型作为参数进行传递
AuthorAttributesCheck aa = new AuthorAttributesCheck(t); //通过AuthorAttributesCheck类来搜索看Show类是否存在特性类
if (aa != null) //如果存在的话,就进行数据的读出
{
Console.WriteLine("The Author is {0} and {1}", aa.GetName(),aa.GetNotes ());
}
Console.ReadLine();
}
}
public class Author:Attribute //这个就是指明从Attribute继承出来的自定义特性
{
protected string _name;
protected string _notes;
public Author (string name)
{
_name = name;
}
public string Name
{
get
{
return _name;
}
}
public string Notes
{
get
{
return _notes;
}
set
{
_notes = value;
}
}
}
[Author("shaw")] //在这里标注出特性,将它和Show类联系,即可得到Show类作者的信息
public class Show
{
public Show ()
{
Console.WriteLine("YES");
}
}
public class AuthorAttributesCheck
{
protected Type _type; //创建一个Type实例用来获得参数类型
public AuthorAttributesCheck(Type type)
{
_type = type;
}
public string GetName()
{
foreach (Attribute attrib in _type.GetCustomAttributes(true)) //获得一个自定义特性数组
{
Author author = attrib as Author; //将特性实例和自定义特性数组做比较,看是否存在相同的数组
if (attrib != null)
{
return author.Name; //如果存在的话,即说明type参数的类是被Author特性标注,因此,获取信息
}
}
return null;
}
public string GetNotes() //获取Notes信息的方法
{
foreach (Attribute attrib in _type.GetCustomAttributes(true))
{
Author notes = attrib as Author;
if(notes != null)
{
notes.Notes = "No.1";
return notes.Notes;
}
}
return null;
}
}
posted @
2008-01-16 17:05 肖斌 阅读(156) |
评论 (4) |
编辑