面向对象

继承——————子承父业

继承是软件(代码)复用的一种形式。使用继承可以复用现有类的数据行为(方法),为其赋予新的功能(方法)从而创建出新类。复用能节省程序开发的时间,能重用经过实践检验和调试的高质量代码,从而提高系统的质量。

继承的定义和使用

在现有的类(也称是直接基类,父类)上创建新类(称为派生类,子类)的处理过程称为继承。

派生类能自动获得基类的除构造函数和析构函数以外的所有成员,可以在派生类中添加新的属性和方法扩展其功能。

语法为:

<访问修饰符> class 派生类名:基类名

{

   类的成员。(类的代码)

}

在实际中一个类的对象也是另一个类的对象。

如:

教师类和学生类都可以从人这个类派生,而讲师,教授可以从教师类中派生,研究生和本科生可以从学生类派生而得到。

如:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication2
{

    public class Person
    {
        private string _id;//声明身份证号码字段
        public string Id//声明身份证号码属性
        {
            get//get访问器,得到身份证号码字段的值
            {
                return _id;
            }
            set//set访问器设置身份证号码字段的值
            {
                _id = value;
            }
        }
        private string _name;//声明姓名字段
        public string Name//声明姓名属性
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
            }
        }
        private int _age;//声明年龄字段
        public int Age//声明年龄属性
        {
            get
            {
                return _age;
            }
            set
            {
                _age = value;
            }
        }
        private string _gender;//声明性别字段
        public string Gender//声明性别属性
        {
            get
            {
                return _gender;
            }
            set
            {
                _gender = value;
            }
        }
        public Person()//定义无参的构造函数
        { }
        public Person(string name, int age, string gender)//定义3个参数的构造函数
        {
            _name = name;
            _age = age;
            _gender = gender;
        }
        public void Display()//用于输出Person对象的姓名,性别,和年龄信息
        {
            Console.WriteLine("{0}是{1}性,年龄为{2}",this._name,this._gender,this._age);
        }
    }
    public class Student : Person//创建派生类,派生自Person
    {
        private string _class;//定义表示学生所在班级的字段_class
        public string Class//定义获取或设置班级信息的属性Class
        {
            get
            {
                return _class;
            }
            set
            {
                _class = value;
            }
        }
        private string _department;//定义学生所属系的字段
        public string Department//定义学生所属系的属性
        {
            get
            {
                return _department;
            }
            set
            {
                _department = value;
            }
        }
        private string _no;//定义表示学生学号的字段
        private string No//定义学好的属性
        {
            get
            {
                return _no;
            }
            set
            {
                _no = value;
            }
        }
        public Student()//无参构造函数
        { }
        public void Study()//定义派生类独有的方法Studuy,表示学生负有学习的任务
        {
            Console.WriteLine("学生在学校学习!");
        }
    }
   

        class Program
        {
            static void Main(string[] args)
            {

                Person objperson = new Person("张三",18,"");//创建Person的对象objperson
                objperson.Display();//调用Display方法显示对象信息
                Student objstudent = new Student();//创建Student的对象objstudent
                objstudent.Name = "李四";
                objstudent.Age = 18;
                objstudent.Gender = "";
                objstudent.Class = "2016软件工程专业1班";
                objstudent.Display();//访问基类Display方法
                objstudent.Study();//调用派生类方法
              
                Console.ReadKey();

            }

      


        }


    }

