2 C#面向对象的特性

面向对象是当前计算机界关心的重点,是软件开发方法的主流,本章从面向对象的基本概念入手,详细分析面向对象中的知识点。面向对象主要涉及的概念有:类、对象、接口、继承、多态等,本章主要介绍C#中关于这些概念的应用。

2.1 面向对象编程概述

面向对象编程(OOP)是将现实中的事物抽象化,其设计的重点就是类的设计。本节介绍OOP开发中的一些基本术语。

2.1.1 什么是类和对象

类是面向对象程序设计的核心,实际上是一种复杂的数据类型。将不同类型的数据和与这些数据相关的操作封装在一起,就构成了类。而将抽象化的类具体化,就成了对象,通常说对象是类的实例。

类是将现实事物抽象化,而对象是将事物具体化。如“张三”是一个“学生”,那么张三其实是比较具体的一个人,而“学生”则是一个抽象事物。此时可以创建一个学生类,包含学号、年龄、班级等,如果指名张三的这些属性,则张三是学生类的一个实例。

现在创建一个学生类“Student”,代码如下所示,其中get是类的访问器,用来返回对象的实际值。

    1.     public class Student
    2.     {
    3.         public string StudentNo
    4.         {get{return"";}}
    5.         public int StudentAge
    6.         {get{return 0;}}
    7.         public string StudentGrade
    8.         {get{return"";}}
    9.     }

现在来实例化这个类,即创建一个对象“zhang”,代码如下所示。

    Student zhang = new Student();

通过这个实例,希望读者能够明白对象和类的概念,以及对象和类的关系。

2.1.2 用C#如何创建类

【本节示例参考:\示例代码\C02\ StudentClassAPP】

定义类的语法是基本相同的,但不同的工具创建类的方法会不同,下面演示在Windows应用程序中创建类的步骤。

1 新建一个Windows应用程序“StudentClassAPP”,在解决方案资源管理器中,在根目录上单击鼠标右键,在弹出的快捷菜单中选择“添加|新建项”菜单命令,打开“添加新项”对话框,如图2.1所示。

图2.1 “添加新项”对话框

2 选中“类”模板,修改名称为“Student.cs”。单击“添加”按钮,此时在根目录下生成一个“Student.cs”类文件,默认生成的代码如下所示,其中最顶端的3行代码,表示引用的程序集,这些程序集保存在.NET Framework中。namespace表示类所在的命名空间,默认会是当前的应用程序名。

    1.  using System;
    2.  using System.Collections.Generic;
    3.  using System.Text;
    4.
    5.  namespace WindowsApplication3
    6.  {
    7.     class Student
    8.     {
    9.     }
    10. }

3 上面生成了一个空的Student类,现在为类添加成员:学号、年龄、班级。代码如下所示。如果希望外部对象可以访问类中的各个成员,则成员的作用域为“public”,如“StudentNo”。如果变量只在类中有效,则作用域为“private”,如“ no”。

    1.     class Student
    2.     {
    3.         private string_no;
    4.         private int_age;
    5.         private string_grade;
    6.         public string StudentNo//学号
    7.         {
    8.            get{return_no;}
    9.            set{_no=value;}
    10.        }
    11.        public int StudentAge//年龄
    12.        {
    13.           get{return_age;}
    14.           set{_age=value;}
    15.        }
    16.        public string StudentGrade//班级
    17.        {
    18.           get{return_grade;}
    19.           set{_grade=value;}
    20.        }
    21.    }

4 在定义类中的成员时,本例使用了get{ }和set{ },这是类的两个访问器。get表示读取,set表示编写,如果一个成员只允许读取,则不需要set{}语句,相反则不需要get{}语句。在set语句中有个关键字“value”,用来表示用户赋给成员的值。

5 保存这些代码,VS2008会自动编译Student类。

2.1.3 用C#如何创建对象

前面创建了类“Student”,本例学习如何在C#中创建类的对象,演示步骤如下:

1 打开Windows应用程序“StudentClassAPP”。

2 在Form1.cs设计界面中,添加1个Button和1个Label,其中Label用来显示文本。Button用来处理业务逻辑。

