c#--构造函数二

构造函数,是一种特殊的函数,他没有返回类型,它的方法名和类的名字相同,它的功能是对这个类的成员变量实现初始化,这种问题建议你多多看看书...
答案补充
在你每创建一个对象的时候,系统都会对这个类的默认一个空的构造函数,要是你写了,最好多写一个空的构造函数 防止在编译的时候出错
class T
{
public T(int a);
public T;
}
构造函数就是定义一个类的对象是,用来初始化的~~
在构造函数中不要对类的示例做初始化以外的事情.不要尝试显式的调用构造函数,也就是直接去调用
这句话就是说,构造函数本身,不需要我们自己去调用。
例如:
class A
{ int a,b,c;
public A()//构造函数
{a=0;b=0;c=0;}
public A(int w)
{a=w;}
public A(int w,int y,int z)
{a=w;
b=y;
c=z;
}
}
以上类A有3个构造函数,有3个全局变量,当你创建一个A的对象时,例如
A a = new A(); //此时,系统会自动调用类 A 的无参的构造函数,给a,b,c三个全局变量赋初始值0。
当你想给类中的a变量赋值时 例如
A a = new A(5); //此时,系统会调用类 A 中含有一个参数的构造函数,在函数中为 全局变量a赋初始值5.
当你想给所有的全局变量赋值时,就可以写成
A a = new A(4,5,6); //这样当定义完对象a时,就会给所有的全局变量赋值了~~

如果你把全局变量定义成 public类型的话
A a = new A(4,5,6);
a.a 的值就是4,
a.b 的值就是5,
a.c 的值就是6.//前提 a,b,c要都是公有的(public)
以上就是构造函数的具体用法,所以书上说不要尝试显示调用,也就是不要尝试直接调用~~
就是这个意思
 
 
 
 
 

posted @ 2012-04-11 13:32 青蛙學堂 阅读(155) | 评论 (0)编辑 收藏

c#--构造函数