运行结果

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication2
{

    public class Person
    {
        private string _id;//声明身份证号码字段
        public string Id//声明身份证号码属性
        {
            get//get访问器,得到身份证号码字段的值
            {
                return _id;
            }
            set//set访问器设置身份证号码字段的值
            {
                _id = value;
            }
        }
        private string _name;//声明姓名字段
        public string Name//声明姓名属性
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
            }
        }
        private int _age;//声明年龄字段
        public int Age//声明年龄属性
        {
            get
            {
                return _age;
            }
            set
            {
                _age = value;
            }
        }
        private string _gender;//声明性别字段
        public string Gender//声明性别属性
        {
            get
            {
                return _gender;
            }
            set
            {
                _gender = value;
            }
        }
        public Person()//定义无参的构造函数
        { }
        public Person(string name, int age, string gender)//定义3个参数的构造函数
        {
            _name = name;
            _age = age;
            _gender = gender;
        }
        public void Display()//用于输出Person对象的姓名,性别,和年龄信息
        {
            Console.WriteLine("{0}是{1}性,年龄为{2}",this._name,this._gender,this._age);
        }
    }
    public class Student : Person//创建派生类,派生自Person
    {
        private string _class;//定义表示学生所在班级的字段_class
        public string Class//定义获取或设置班级信息的属性Class
        {
            get
            {
                return _class;
            }
            set
            {
                _class = value;
            }
        }
        private string _department;//定义学生所属系的字段
        public string Department//定义学生所属系的属性
        {
            get
            {
                return _department;
            }
            set
            {
                _department = value;
            }
        }
        private string _no;//定义表示学生学号的字段
        private string No//定义学好的属性
        {
            get
            {
                return _no;
            }
            set
            {
                _no = value;
            }
        }
        public Student()//无参构造函数
        { }
        public void Study()//定义派生类独有的方法Studuy,表示学生负有学习的任务
        {
            Console.WriteLine("学生在学校学习!");
        }
    }

    class Teacher : Person
    {
        private string _tid;
        public string Tid
        {
            get
            {
                return _tid;
            }
            set
            {
                _tid = value;
            }
        }
        public string _course;
        public string Course
        {
            get
            {
                return _course;
            }
            set
            {
                _course = value;
            }
        }
        public void Teaching()
        {
            Console.WriteLine("教师在学校教课");
        }
    }
    public class DoubleStudent : Student
    {
        private string _sndBachelor;
        public string SndBachelor
        {
            get
            {
                return _sndBachelor;
            }
            set
            {
                _sndBachelor = value;
            }
        }
        public DoubleStudent()
        {
 
        }
        public void UsaBachelor()
        {
            Console.WriteLine("正在攻读美国Fort Hays 大学学位");
        }
    }
        class Program
        {
            static void Main(string[] args)
            {
                Teacher objTeacher = new Teacher();//创建Teacher类的对象
                objTeacher.Name = "Martin";
                objTeacher.Age = 35;
                objTeacher.Gender = "";
                objTeacher.Display();
                objTeacher.Teaching();
                Console.WriteLine("DoubleStudent");
                DoubleStudent objspecial = new DoubleStudent();
                objspecial.Name = "Bliss";
                objspecial.Age = 18;
                objspecial.Gender = "";
                objspecial.Display();
                objspecial.Study();
                objspecial.UsaBachelor(); 

              
                Console.ReadKey();

            }

      


        }


    }

运行结果

继承的特性

1,继承的可传递性

如果C从B中派生,B又从A中派生,那么C不仅继承了B中声明的成员,同样也继承了A中的成员。派生类是对基类的扩展,在派生类中可以添加新成员,但不能去除已经继承的成员。

构造函数和析构函数不能被继承。除此以外的其他成员,不论对它们定义了怎样的访问方式,都能被继承。基类中成员的访问方式只能决定派生类能否访问它们。派生类如果定义了与继承而来的成员同名的新成员,就可以覆盖已继承的成员。但这并不意味派生类删除了这些成员,只是不能再访问这些成员。

2,继承的单一性

继承的单一性是指派生类只能从一个基类中继承,不能同时继承多个基类。C#不支持类的多重继承,也就是说儿子只能有一个亲生父亲,不能同时拥有多个亲生父亲,多重继承可以通过接口实现。

3,继承中的访问修饰符

C#中的访问修饰符有public,protected,private,internal和protected internal等5种,可以使用这些访问修饰符指定5个可访问性级别:public, protected,internal,protected internal和private。在继承时各个访问修饰符的访问权限如表所示

访问修饰符 类内部 派生类
public 访问权限不受限制 不受限制
protected 访问仅限于包含类或从包含类派生的类型 可以访问
internal 访问仅限于当前项目 可以访问
protected  internal 访问仅限于从包含类派生的当前项目或类型 可以访问
private 访问仅限于包含类型 不可访问