3 双击Button按钮,切换到窗体的代码视图,书写创建对象的代码如下所示。

    1.         private void button1_Click(object sender,EventArgs e)
    2.         {
    3.            Student zhang=new Student();//创建对象
    4.            //以下其实是使用了类的编写器set
    5.            zhang.StudentNo="BJ100010";
    6.            zhang.StudentAge=16;
    7.            zhang.StudentGrade="高二";
    8.            //显示对象的内容,其实是使用了类的读取器get
    9.            label1.Text=zhang.StudentNo+zhang.StudentAge.ToString()+zhang.StudentGrade;
    10.        }

4 保存所有的代码。按F5运行程序,单击“Button”按钮,可以看到Label显示了对象的内容。

2.1.4 什么是面向对象编程

面向对象编程(Object-Oriented Programming),简称OOP,:是将程序的相关逻辑,包括属性和行为封装到编程所需的“对象”中。面向对象的编程语言,使得复杂的工作条理清晰、编写容易。

面向对象编程之所以流行,是因为其达到了软件工程的三个主要目标:重用性、灵活性和扩展性。面向对象编程的基本思想是使用对象的继承、封装、多态等来进行程序开发。面向对象编程的本质是以对象为中心,编写可重复利用、可方便扩展的代码。

图2.2以图形的方式,展示了面向对象开发的一个标准过程。

图2.2 面向对象开发的标准过程

2.2 面向对象的技术

面向对象的关键技术就是对象、类、接口、继承和多态。对象和类在第一节已经详细介绍过,本节介绍接口、继承和多态。

2.2.1 接口

接口只包含成员的定义,不包含成员的实现,成员是指类中的方法、属性、索引器和事件等。接口的主要目的是为不相关的类,提供通用的属性和行为,如C#中的接口“IDbConnection”,用来定义数据源的连接,提供了多个未实现的属性和方法,开发者可以自定义2个类“SqlConnection”和“AccessConnection”,并继承IDbConnection接口,那么这2个类就具备相同的成员,但实现内容不同,因为SqlConnection用来连接SQL Server数据库,而AccessConnection用来连接Access数据库。下面的代码演示一个简单的接口定义。其中“interface”是定义接口的关键字。

    1.     interface IConnection
    2.     {
    3.         public string DatabaseName;
    4.         public void AddDataBase();
    5.         public string GetDataBaseConn();
    6.     }

接口就好像一个模板,提供基本成员的结构,但并没有添加实质性的内容。由于C#不能实现多个类的继承,而可以实现多个接口的继承,所以使用接口,是可以让一个类具备两个以上基类的唯一方式。

2.2.2 用C#如何创建接口

现在演示用C#创建一个接口,步骤如下:

1 打开应用程序,在解决方案资源管理器中,右击根目录,在弹出的快捷菜单中,选择“添加|新建项”菜单命令,打开项模板对话框。

2 选中“接口”模板,默认名称为“Interface1.cs”。单击“添加”按钮,此时在根目录下生成一个“Interface1.cs”类文件,默认代码如下所示。

    1.  using System;
    2.  using System.Collections.Generic;
    3.  using System.Text;
    4.
    5.  namespace WindowsApplication3
    6.  {
    7.     interface Interface1
    8.     {
    9.     }
    10. }

3 默认生成一个空的接口“Interface1”,设计一个公司员工的接口定义,代码如下所示。

    1.     interface Interface1
    2.     {
    3.         string EmployeeNmae;//员工姓名
    4.         void AddEmployee();//添加员工
    5.         void DelEmployee();//删除员工
    6.         string EmployeeAddress;//员工住址
    7.     }

4 保存并编译所有的代码。

2.2.3 继承

继承就是从父类中获取一些公开的成员,如方法和属性。继承的语法如下所示。

    class Student:Person    //继承类
    class Student:Interface1  //继承接口

子类和父类之间以“:”间隔,C#只允许继承一个父类,但允许继承(或者说实现)多个接口。如果子类继承(实现)了接口,则必须实现接口中定义的所有公开成员。