构造函数分为:
1.实例构造函数
2.私有构造函数
3.静态构造函数
构造函数是一种特殊的方法,主要是为了给初始化对象赋初值。
1.实例构造函数
使用new表达式创建某个类的对象时,会使用实例构造函数创建和初始化所有实例成员变量。
 public class ProgramTest
    {
        
int j;
        
public ProgramTest()
        {
            j 
= 4;
            Console.WriteLine(
"I am ProgramTest,{0}", j);
        }
        
static void Main(string[] args)
        {

            ProgramTest pt = new ProgramTest();
            Console.Read();
        }

结果为:I am ProgramTest,4

在此次实验中,我们首先定义了一个私有成员j,经过初始化给他赋了一个初值4,当我实例化类ProgramTest时,就会执行实例构造函数。
诸如此类不带参数的构造函数叫“默认构造函数”,如果某个类没有构造函数,则会自动生成一个默认构造函数,并使用默认值来初始化对象字段。
public class ProgramTest
    {
        
int j;
        
public ProgramTest()
        {
            Console.WriteLine(
"I am ProgramTest,{0}", j);
        }
        
static void Main(string[] args)
        {
            ProgramTest pt 
= new ProgramTest();
            Console.Read();
        }

    }
结果为:I am ProgramTest,0 

也可以创建带有参数的构造函数

 public class ProgramTest
    {
        
int j;
        
public ProgramTest(int i)
        {
            j 
= 2;
            Console.WriteLine(
"I am ProgramTest,i={0},j={1}",i, j);
        }
        
static void Main(string[] args)
        {

            ProgramTest pt = new ProgramTest(1);
            Console.Read();
        }

 

结果为:I am ProgramTest i=1,j=2 

 

那若是一个类中既有无参构造函数,又有有参构造函数那会怎么样呢?

 public class ProgramTest
    {
        
int j;
        
public ProgramTest()
        {
            j 
= 3;
            Console.WriteLine(
"I am ProgramTest 默认构造函数,j={0}", j);
        }
        
public ProgramTest(int i)
        {
            j 
= 2;
            Console.WriteLine(
"I am ProgramTest 有参构造函数,i={0},j={1}",i, j);
        }
        
static void Main(string[] args)
        {

            ProgramTest pt1 = new ProgramTest();
            ProgramTest pt2 
= new ProgramTest(1);
            Console.Read();
        }

 

结果为:I am ProgramTest 默认构造函数 j=3
       I am ProgramTest 有参构造函数 i=1,j=2

 

可见,若是两者同时存在,那么看类实例化时,是怎么实例的。
2.私有构造函数

私有构造函数是一种特殊的实例构造函数。 它通常用在只包含静态成员的类中。
如果类具有一个或多个私有构造函数而没有公共构造函数,则其他类(除嵌套类外)无法创建该类的实例。

 

    public class Test
    {
        
private  Test()
        {
            Console.WriteLine(
"I am Test");
        }
    }
    
public class ProgramTest
    {
        
int j;
        
private ProgramTest()
        {
            j 
= 3;
            Console.WriteLine(
"I am ProgramTest 默认构造函数,j={0}", j);
        }
        
static void Main(string[] args)
        {
            Test t 
= new Test();
            ProgramTest pt1 
= new ProgramTest();
            Console.Read();
        }
    }

结果:这时你会发现编译器会提示你,你无法创建Test的实例
即使你在Test类中添加一个静态成员,结果依然会提示因为该构造函数受其保护级别的限制而不可访问)

若是只在自己类里有私有类呢?

  public class ProgramTest
    {
        
int j;
        
private ProgramTest()
        {
            j 
= 3;
            Console.WriteLine(
"I am ProgramTest 默认构造函数,j={0}", j);
        }
        
static void Main(string[] args)
        {

            ProgramTest pt1 = new ProgramTest();
            Console.Read();
        }
    }

结果:I am ProgranmTest 默认构造函数,j=3

注意,如果您不对构造函数使用访问修饰符,则在默认情况下它仍为私有构造函数。但是,通常显式地使用private修饰符来清楚地表明该类不能被实例化。
若是一个类中既有实例构造函数又有私有构造函数,那么当实例对象是会怎么执行呢?

 public class Test
    {
        
int i;
        
private  Test()
        {
            i 
= 1;
            Console.WriteLine(
"I am Test 默认构造函数 i={0}", i);
        }
        
public Test(int i)
        {
            Console.WriteLine(
"I am Test 有参构造函数 i={0}", i);
        }
    }
    
public class ProgramTest
    {
        
static void Main(string[] args)
        {
            Test t 
= new Test();  //编译器提示:因为该构造函数受其保护级别的限制而不可访问       
            Console.Read();

若是只执行有参构造函数呢?

  public class Test
    {
        
int i;
        
private  Test()
        {
            i 
= 1;
            Console.WriteLine(
"I am Test 默认构造函数 i={0}", i);
        }
        
public Test(int i)
        {
            Console.WriteLine(
"I am Test 有参构造函数 i={0}", i);
        }
    }
    
public class ProgramTest
    {
        
static void Main(string[] args)
        {
            Test t 
= new Test(2);
            Console.Read();
        }
    }

结果:I am Test 有参构造函数 i=2

3.静态构造函数
静态构造函数用来初始化静态变量,这个构造函数是属于类的,而不是属于哪个实例的。

就是说这个构造函数只会被执行一次。也就是在创建第一个实例或引用任何静态成员之前,由.NET自动调用。
 public class Test
    {
        
static int i;
        
static  Test()
        {
            i 
= 1;
            Console.WriteLine(
"I am Test 默认构造函数 i={0}", i);
        }
    }
    
public class ProgramTest
    {
        
static void Main(string[] args)
        {
            Test t1 
= new Test();
            Console.Read();
        }
    }

结果为:I am Test 默认构造函数 i=1

静态函数的特点:
1.静态构造函数既没有访问修饰符,也没有参数。
2.在创建第一个实例或引用任何静态成员之前,将自动调用静态构造函数来初始化类,也就是无法直接调用静态函数,也无法控制什么时候执行静态函数。
3.一个类只能有一个静态构造函数,最多只能运行一次。
4.静态函数不可以被继承。
5.如果没有静态函数,而类中的静态成员有初始值,那么编译器会自动生成默认的静态构造函数。
如果静态默认构造函数和公有默认构造函数同时存在,会怎么样呢?

 

    public class Test
    {
        
static int i;
        
static  Test()
        {
            i 
= 1;
            Console.WriteLine(
"I am Test 静态默认构造函数 i={0}", i);
        }
        
public Test()
        {
            Console.WriteLine(
"I am Test 公有默认构造函数 i={0}", i);
        }
    }
    
public class ProgramTest
    {
        
static void Main(string[] args)
        {
            Test t1 
= new Test();
            Console.Read();
        }
    }

结果:I am Test 静态默认构造函数 i=1

     I am Test 公有默认构造函数 i=1

 

 

如果静态默认构造函数和公有有参构造函数同时存在,我实例化类让它调用静态默认构造函数会怎么样呢?
 public class Test
    {
        
static int i;
        
static  Test()
        {
            i 
= 1;
            Console.WriteLine(
"I am Test 静态默认构造函数 i={0}", i);
        }
        
public Test(int j)
        {
            Console.WriteLine(
"I am Test 公有有参构造函数 i={0}", j);
        }
    }
    
public class ProgramTest
    {
        
static void Main(string[] args)
        {
            Test t1 
= new Test();  //系统会提示错误      
            Console.Read();

        }

    }

如果静态默认构造函数和公有有参构造函数同时存在,我实例化类让它调用公有构造函数会怎么样呢?
    public class Test
    {
        
static int i;
        
static  Test()
        {
            i 
= 1;
            Console.WriteLine(
"I am Test 静态默认构造函数 i={0}", i);
        }
        
public Test(int j)
        {
            Console.WriteLine(
"I am Test 公有有参构造函数 i={0}", j);
        }
    }
    
public class ProgramTest
    {
        
static void Main(string[] args)
        {
            Test t1 
= new Test(2);
            Console.Read();
        }
    }

结果:I am Test 静态默认构造函数 i=1
     I am Test 公有有参构造函数 j=2


posted @ 2012-04-11 13:23 青蛙學堂 阅读(163) | 评论 (0)编辑 收藏

c#--自定义事件

在windows 编程中用到最多的就是控件的时间了,微软给我们很好的方式,把注意力放到事件执行方法的设计和编码上,但是但我们真正弄懂了事件的真正出发执行原理的话,对我们的编程的提高真是非常榜的,例如在windows编程中如果我单击了一个button按钮触发了button 的click事件  Button1_Click(){}  ,但是有时候我们编程的时候,不但想要触发button 的单击事件,我还想要把其他的时间也要调用下来顺序执行,要实现这种方式,除了在方法最后对其他方法的调用,还可以利用将其他需要顺序执行的方法封装到button的click 事件的委托对象中,这样就能够顺序执行毁掉方法列表中的程序了,而这种方式的实现是以清楚事件触发和委托的调用为前提的。

    事件是类和对象向外界发出的消息,事件的执行是通过事件委托的方式,调用我们所准备好的处理方法,而是先消息的响应的。要响应某些事件并针对某些事件执行我们意定的方法,需要做到以下几步:

        1、声明事件委托。

        2、声明事件。

        3、添加事件的触发方法。

        4、添加事件的处理程序(响应事件的方法)。

        5、将指定的事件处理程序邦定到要处理的事件上(订阅事件)。

        6、用户信息操作,并触发事件(调用事件的触发方法)。

        7、通过事件委托的回调,执行我们需要的事件处理程序。

      下面我们举一个简单的自定义事件处理程序的例子(控制台程序)

   namespace 事件
   {
    //发布事件的类
    public class TestEventSource
    {
        //定义事件参数类
        public class TestEventArgs : EventArgs
        {
            public readonly char KeyToRaiseEvent;
            public TestEventArgs(char keyToRaiseEvent)
            {
                KeyToRaiseEvent = keyToRaiseEvent;
            }
        }

        //定义delegate
        public delegate void TestEventHandler(object sender, TestEventArgs e);
        //用event 关键字声明事件对象
        public event TestEventHandler TestEvent;

        //事件触发方法
        protected virtual void OnTestEvent(TestEventArgs e)
        {
            if (TestEvent != null)
                TestEvent(this, e);
        }

        //引发事件
        public void RaiseEvent(char keyToRaiseEvent)
        {
            TestEventArgs e = new TestEventArgs(keyToRaiseEvent);
            OnTestEvent(e);
        }

    }
    //监听事件的类
    public class TestEventListener
    {
        //定义处理事件的方法,他与声明事件的delegate具有相同的参数和返回值类型
        public void KeyPressed(object sender, TestEventSource.TestEventArgs e)
        {
            Console.WriteLine("发送者:{0},所按得健为:{1}", sender, e.KeyToRaiseEvent);
        }

        //订阅事件
        public void Subscribe(TestEventSource evenSource)
        {
            evenSource.TestEvent += new TestEventSource.TestEventHandler(KeyPressed);
        }
        //取消订阅事件
        public void UnSubscribe(TestEventSource evenSource)
        {
            evenSource.TestEvent -= new TestEventSource.TestEventHandler(KeyPressed);
        }
    }

    //测试类
    public class Test
    {
        public static void Main()
        {
            //创建事件源对象
            TestEventSource es = new TestEventSource();
            //创建监听对象
            TestEventListener el = new TestEventListener();
            //订阅事件
            Console.WriteLine("订阅事件\n");
            el.Subscribe(es);
            //引发事件
            Console.WriteLine("输入一个字符,再按enter键");
            string s = Console.ReadLine();
            es.RaiseEvent(s.ToCharArray()[0]);
            //取消订阅事件
            Console.WriteLine("\n取消订阅事件\n");
            el.UnSubscribe(es);

            //引发事件
            Console.WriteLine("输入一个字符,再按enter健");
            s = Console.ReadLine();
            es.RaiseEvent(s.ToCharArray()[0]);

 

        }
    }

}

程序执行结

订阅事件

输入一个字符,再按enter键
aaaa
发送者:事件.TestEventSource,所按得健为:a

取消订阅事件

输入一个字符,再按enter健

          TestEventSource类。他就相当于windows控件类一样,是事件的源,里面包含有事件的声明,以及存储调用参数的事件参数类,以及事件的触发方法。       

         TestEventListener类。他提供了事件处理程序,并实现了事件处理程序和事件对象的邦定,当然时间处理程序可以放在别处,跟邦定程序(订阅事件)放在一起便于理解和调用

        Test 类,实例化自定义事件的事件源对象,并调用 TestEventListener类中的Subscribe(es);方法进行事件对象和事件处理程序的邦定(订阅事件),调用 TestEventSource类中的RaiseEvent(char keyToRaiseEvent)引发对象,并有对象所指定的委托回调处理事件。完成整个自定义事件。

           其中   RaiseEvent(char keyToRaiseEvent)      就相当于main()一样是自定义事件的执行入口,       从这个法开始---〉调用事件委托----〉查找订阅事件程序找到事件所封装的方法集----〉由委托回调事件处理程序并传递参数---〉执行事件处理程序。

posted @ 2012-04-10 21:35 青蛙學堂 阅读(288) | 评论 (0)编辑 收藏

c#委托--事件

当第一次听到委托、事件时感觉比较抽象、很好奇,当看到老师在课堂上利用委托和事件实现两个窗体调用时、感觉委托太神奇了,呵、不废话了……

  C#委托和事件在做程序是很常见到的,对于像我这样的接触C#不是很长的光会去用,但不知道他里面的含义及本质、想理解他还是有一点困难的,下面有两个例子大家可以看一下

public delegate void Mydelegate(string name); //定义一个委托   
    class Program   
    {   
        public static void show(string name)   
        {   
            Console.WriteLine(name);   
        }   
        static void Main(string[] args)   
        {    
            Mydelegate My = show;//利用遇他相对应的方法来实例化委托    
          My("呵呵");//调用委托   
           Console.ReadKey();   
        }   
    }

  这个小例子是定义一个委托,通过与他相对应的方法来实例化委托,然后调用委托,实现方法。

  下面一个例子是我看过张子阳博客后写的,本人英语不是太好、可能里面定义会有些……

using System;   
using System.Collections.Generic;   
using System.Text;   
 
namespace ConsoleApplication7   
{   
    //我们来模拟一个打字智能机,他有三部分构成:在键盘上面输入文字、输出在显示器、语音提示;如果要实现这三种操作必须需要三种不同的硬件,所以   
    //键盘只能实现打字、显示器实现输出,语单提示设备实现读出文字。所以我们应该让他们看成三种不同的对象,来实现程序!   
    //定义三个类,Smart(智能机类),Typing(打字方法),show(显示方法),MakyVoice(语音提示方法)   

    //键盘打字   
    public class Smart   
    {   
        public delegate void SmartDelegate(char T);//定义一个委托   
        public event SmartDelegate SmarEvent;//定义实现这个委托的事件   
 
        public char T;//相当于你每一次打的单个文字   
 
        //定用一个字符串相当于我们从键盘上打出来的文字…… 呵   
        public string Text = "解放四大快捷方式打开附件多撒即可了飞洒富商大贾快乐看附件撒疯狂";   
 
        public void Typing()   
        {   
            foreach (char t in Text)   
            {   
                T = t;   
                if (SmarEvent != null)   
                {   
                    SmarEvent(T);   
                }   
            }   
        }   
    }   
 
    //显示输出   
    public class Display   
    {   
        public void show(char T)   
        {   
            Console.WriteLine(T);   
        }   
    }   
 
    //语言提示   
    public class Voice   
    {   
        public void MakyVoice(char T)   
        {   
            Console.WriteLine("您输出了:" + T);   
        }   
    }   
 
    class Program   
    {   
        static void Main(string[] args)   
        {   
            Smart S = new Smart();   
            Display D = new Display();   
            Voice V = new Voice();   
            S.SmarEvent+=new Smart.SmartDelegate(D.show);   
            S.SmarEvent+=new Smart.SmartDelegate(V.MakyVoice);   
 
            S.Typing();   
            Console.ReadKey();   
        }   
    }   

posted @ 2012-04-10 21:28 青蛙學堂 阅读(214) | 评论 (0)编辑 收藏

C#接口是什么

C#接口是什么呢?C#接口(interface)用来定义一种程序的协定。实现接口的类或者结构要与接口的定义严格一致。有了这个协定,就可以抛开编程语言的限制(理论上)。C#接口可以从多个基接口继承,而类或结构可以实现多个接口。C#接口可以包含方法、属性、事件和索引器。接口本身不提供它所定义的成员的实现。接口只指定实现该接口的类或接口必须提供的成员。   

C#接口好比一种模版,这种模版定义了对象必须实现的方法,其目的就是让这些方法可以作为接口实例被引用。接口不能被实例化。类可以实现多个接口并且通过这些实现的接口被索引。接口变量只能索引实现该接口的类的实例。例子:

  1. interface IMyExample  {  
  2.  
  3.   string this[int index]  { get ; set ; }  
  4.  
  5.  event EventHandler Even ;  
  6.  
  7.  void Find(int value) ;  
  8.  
  9.   string Point  { get ; set ; }  
  10.  
  11. }  
  12.  
  13. public delegate void EventHandler(object sender, Event e) ;   

上面例子中的C#接口包含一个索引this、一个事件Even、一个方法Find和一个属性Point。C#接口可以支持多重继承。就像在下例中,接口"IComboBox"同时从"ITextBox"和"IListBox"继承。

  1. interface IControl  {  
  2.  
  3.  void Paint( ) ;  
  4.  
  5.  }  
  6.  
  7.   interface ITextBox: IControl  {  
  8.  
  9.  void SetText(string text) ;  
  10.  
  11.  }  
  12.  
  13.   interface IListBox: IControl  {  
  14.  
  15.  void SetItems(string[] items) ;  
  16.  
  17.  }  
  18.  
  19.   interface IComboBox: ITextBox, IListBox  { }   

类和结构可以多重实例化C#接口。就像在下例中,类"EditBox"继承了类"Control",同时从"IDataBound"和"IControl"继承。

  1. interface IDataBound  {  
  2.  
  3.   void Bind(Binder b) ;  
  4.  
  5.  }  
  6.  
  7. blic class EditBox: Control, IControl, IDataBound  {  
  8.  
  9.   public void Paint( ) ;  
  10.  
  11. public void Bind(Binder b)  { }  
  12.  
  13.  }  

在上面的代码中,"Paint"方法从"IControl"接口而来;"Bind"方法从"IDataBound"接口而来,都以"public"的身份在"EditBox"类中实现。   

C#接口的总结说明:   

1、C#中的接口是独立于类来定义的。这与 C++模型是对立的,在 C++中接口实际上就是抽象基类。 

2、接口和类都可以继承多个接口。

3、而类可以继承一个基类,接口根本不能继承类。这种模型避免了 C++的多继承问题,C++中不同基类中的实现可能出现冲突。因此也不再需要诸如虚拟继承和显式作用域这类复杂机制。C#的简化接口模型有助于加快应用程序的开发。

4、一个接口定义一个只有抽象成员的引用类型。C#中一个接口实际所做的,仅仅只存在着方法标志,但根本就没有执行代码。这就暗示了不能实例化一个接口,只能实例化一个派生自该接口的对象。

5、接口可以定义方法、属性和索引。所以,对比一个类,接口的特殊性是:当定义一个类时,可以派生自多重接口,而你只能可以从仅有的一个类派生。

C#接口的基本情况就向你介绍到这里,希望对你了解C#接口的含义和C#接口的使用有所帮助。

posted @ 2012-04-10 21:17 青蛙學堂 阅读(1859) | 评论 (0)编辑 收藏

C#接口定义

C#接口定义是什么呢?其实,C#接口定义的就是一种约定,使得实现接口的类或结构在形式上保持一致。个人觉得,使用接口可以使程序更加清晰和条理化,这就是接口的好处,但并不是所有的编程语言都支持接口,C#是支持接口的。注意,虽然在概念上,C#接口类似于COM接口,但他们的底层结构是不同的。那么,我们来看一下如何声明和使用接口。

C#接口定义之声明接口

声明接口在语法上和声明抽象类完全相同,例如这里有一个银行账户的接口:

  1. public interface IBankAccount  
  2. {  
  3. void PayIn(decimal amount);  
  4. bool Withdraw(decimal amount);  
  5.  
  6. decimal Balance  
  7. {  
  8. get;  
  9. }  
  10. }  

注意:接口中只能包含方法、属性、索引器和事件的声明。不允许声明成员上的修饰符,即使是pubilc都不行,因为接口成员总是公有的,也不能声明为虚拟和静态的。如果需要修饰符,最好让实现类来声明。

C#接口定义之使用接口的实例:

这是书上的一个简单的例子,但足以说明接口的使用方法。

一个银行账户的接口,两个不同银行账户的实现类,都继承于这个接口。接口声明如上。下面是两个账户类:

  1. class SaverAccount : IBankAccount  
  2. {  
  3. private decimal balance;  
  4.  
  5. public decimal Balance  
  6. {  
  7. get   
  8. {  
  9. return balance;  
  10. }  
  11. }  
  12.  
  13. public void PayIn(decimal amount)  
  14. {  
  15. balance += amount;  
  16. }  
  17.  
  18. public bool Withdraw(decimal amount)  
  19. {  
  20. if (balance >= amount)  
  21. {  
  22. balance -= amount;  
  23. return true;  
  24. }  
  25. Console.WriteLine("Withdraw failed.");  
  26. return false;  
  27. }  
  28.  
  29. public override string ToString()  
  30. {  
  31. return String.Format("Venus Bank Saver:Balance={0,6:C}", balance);  
  32. }  
  33. }  
  34.  
  35. class GoldAccount : IBankAccount  
  36. {  
  37. private decimal balance;  
  38.  
  39. public decimal Balance  
  40. {  
  41. get   
  42. {  
  43. return balance;  
  44. }  
  45. }  
  46.  
  47. public void PayIn(decimal amount)  
  48. {  
  49. balance += amount;  
  50. }  
  51.  
  52. public bool Withdraw(decimal amount)  
  53. {  
  54. if (balance >= amount)  
  55. {  
  56. balance -= amount;  
  57. return true;  
  58. }  
  59. Console.WriteLine("Withdraw failed.");  
  60. return false;  
  61. }  
  62.  
  63. public override string ToString()  
  64. {  
  65. return String.Format(  
  66. "Jupiter Bank Saver:Balance={0,6:C}", balance);  
  67. }  
  68. }  

可见,这两个实现类多继承了IBankAccount接口,因此它们必须要实现接口中的所有声明的方法。要不然,编译就会出错。让我们来测试一下,下面是测试代码:

  1. static void Main(string[] args)  
  2. {  
  3. IBankAccount venusAccount = new SaverAccount();  
  4. IBankAccount jupiterAccount = new CurrentAccount();  
  5. venusAccount.PayIn(200);  
  6. jupiterAccount.PayIn(500);  
  7. Console.WriteLine(venusAccount.ToString());  
  8. jupiterAccount.PayIn(400);  
  9. jupiterAccount.Withdraw(500);  
  10. jupiterAccount.Withdraw(100);  
  11. Console.WriteLine(jupiterAccount.ToString());  
  12.  
  13. }  

请注意开头两句,我们把它们声明为IBankAccount引用的方式,而没有声明为类的引用,为什么呢?因为,这样我们就可以让它指向执行这个接口的任何类的实例了,比较灵活。但这也有个缺点,如果我们要执行不属于接口的方法,比如这里重载的ToString()方法,就要先把接口的引用强制转换成合适的类型了。

C#接口定义之接口的继承

接口也可以彼此继承,就象类的继承一样。比如我们又声明一个接口ITransferBankAccount,它继承于IBankAccount接口。

  1. interface ITransferBankAccount : IBankAccount   
  2. {  
  3. bool TransferTo(IBankAccount destination, decimal amount);  

在这个接口中,又新增加了一个方法TransferTo(),所以如果我们要写一个类从ITransferBankAccount继承的话,就必须要实现IBankAccount和ITransferBankAccount两个接口所有的方法声明。即:

  1. class CurrentAccount : ITransferBankAccount  
  2. {  
  3. private decimal balance;  
  4.  
  5. public decimal Balance  
  6. {  
  7. get 
  8. {  
  9. return balance;  
  10. }  
  11. }  
  12.  
  13. public void PayIn(decimal amount)  
  14. {  
  15. balance += amount;  
  16. }  
  17.  
  18. public bool Withdraw(decimal amount)  
  19. {  
  20. if (balance >= amount)  
  21. {  
  22. balance -= amount;  
  23. return true;  
  24. }  
  25. Console.WriteLine("Withdraw failed.");  
  26. return false;  
  27. }  
  28.  
  29. public override string ToString()  
  30. {  
  31. return String.Format(  
  32. "Jupiter Bank Saver:Balance={0,6:C}", balance);  
  33. }  
  34.  
  35. public bool TransferTo(  
  36. IBankAccount destination, decimal amount)  
  37. {  
  38. if (Withdraw(amount))  
  39. {  
  40. destination.PayIn(amount);  
  41. return true;  
  42. }  
  43. else 
  44. {   
  45. return false;  
  46. }  
  47. }  
  48. }  

C#接口定义的一些总结:

1、C#中的接口是独立于类来定义的。这与 C++模型是对立的,在 C++中接口实际上就是抽象基类。

2、接口和类都可以继承多个接口。

3、类可以继承一个基类,接口根本不能继承类。这种模型避免了 C++的多继承问题,C++中不同基类中的实现可能出现冲突。因此也不再需要诸如虚拟继承和显式作用域这类复杂机制。C#的简化接口模型有助于加快应用程序的开发。

4、一个接口定义一个只有抽象成员的引用类型。C#中一个接口实际所做的,仅仅只存在着方法标志,但根本就没有执行代码。这就暗示了不能实例化一个接口,只能实例化一个派生自该接口的对象。

5、接口可以定义方法、属性和索引。所以,对比一个类,接口的特殊性是:当定义一个类时,可以派生自多重接口,而你只能可以从仅有的一个类派生。

C#接口定义以及相关的内容就向你介绍到这里,希望对你了解和学习C#接口定义及相关内容有所帮助。

posted @ 2012-04-10 21:15 青蛙學堂 阅读(746) | 评论 (0)编辑 收藏

C#接口的作用

C#接口的作用是什么呢?首先我们来看看什么事实C#接口,C#接口是一个让很多初学C#者容易迷糊的东西,用起来好像很简单,定义接口,里面包含方法,但没有方法具体实现的代码,然后在继承该接口的类里面要实现接口的所有方法的代码,但没有真正认识到接口的作用的时候就觉得用接口是多此一举,当然你这样想那是绝对绝对错误的,比尔盖茨的微软请的员工都是比盖茨还聪明的人,他们的C#能添这样的多足吗?!关于接口的作用,网上有一位就真的深入浅出给我们做了很好理解的分析。

C#接口的作用解释实例:

  1. public interface IBark  
  2. {  
  3.     void Bark();  

再定义一个类,继承于IBark,并且必需实现其中的Bark()方法

  1. public class Dog:IBark  
  2. {  
  3.     public Dog()  
  4.     {}  
  5.     public void Bark()  
  6.     {  
  7.        Consol.write("汪汪");  
  8.      }  

然后,声明Dog的一个实例,并调用Bark()方法

  1. Dog 旺财=new Dog();  
  2. 旺财.Bark(); 

试想一样,若是想调用Bark()方法,只需要在Dog()中声明这样的一个方法不就行了吗,干什么还要用接口呢.因为接口中并没有Bark()具体实现.真的实现还是要在Dog()中.那么使用接口不是多此一举吗?

还有人是这样说的:从接口的定义方面来说,接口其实就是类和类之间的一种协定,一种约束.还拿上面的例子来说.所有继承了IBark接口的类中必需实现Bark()方法.那么从用户(使用类的用户)的角度来说,如果他知道了某个类是继承于IBark接口,那么他就可以放心大胆的调用Bark()方法,而不用管Bark()方法具体是如何实现的.比如,我们另外写了一个类.

  1. public class Cat:IBark  
  2. {  
  3.    public Cat()  
  4.    {}  
  5.    public void Bark()  
  6.    {  
  7.       Consol.write("喵喵");  
  8.    }  

当用户用到Cat类或是Dog类的时候,知道他们继承于IBark,那么不用管类里的具体实现,而就可以直接调用Bark()方法,因为这两个类中肯定有关于Bark()方法的具体实现.

如果我们从设计的角度来看.一个项目中用若干个类需要去编写,由于这些类比较复杂,工作量比较大,这样每个类就需要占用一个工作人员进行编写.比如A程序员去定Dog类,B程序员去写Cat类.这两个类本来没什么联系的,可是由于用户需要他们都实现一个关于"叫"的方法.这就要对他们进行一种约束.让他们都继承于IBark接口,目的是方便统一管理.另一个是方便调用.当然了,不使用接口一样可以达到目的.只不过这样的话,这种约束就不那么明显,如果这样类还有Duck类等等,比较多的时候难免有人会漏掉这样方法.所以说还是通过接口更可靠一些,约束力更强一些.

C#接口的作用以及相关的内容就向你介绍到这里,希望对你了解和学习C#接口的作用有所帮助。

posted @ 2012-04-10 21:12 青蛙學堂 阅读(198) | 评论 (0)编辑 收藏

c#--接口interface

通过学习对C#中接口的作用有了更进一步的理解,拿出来跟大家分享一下,有说的不对的地方请大家指教。
我在上一篇帖子(http://www.programfan.com/club/showbbs.asp?id=150228)中只是简单的谈了一下接口的作用,有兴趣的朋友可以去看一下。
言归正传:
    假设我们公司有两种程序员:VB程序员,指的是用VB写程序的程序员,用clsVBProgramer这个类表示;Delphi程序员指的是用Delphi写程序的程序员,用clsDelphiProgramer这个类来表示。 每个类都有一个WriteCode()方法。定义如下:

class clsVBProgramer()
{
  ....
  WriteCode()
  {
     //用VB语言写代码;
  }
  ....
}

class clsDelphiProgramer()
{
  ....
  WriteCode()
  {
    //用Delphi语言写代码;
  }
   ....
}

现在公司来了一个项目,要求派某个程序员写一个程序。
class clsProject()
{
  ....
  WritePrograme(clsVBProgramer programer)//用VB写代码
  {
    programer.WriteCode();
  }
  WritePrograme(clsDelphiProgramer programer)//重载方法,用Delphi写代码
  {
    programer.WriteCode();
  }
 ......
}
在主程序中我们可以这样写:
main()
{
   clsProject proj=new  clsProject;
   //如果需要用VB写代码
   clsVBProgramer programer1=new clsVBProgramer;
   proj.WritePrograme(programer1);
   //如果需要用Delphi写代码
   clsDelphiProgramer programer2=new clsDelphiProgramer;
   proj.WritePrograme(programer2);
}

但是如果这时公司又来了一个C#程序员,我们怎么改这段程序,使它能够实现用C#写程序的功能呢?我们需要增加一个新类clsCSharpProgramer,同时在此clsProject这个类中要再次重载WritePrograme(clsCSharpProgramer programer)方法。这下麻烦多了。如果还有C程序员,C++程序员,JAVA程序员呢。麻烦大了!

但是如果改用接口,就完全不一样了:
首先声明一个程序员接口:
interface IProgramer()
{
  WriteCode();
}
然后声明两个类,并实现IProgramer接口:
class clsVBProgramer():IProgramer
{
  ....
  WriteCode()
  {
     //用VB语言写代码;
  }
  ....
}

class clsDelphiProgramer():IProgramer
{
  ....
  WriteCode()
  {
    //用Delphi语言写代码;
  }
   ....
}
对clsProject这个类进行一下修改:
class clsProject()
{
  ....
  WritePrograme(IProgramer programer)
  {
    programer.WriteCode();//写代码
  }
  ......
}

main()
{
   clsProject proj=new  clsProject;
   IProgramer programer;
   //如果需要用VB写代码
   programer=new clsVBProgramer;
   proj.WritePrograme(programer);
   //如果需要用Delphi写代码
   programer=new clsDelphiProgramer;
   proj.WritePrograme(programer);    
}
如果再有C#,C,C++,JAVA这样的程序员添加进来的话,我们只需把它们相关的类加进来,然后在main()中稍做修改就OK了。扩充性特别好!

另外我们如果把clsProject这个类封成一个组件,那么当我们的用户需要要扩充功能的时候,我们只需要在外部做很小的修改就能实现,可以说根本就用不着改动我们已经封好组件!是不是很方便,很强大!

posted @ 2012-04-10 21:03 青蛙學堂 阅读(124) | 评论 (0)编辑 收藏

c#--委托

我是这样理解的:委托是对方法的引用,相当于方法的别名,也就是说委托与方法具有相同的行为。

委托变量说白了就是接受方法名作为参数的变量,当我们使用这个委托变量的时候就相当于调用了这个方法。

我也感觉"委托"就是方法别名,或者调用别人的方法时,不用原来的方法名,可以自己起一个有意义的名字(联想一下文件的快捷方式)

委托在现实生活中来说就是你叫别人去帮你做一件事(别人做事用到方法),然后他把事做了之后给你返回个结果。

你可以直接打电话给奥巴马,不过一般情况下是他的助手转接的,并且他的助手会告诉你,我们已经给你汇报啦,他的助手就是个委托。

委托是为事件而生的,事件用的是消息处理机制,任何委托的函数都由消息来触发,他在消息处理线程运行
我觉得委托的意思就是,委托Windows的消息处理去处理一个函数。

方法参数化

想把方法作为参数吗?就使用委托吧~

参数是什么作用? 答:运行时候可以传入不同的值,fun(int a),我第一次运行时传入5,第二次运行时候传入3
方法作为参数呢? 答:运行时候可以传入不同的方法,具体例子很多。

委托是一种定义方法签名的类型,可以与具有兼容签名的任何方法关联。您可以通过委托调用方法。委托用于将方法作为参数传递给其他方法。事件处理程序就是通过委托调用的方法

using System;
//定义委托,它是一个函数声明,但是没有实现
public delegate string Mydelegate(string s);
// 定义类
public class A
{
// 定义方法,为了使用委托,方法签名与委托签名相同,就是返回类型 参数与委托签名相同
public string UpperMethod(string ss)
{
    return ss.ToUpper();
}
// 定义方法,为了使用委托,方法签名与委托签名相同,就是返回类型 参数与委托签名相同
public string LowerMethod(string ss)
{
    return ss.ToLower();
}
}

class Program
{
public static void Main(string[]args)
{
    // 实例化类
    A aa = new A();
    //委托可以与你的方法绑定啦
    Mydelegate del = new Mydelegate(aa.UpperMethod);
    //Mydelegate del += new Mydelegate(aa.LowerMethod);
    Console.WriteLine(del("adAAd"));
    //给委托添加一个方法,形成委托链
    del += aa.LowerMethod;
    Console.WriteLine(del("adAAd"));
    //调用委托,可以调到所有已经与此委托绑定的方法
}
}


posted @ 2012-04-10 16:57 青蛙學堂 阅读(176) | 评论 (0)编辑 收藏

泛型--转

一、泛型用途
  泛型的用途主要是实现动态类型,数据类型也作为一中参数来处理。通过泛型可以定义类型安全类,而不会损害类型安全、性能或工作效率。实例化类型推迟到客户端实现时,主要用途就是代码重用。比如一种数据结构或设计模式,在没有泛型支持的时候,必须对每一种对象类型编写相似的代码才可以实现。如,一个Tree,当Node里为字条串是一个,数字是一个,其他类又是一个,这个一个Tree,就有了多种类的实现,这是不利于代码的重用和维护的。另一种变通的方法Node中包含数据的地方用object来代替,这样做的问题一是如果Data域为值类型,会造成频繁的装箱和拆箱操作,影响效率。二是类型安全问题,需要用到强制类型转换,不能对客户端代码进行适当的限制,容易出现未知的错误。
二、泛型语法
泛型用"<>"括起来,括号里面是泛型(一般类型参数)名称,在实例化时,用适当的实参代替。泛型在类上声明,在类的方法或成员声明时引用:
 public class Node<K, T>

 public someMethod(K someParameter)
{
}
... ...

三、泛型可以在不同类进行引用和传递,既一个类定义了泛型,另外一个泛型类也可以引用这个类中的泛型而实现为一个泛型类。泛型类也可以有继承关系。
四、泛型约束:
存在三个类型的约束。派生约束指示编译器一般类型参数派生自诸如接口或特定基类之类的基类型。默认构造函数约束指示编译器一般类型参数公开了默认的公共构造函数(不带任何参数的公共构造函数)。引用/值类型约束将一般类型参数约束为引用类型或值类型。一般类型可以利用多个约束,您甚至可以在使用一般类型参数时使 IntelliSense 反射这些约束,例如,建议基类型中的方法或成员。

语法:where
  派生约束:类或接口的名字 不能将 System.Delegate 或 System.Array 约束为基类。
 引用 、值约束:值约束:struct 类约束:class
  默认构造函数:new(),默认构造函数要放在其他约束之前
public class Node<K, T> where K:new(),class,IComparable where T:struct
{
}

五、示例

    public class Node<K, T> where K : IComparable
    {
        public K Key;
        public T Item;
        public Node<K,T> NextNode;
        public Node()
        {
            Key = default(K);
            Item = default(T);
            NextNode = null;
        }
        public Node(K key, T item, Node<K,T> nextNode)
        {
            Key = key;
            Item = item;
            NextNode = nextNode;
        }
    }

    public class LinkedList<K, T> where K : class,IComparable,new()
    {
        Node<K,T> m_Head;
        public LinkedList()
        {
            m_Head = new Node<K,T>();
        }
        public void AddHead(K key, T item)
        {
            Node<K,T> newNode = new Node<K,T>(key, item, m_Head.NextNode);
            m_Head.NextNode = newNode;
        }
    }

posted @ 2012-04-10 16:20 青蛙學堂 阅读(181) | 评论 (0)编辑 收藏

仅列出标题
共43页: First 11 12 13 14 15 16 17 18 19 Last 
<2024年5月>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

导航

统计

常用链接

留言簿(8)

随笔分类

随笔档案

收藏夹

青蛙学堂

最新评论

阅读排行榜

评论排行榜