基类中的成员如果使用public修饰,任何类都可以访问;如果用privatc修饰,它将作为私有成员,只有类本身可以访问,其他任何类都无法访问。在C#中,我们使用protected修饰符,使用这个访问修饰符的成员可以被其派生类访问,而不允许其他非派生类访问。

base和this关键字

通过上面的介绍可以知道,基类中只能被public,protected,internal修饰的成员才可以被访问,这些成员包括任何基类的字段,属性,方法和索引器,但是基类的构造函数和析构函数是不能被继承的。如果要继承基类的构造函数,必须使用base关键字来实现。C#中的base关键字代表基类,使用base关键字可以调用基类的构造函数,属性和方法。使用base关键字调用基类构造函数的语法如下:

派生类构造函数:base(参数列表)

例如:

    public Student(string name,int age,string gender):base(name,age ,gender)//无参构造函数
        { 

        }

使用base关键字调用基类方法的语法如下:

base.基类方法();

   public void Study()//定义派生类独有的方法Studuy,表示学生负有学习的任务
        {
            Console.WriteLine("学生在学校学习!");
            base.Display();//使用base关键字调用基类方法
        }

相对于base来说,this关键字是引用类的当前实例。例如:

   public Person(string name, int age, string gender)//定义3个参数的构造函数
        {
           this. _name = name;
           this._age = age;
           this. _gender = gender;
        }

this关键字引用类的当前实例,还可用做扩展方法的第一个参数的修饰符,this关键字还可以调用自己的构造方法。使用this关键字可以使代码的编写简单化,不容易出错。在类的方法里输入this关键字,在后面输入一个“.”符号后,系统就会把本类所能调用的非静态方法和变量都显示出来供选择,这样可以提高编写代码的效率。

派生类继承基类的属性和方法,使创建派生类变得简单,可实现代码的重用。继承还有个重要的特性,就是基类对象可以引用派生类对象,也就是派生类对象可以赋值给基类对象。

如:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication2
{

   
        public class Person
        {
            private string _id;
            public string Id
            {
                get
                {
                   return this._id;
                }
                set
                {
                    this._id=value;
                }
            }
            private string _name;
            public string Name
            {
                get
                {
                    return this._name;
                }
                set
                {
                    this._name=value;
                }
            }
            private int _age;
            public int Age
            {
                get
                {
                    return this._age;
                }
                set
                {
                    this._age=value;
                }
            }
            private string _gender;
            public string Gender
            {
                get
                {
                    return this._gender;
                }
                set
                {
                    this._gender=value;
                }
            }
            public Person()
            {

            }
            public Person(string name,int age,string gender)
            {
                this._name=name;
                this._age=age;
                this._gender=gender;
            }
            public void Display()
            {
                Console.WriteLine("{0}是{1}性,年龄为{2}",this._name,this._gender,this._age);
            }
        }
        public class Student:Person
        {
            private string _class;
            public string Class
            {
                get
                {
                    return _class;
                }
                set
                {
                    _class=value;
                }
            }
            private string _department;
            public string Departmtent
            {
                get
                {
                    return this._department;
                }
                set
                {
                    this._department=value;
                }
            }
            private string _no;
            public string No
            {
                get
                {
                    return this._no;
                }
                set
                {
                    this._no=value;
                }
            }
            public Student()
            {

            }
            public Student(string name,int age,string gender):base(name,age,gender)
            {

            }
            public void Study()
            {
                Console.WriteLine("学生在学习呢!");
            }
        }

        class Program
        {
            static void Main(string[] args)
            {
                Person objPerson = new Person("刘六",18,"");
                Console.WriteLine("基类Person对象的Display方法");
                objPerson.Display();
                Student objstudent = new Student("王七",18,"");
                objstudent.Class = "2016软件工程专业1班";
                Console.WriteLine("派生类调用基类Person对象的Displauy方法:");
                objstudent.Display();
                Console.WriteLine("派生类调用自己的Study方法:");
                objstudent.Study();
                Console.WriteLine("基类对象引用派生类实例");
                Person person = new Person();
                person = objstudent;
                ((Student)person).Study();
              
                Console.ReadKey();

            }

      


        }


    }