所谓公开的成员,就是在父类中被定义为public的成员,因为public的作用域,可以在子类中生效,而private的作用域则不可。

2.2.4 用C#如何实现继承

本节创建了一个父类,一个子类,并介绍了如何调用子类。演示步骤如下:

1 创建一个类“ParentClass”作为父类,代码如下所示,只定义了一个属性“ParentName”。

    1.     class ParentClass
    2.     {
    3.         private string_name;
    4.         public string ParentName//父类名
    5.         {
    6.            get{return_name;}
    7.            set{_name=value;}
    8.         }
    9.     }

2 再创建一个类“SonClass”作为子类,代码如下所示,要求其继承“ParentClass”类。同时还定义了一个属性“SonName”。

    1.     class SonClass:ParentClass
    2.     {
    3.         private string_name;
    4.         public string SonName//子类名
    5.         {
    6.            get{return_name;}
    7.            set{_name=value;}
    8.         }
    9.     }

3 在窗体中调用子类的代码如下所示。

              SonClass myson=new SonClass();   //创建子类对象
              myson.ParentName="父名";         //自动继承父类的属性
              myson.SonName="子名";          //子类自己的属性

2.2.5 多态

多态是指类可以有多种形态,通过修改可以形成多个类的实现方法。当子类从父类继承时,它会获得父类的所有方法、字段、属性和事件。若要更改父类的数据和行为,通常有两种选择:可以创建新的成员替换父级成员,或者可以重写虚拟的父级成员。

如果要替换父级成员,需要使用new关键字。下面代码演示了GetName方法的2种形态,一种是返回父级名称,一种是返回子级名称。

    1.     class ParentClass  //父类
    2.     {
    3.         public string GetName()
    4.         {
    5.            return"父级名称";
    6.         }
    7.     }
    8.     class SonClass:ParentClass   //子类继承父类
    9.     {
    10.        public new string GetName()
    11.        {
    12.           return"子级名称";
    13.        }
    14.    }

如果要重写虚拟的父级成员,需要两个条件,父级成员使用了关键字“virtual”,而子级成员使用关键字“override”。下面演示这种形式下的GetName方法。

    1.     class ParentClass  //父类
    2.     {
    3.         public virtual string GetName()
    4.         {
    5.            return"父级名称";
    6.         }
    7.     }
    8.     class SonClass:ParentClass  //子类继承父类
    9.     {
    10.        public override string GetName()
    11.        {
    12.           return"子级名称";
    13.        }
    14.    }

2.2.6 用C#如何实现多态

使用多态要注意被调用的究竟是哪一种形态。本例通过两个类和1个方法,演示多态的使用,实现步骤如下所示:

1 创建类“Employee”,表示公司里的员工。代码如下所示,其包含一个虚方法getDepart。

    1.     class Employee  //父类
    2.     {
    3.         public virtual string getDepart()
    4.         {
    5.            return"总公司";
    6.         }
    7.     }

2 创建类“MarketEmployee”,表示市场部员工,代码如下所示,其重写了父类的getDepart方法。

    1.     class MarketEmployee:Employee   //子类继承父类
    2.     {
    3.         public override string getDepart()
    4.         {
    5.            return"市场部";
    6.         }
    7.     }

3 下面代码演示了如何调用这2种形态的方法,注释中还给出了运行结果。

    Employee myee=new Employee();            //创建父类
    string str1=  myee.getDepart();               //结果为“父公司”
    MarketEmployee yee=new MarketEmployee();   //创建子类
    string str2 = yee.getDepart();//结果为“市场部”

2.3 面向对象开发的简单实例

为了让读者彻底地掌握面向对象开发的技术,本节以一个非常简单的案例,介绍如何在日常应用开发中,采用面向对象技术。

2.3.1 面向对象功能设计

本例要实现的功能是在一个公司中有2个部门:采购部和销售部,这2个部门的员工具备相同的属性:员工号、姓名、年龄、住址,但销售部员工还有一个比较特别的属性:销售额。2个部门的员工也具备相同的“操作”:上班和下班。但采购部还有一个操作是采购,销售部还有一个操作是销售。图2.3以图形方式展现了这2个部门的相同点和不同点。