运行结果

 面向对象——多态

"多态“最早用于生物学,指同一种族的生物体具有相同的特性。

比如青蛙小的时候是蝌蚪,长大了就是青蛙,同是一种生物但是有不同的表现形式。

C#中,多态的定义是:同一操作作用于不同的类的对象,不同的类的对象进行不同的执行,最后产生不同的结果。

多态的实现

C#中支持基于接口的多态和基于继承的多态,基于继承的多态设计在基类中定义方法,并在派生类中重写方法。多态和重写是紧密联系的,重写是实现多态的重要手段,重写基类方法就是修改它的实现,或者说在派生类中对继承的基类方法的重新编写。在基类中用virtual关键字声明的方法(叫做虚拟方法)在派生类中可以重写,虚拟方法语法如下;

访问修饰符 virtual 返回类型 方法名()

{

   //方法体

}

在派生类中使用override关键字来声明重写,以实现对基类中虚拟方法的修改或重新编写。

例如:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication2
{

   
        public class Person
        {
            private string _id;
            public string Id
            {
                get
                {
                   return this._id;
                }
                set
                {
                    this._id=value;
                }
            }
            private string _name;
            public string Name
            {
                get
                {
                    return this._name;
                }
                set
                {
                    this._name=value;
                }
            }
            private int _age;
            public int Age
            {
                get
                {
                    return this._age;
                }
                set
                {
                    this._age=value;
                }
            }
            private string _gender;
            public string Gender
            {
                get
                {
                    return this._gender;
                }
                set
                {
                    this._gender=value;
                }
            }
            public Person()
            {

            }
            public Person(string name,int age,string gender)
            {
                this._name=name;
                this._age=age;
                this._gender=gender;
            }
            public virtual  void Display()
            {
                Console.WriteLine("{0}是{1}性,年龄为{2}",this._name,this._gender,this._age);
            }
        }
        public class Student:Person
        {
            private string _class;
            public string Class
            {
                get
                {
                    return _class;
                }
                set
                {
                    _class=value;
                }
            }
            private string _department;
            public string Departmtent
            {
                get
                {
                    return this._department;
                }
                set
                {
                    this._department=value;
                }
            }
            private string _no;
            public string No
            {
                get
                {
                    return this._no;
                }
                set
                {
                    this._no=value;
                }
            }
            public Student()
            {

            }
            public Student(string name,int age,string gender):base(name,age,gender)
            {
                this._class = "三班";
                this._department = "建筑系";
                this._no = "141020";
            }
            public void Study()
            {
                Console.WriteLine("学生在学习呢!");
            }
            public override void Display()
            {
                base.Display();
                Console.WriteLine("学生在学习呢!");
            }
        }

        class Program
        {
            static void Main(string[] args)
            {
              
               
                Person objPerson = new Person("刘六",18,"");
                Console.WriteLine("基类Person对象的Display方法");
                objPerson.Display();
                Student objstudent = new Student("王七",18,"");
                objstudent.Class = "2016软件工程专业1班";
                Console.WriteLine("Student对象的Display方法");
                objstudent.Display();
                Console.ReadKey();

            }

      


        }


    }

方法的重载,重写和隐藏

在基类和派生类中可以存在同名方法,这些同名的方法可以为重载,重写和隐藏等3种类型。

1.重载

重载是在同一作用域内发生的(比如一个类里面),定义一系列同名方法,但是方法的参数列表不同,就是签名不同,签名由方法名和参数组成。通过传递不同的参数来决定到底调用哪一个同名方法,返回值类型不同不能构成重载,因为签名不包括返回值。

2.重写

基类方法中使用virtual关键字声明的方法和派生类中使用override关键字声明的方法名称相同,参数列表也相同,就是基类方法和派生类方法的签名相同,实现了派生类重写基类中的同名方法。

3.隐藏

基类中的方法不声明为virtual(默认为非虚方法),在派生类中声明与基类同名时,需使用new关键字,以隐藏基类同名的方法。

例如:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication2
{

   
        public class Person
        {
            
            public virtual  void Display()
            {
                Console.WriteLine("这是一个人");
            }
            public void Display(string name)
            {
                this.Display();
                Console.WriteLine("这个人的名字叫{0}",name);
            }
        }
        public class Student:Person
        {
           
            public override void Display()
            {
                base.Display();
                Console.WriteLine("学生在学习呢!");
            }
            public new void Display(string name)
            {
                Console.WriteLine("这个方法隐藏了基类的方法");
            }
        }

        class Program
        {
            static void Main(string[] args)
            {
              
               
             
                Console.ReadKey();

            }

      


        }


    }

统一的接口—————接口

接口是面向对象编程的一个重要技术,在C#中负责实现多重继承。一个接口定义一个协议,实现接口的类或结构必须遵守其协定。

接口的定义

接口是用来描述一种程序的规定,可定义属于任何类或结构的一组相关行为。接口由方法,属性,事件,索引器或这4种成员类型的任何组合构成。

接口不能包含常数,字段,运算符,实例构造函数,析构函数或类型,也不能包含任何种类的静态成员。

接口的成员一定是公共的。

定义接口的语法如下:

<访问修饰符>interface 接口名

{

//接口的主体

 

}

接口不能包含其所定义的成员的任何实现语句,接口只指定实现该接口的类或必须提供的成员。

接口的实现

定义了接口后,就要在类或结构中实现。C#中通常把派生类和基类的关系称为继承,类和接口的关系称为实现。实现接口的语法和继承类一样,都有“:”,接口中的方法在类中实现时不是重载,不需要使用override关键字。

接口中不能定义构造函数,所以接口不能实例化。

例如:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication2
{
    interface IPoint
    {
        int x { get; set; }
        int y { get; set; }
    }
    class Point : IPoint
    {
        private int px;
        private int py;
        public Point(int x, int y)
        {
            px = x;
            py = y;
        }
        public int x
        {
            get
            {
                return px;
            }
            set
            {
                py = value;
            }
        }
        public int y
        {
            get
            {
                return py;

            }
            set
            {
                py = value;
            }
        }

    }
        class Program
        {
            static void Main(string[] args)
            {

                Point p = new Point(5, 30);
                Console.Write("新创建的Point点的坐标是:");
                Console.WriteLine("x={0},y={1}",p.x,p.y);
             
                Console.ReadKey();

            }

      


        }


    }

再次进行扩展

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication2
{
    interface IPerson
    {
        void DoWork();//表示person在做工作

        void DoExercise();//表示person锻炼身体
    }
    public class Person : IPerson
    {
        private string _id;
        public string Id
        {
            get
            {
                return _id;
            }
            set
            {
                _id = value;
            }
                
        }
        private string _name;
        public string Name
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
            }
        }
        private int _age;
        public int Age
        {
            get
            {
                return _age;

            }
            set
            {
                _age = value;
            }
        }
        private string _gender;
        public string Gender
        {
            get
            {
                return _gender;
            }
            set
            {
                _gender = value;

            }
        }
        public Person()
        {}
        public Person(string name, int age, string gender)
        {
            this._name = name;
            this._age = age;
            this._gender = gender;
        }
        public void DoWork()
        {
            Console.WriteLine("{0}每天的任务是工作",this._name);
        }
        public void DoExercise()
        {
            Console.WriteLine("{0}每天下午参加体育锻炼",this._name);
        }
        public void Diplay()
        {
            Console.WriteLine("{0}是{1}性,年龄为{2}",this._name,this._gender,this._age);
        }
 
    }
   
        class Program
        {
            static void Main(string[] args)
            {

                Person p1 = new Person("Johnson",28,"");
                p1.Diplay();
                p1.DoWork();
                p1.DoExercise();
             
                Console.ReadKey();

            }

      


        }


    }

接口的继承

C#中的派生类只有一个基类,不支持类的多重继承,但可以继承多个接口,通过接口实现多继承。