图2.3 2个部门的相似点和不同点

2.3.2 面向对象的类设计

根据这2个部门的共性和特性,又为了以后扩展的需要,设计一个员工类(Employee),此类包含所有员工的共性。因为各个部门又有自己的特性,所以为每个部门单独设计一个类,但这些类必须继承员工类,才能包含那些共性。

图2.4是一个标准的类设计图,其中SaleEmployee表示销售部门员工类,BuyEmployee表示采购部门员工类,这2个类都继承自Employee(员工类)。

图2.4 标准的类设计图

2.3.3 面向对象的应用

【本节示例参考:\示例代码\C02\ OOPSample】

本节将根据类的设计创建一个应用程序,创建的步骤如下:

1 打开VS2008,新建一个项目“OOPSample”。

2 在解决方案资源管理器的根目录下,添加一个类“Employee.cs”,类的设计代码如下所示,主要是设计员工的共性。

    1.     class Employee
    2.     {
    3.         //私有属性的设计
    4.         private int_id;
    5.         private string_name;
    6.         private int_age;
    7.         private string_address;
    8.         public int EmployeeID  //员工号
    9.         {
    10.           get{return_id;}
    11.           set{_id=value;}
    12.        }
    13.        public string Name  //员工号
    14.        {
    15.           get{return_name;}
    16.           set{_name=value;}
    17.        }
    18.        public int Age  //员工号
    19.        {
    20.           get{return_age;}
    21.           set{_age=value;}
    22.        }
    23.        public string Address  //员工号
    24.        {
    25.           get{return_address;}
    26.           set{_address=value;}
    27.        }
    28.        public void WorkOn()
    29.        {
    30.           //上班操作的代码
    31.        }
    32.        public void WorkOff()
    33.        {
    34.           //下班操作的代码
    35.        }
    36.    }

3 在根目录下再添加一个类“SaleEmployee.cs”,此类继承Employee类,代码如下所示,主要是设计销售部员工的特性。

    1.     class SaleEmployee:Employee
    2.     {
    3.         private int_salecount;
    4.         public int SaleCount//销售额
    5.         {
    6.            get{return_salecount;}
    7.            set{_salecount=value;}
    8.         }
    9.         public void Sale()
    10.        {
    11.           //销售操作的代码
    12.        }
    13.    }

4 在根目录下再添加一个类“BuyEmployee.cs”,此类继承Employee类,代码如下所示,主要是设计采购部员工的特性。

    1.     class BuyEmployee:Employee
    2.     {
    3.         public void Buy()
    4.         {
    5.            //采购操作的代码
    6.         }
    7.     }

5 下面的代码演示如何在应用程序中,使用这2个部门的类。

        SaleEmployee mysale = new SaleEmployee();//实例化销售部员工类
        mysale.Name = "销售员1";
        mysale.Sale(); //销售操作
        mysale.WorkOff(); //下班
        label1.Text=mysale.SaleCount.ToString(); //显示此员工的销售额
        BuyEmployee mybuy = new BuyEmployee();//实例化采购部员工类
        mybuy.Name = "采购员1";
        mybuy.WorkOn();//上班
        mybuy.Buy();//采购

承上启下

■ 学完本章后,读者需要回答:

1.什么是类?什么是对象?

2.如何声明类、属性、方法?

3.如何编译类?

4.什么是接口,如何用C#实现一个接口?

5.什么是多态,如何实现类的多态?

6.什么是继承?如何实现类的继承?

7.是否对.NET基础类库框架有了初步的认识?

8.如何设计应用程序中的类,如何应用对象?

■ 在下一章中,读者将会了解:

1.ASPX的几个核心对象。

2.使用Response对象向浏览器输出字符串。

3.使用Request对象接受用户的POST方式和GET方式提交的数据。

4.使用Server对象获取服务器的信息。

5.使用Application对象实现程序级别的数据共享。

6.使用Session对象实现会话级别的数据共享。