其实接口就是为实现多继承产生的。在C#中接口可以多继承,接口之间可以相互继承,普通类和抽象类可以继承自接口。一个类可以同时继承一个类和多个接口,但是接口不能继承类。

抽象类和抽象方法

抽象类:简单的说就是用来描述共性的类就是抽象类,(抽象类是对类的抽象,类是对对象的抽象)抽象类中不考虑具体的实现,只确定必须具有的行为,即确定抽象方法。

包含抽象方法的类就是抽象类,抽象类和抽象方法声明使用abstract关键字。语法如下:

<访问修饰符>abstract class 抽象类名

{

   <访问修饰符> abstract 返回类型 方法名();

}

实现抽象方法

C#中通过方法重写来实现抽象方法。当一个抽象基类派生一个派生类时,派生类将继承基类的所有特征,重新实现所有的抽象方法。在派生类中实现基类的抽象方法,是使用override关键字来重写基类方法。

例如:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication2
{
    public abstract class Employee
    {
        public abstract void Display();
    }
    public class Manager : Employee
    {
        private string name;
        public Manager(string name)
        {
            this.name = name;
        }
        public override void Display()
        {
            Console.WriteLine("Name:"+name);
        }
    }
        class Program
        {
            static void Main(string[] args)
            {
                Manager obj = new Manager("Johnson");
                obj.Display();
                Console.ReadKey();

            }

      


        }


    }

接口,类和抽象类

 一个类可以同时继承类和接口,或者抽象类和接口,抽象类和类不能在一个类的继承列表中同时出现。如果派生类同时继承类或抽象类和接口,一定要把类或者抽象类写在前面,接口写在后面,类名和接口名用“,”隔开,接口没有先后顺序。每一种继承都要根据各自的规则去实现。

接口与抽象类的区别:

1,抽象类是一个不完全的类,需要通过派生类来完善它。

2,接口只是对类的约束,它仅仅承诺了类能够调用的方法。

3,一个类一次可以实现若干个接口。但一个类只能继承一个基类。

4,抽象类只需派生类实现它的抽象方法,接口要求必须实现它的所有成员。在实际编程中,接口的使用要比抽象类广泛得多。

密封类

与抽象类相反的是,C#支持创建密封类,密封类是不能当做基类的类。其他的类不能从此类派生,从而保证了密封类的密封性和安全性。在C#中使用sealed关键字创建密封类。

如:

public selaed class Animal

{

    public Animal()

     {

              Console。WriteLine(“Animal被构造”);

     }

}

设计类的时候,通常情况下是不需要将类设置为密封类的,因为密封类会让类的扩展性非常差,这个类也无法再次扩展和派生。但是出于某种目的,当程序块只需要完成某些特定的功能或者在商业上为保密,就可以使用密封类对类进行密封,以保证类的可靠性。

委托,事件和索引器

委托和事件是C#中两个比较复杂的概念。

委托

委托也叫代理,就是把事情交付给别人去办,如委托律师代理打官司。

C#中如果将一个方法委托给一个对象,这个对象就可以全权代理这个方法的执行。使用委托首先要定义委托,声明委托能代理什么类型的方法,定义委托的语法如下:

<访问修饰符> delegate 返回类型 委托名();

从上面不难看出定义委托和定义方法类似。委托没有具体的实现体,委托能够代表什么样的方法由它的返回值类型和参数列表决定。如定义如下委托:

public delegate void StuDelegate(string name);

使用stuDelegate委托代表的只可以是没有返回值,且参数为一个字符串的方法。

定义了委托之后就要使用委托,首先要实例化委托。实例化委托就是将其指向某个方法,即调用委托的构造函数,并将相关联的方法作为参数传递,然后通过调用委托,执行相关方法的代码,实现委托。

如:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication2
{
    class Test
    {
        public static bool SortArray(int[] array)
        {
            for (int i = array.GetUpperBound(0); i >= 0; i--)
            {
                for (int j = 0; j <= i; j++)
                {
                    if (array[j] <= array[i])
                    {
                        Swap(ref array[j], ref array[i]);
                    }
 
                }
               
            } 
            return true;
        }
        static void Swap(ref int x, ref int y)
        {
            int temp = x;
            x = y;
            y = temp;
        }
    }
   
        class Program
        {
            public delegate bool SortDelegate(int[] x);

            static void Main(string[] args)
            {
                int[] arr = new int[] { 8, 9, 5, 7, 2, 1, 4, 5, 6 };
                Console.WriteLine("排顺序前的数组元素:");
                foreach (int i in arr)
                {
                    Console.WriteLine("{0}",i);
 
                }
                SortDelegate mydelegate;
                mydelegate = new SortDelegate(Test.SortArray);
                mydelegate(arr);
                Console.WriteLine("排顺序后的数组元素:");
                foreach (int i in arr)
                {
                    Console.WriteLine("{0}", i);

                }
                Console.ReadKey();

            }

      


        }


    }

 使用Lambda表达式运行结果不变

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication2
{
   
   
        class Program
        {
            public delegate bool SortDelegate(int[] x);

            static void Main(string[] args)
            {
                int[] arr = new int[] { 8, 9, 5, 7, 2, 1, 4, 5, 6 };
                Console.WriteLine("排顺序前的数组元素:");
                foreach (int i in arr)
                {
                    Console.WriteLine("{0}",i);
 
                }
                SortDelegate mydelegate = array =>
                {
                    for (int i = array.GetUpperBound(0); i >= 0; i--)
                    {
                        for (int j = 0; j <= i; j++)
                        {
                            if (array[j] <= array[i])
                            {
                                int temp = array[j];
                                array[j] = array[i];
                                array[i] = temp;
                            }
                        }
                    }
                    return true;
                };
                mydelegate(arr);
             
                Console.WriteLine("排顺序后的数组元素:");
                foreach (int i in arr)
                {
                    Console.WriteLine("{0}", i);

                }
                Console.ReadKey();

            }

      


        }


    }

索引器

索引器允许类或结构的实例就像数组一样进行索引。索引器类似于属性,不同之处在于它们的访问器采用的参数。索引器主要用于封装内部集合或数组的类中。索引器类似于字典中的检索,在字典中可以进行拼音检索和部首检索等方式查找汉子,索引器可以根据需要设定不同的检索方式快速查找类或结构的实例。索引器表示法不仅简化了客户端应用程序的语法,还使其他开发人员能够更加直观地理解类及其用途。要声明类或结构上的索引器,应使用关键字this如:

public int this[int index]

{

}

例如:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication2
{

    class DayCollection
    {
        string[] days = { "Sun", "Mon", "Tues", "Wed", "Thurs", "Fri", "Sat" };
        private int GetDay(string testDay)
        {
            int i = 0;
            foreach (string day in days)
            {
                if (day == testDay)
                {
                    return i;
                }
                i++;
            }
            return -1;
        }
        public int this[string day]
        {
            get
            {
                return GetDay(day);
            }
        }
    }
   
   
        class Program
        {
            static void Main(string[] args)
            {
                DayCollection week = new DayCollection();
                Console.WriteLine(week["Fri"]);
                Console.WriteLine(week["Invalid Day"]);
                
                Console.ReadKey();

            }

      


        }


    }

运行结果为:5,-1;

再例如:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication2
{

    class TempRecord
    {
        private float[] temps = new float[10]{56.2F,56.7F,56.5F,56.9F,58.8F,
                                          61.3F,65.9F,62.1F,59.2F,57.5F};
        System.DateTime date { get; set; }
        public int Length
        {
            get { return temps.Length; }
        }
        public float this[int index]
        {
            get
            {
                return temps[index];
            }
            set
            {
                temps[index] = value;
            }
        }
    }
   
   
        class Program
        {
            static void Main(string[] args)
            {
                TempRecord temp = new TempRecord();
                temp[3] = 58.3F;
                temp[5] = 60.1F;
                for (int i = 0; i < 10; i++)
                {
                    if (i < temp.Length)
                    {
                        Console.WriteLine("元素{0}={1}", i, temp[i]);
                    }
                    else
                    {
                        Console.WriteLine("索引值{0}超出范围",i);
                    }
                }

                    Console.ReadKey();

            }

      


        }


    }

事件

事件是C#中的一个高级概念,是操作发生时允许执行特定于应用程序的代码的机制,事件要么在相关联的操作发生前发生(事前事件)要么在操作发生后发生(事后事件)。

例如,当用户单击窗口中的按钮时,将引发一个事后事件,以允许执行特定于应用程序的方法。

类和对象可以通过事件向其他类或对象通知发生的相关事情。发送(或引发)事件的类称为“发行者”,接受(或处理)事件的类称为“订户”。在典型的C#Windows 窗体或web应用程序中,可以订阅由控件(如按钮和列表框)引发的事件。如在考场上老师说“开始考试”,学生就开始答卷,其中老师说的“开始答卷”是事件,“学生开始答卷”是这个事件引发的动作。老师是事件的发行者。学生是事件的订户。

定义和使用事件一般有下面几个步骤

1,在一个类中声明关于事件的委托。

public delegate void 事件类型名称(object serder,EventArgs e);

事件的类型名称建议用EventHandler结尾。如果想自定义事件的参数EventArgs,可以用EventArgs类派生自己的事件参数类,也可以没有参数。

2,在类中声明事件。使用步骤1的delegate做为事件的类型。

public event 事件类型名称 事件名称;

3,在类中需要引发事件的方法中,编写引发事件的方法。

事件名称(this,new EventArgs());或者

if(事件名称!=null) 事件名称(this,new EventArgs());

4,订阅事件,当事件发生时通知订户。

带有事件的类的实例.事件名称+=new 事件名称(事件处理方法名称);

5,编写事件处理方法

public void 事件处理方法名称(object sender ,EventArgs e)

{

要添加的代码

}

6,在适当的条件下触发事件,即需要调用步骤3中的引发事件的方法。

范例:事件的定义和使用

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication2
{

   public class Heater
    {
       private int temperature;
       public delegate void BoilHandler(int param);
       public event BoilHandler BoilEvent;
       public void BoilWater()
       {
           for (int i = 0; i <= 100; i++)
           {
               temperature = i;
               if (temperature > 96)
               {
                   if (BoilEvent != null)
                   {
                       BoilEvent(temperature);
                   }
               }
           }
       }
    }
   public class Alarm
   {
       public void MakeAlert(int param)
       {
           Console.WriteLine("Alarm:滴滴滴,水已经{0}度了", param);
       }
   }
   public class Display
   {
       public static void ShowMsg(int param)
       {
           Console.WriteLine("Display:水快烧开了,当前温度:{0}度",param);
       }
   }
        class Program
        {
            static void Main(string[] args)
            {
                Heater heater = new Heater();
                Alarm alarm = new Alarm();
                heater.BoilEvent += alarm.MakeAlert;
                heater.BoilEvent += Display.ShowMsg;
                heater.BoilWater();

                    Console.ReadKey();

            }

      


        }


    }

 

运行结果为:

 把Heater类不变,去掉Alarm类和Display类,使用匿名方法订阅事件

如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication2
{

   public class Heater
    {
       private int temperature;
       public delegate void BoilHandler(int param);
       public event BoilHandler BoilEvent;
       public void BoilWater()
       {
           for (int i = 0; i <= 100; i++)
           {
               temperature = i;
               if (temperature > 96)
               {
                   if (BoilEvent != null)
                   {
                       BoilEvent(temperature);
                   }
               }
           }
       }
    }
 
        class Program
        {
            static void Main(string[] args)
            {
                Heater heater = new Heater();
                heater.BoilEvent += delegate(int param)
                {
                    Console.WriteLine("Alarm:嘀嘀嘀,水已经{0}度了。", param);
                };
                heater.BoilEvent += delegate(int param)
                {
                    Console.WriteLine("Display:水烧开了,当前温度为:{0}度",param);
                };
                heater.BoilWater();

                    Console.ReadKey();

            }

      


        }


    }

运行结果与之前相同。

 

posted @ 2016-05-17 19:39  小李少  阅读(267)  评论(0编辑  收藏  举报