志在指尖
用双手敲打未来

C#基于对象的程序设计(二)

C#基于对象的程序设计(二)

在这期教学前,请大家先回顾一下上期C#教程:C#基于对象的程序设计(一)

教学目标:面向对象编程是当前计算机界关心的重点,是软件开发方法的主流。本章通过具体实例讲解面向对象的特性——继承、接口和多态性,学生更加容易理解和掌握面向对象的设计方法和编程特点。

教学重点:继承和多态

教学难点:1. 类的继承

  1. 多态
C#基于对象的程序设计(二)

C#基于对象的程序设计(二)

什么是面向对象编程?

     面向对象编程(Object-Oriented Programming,简称OOP,它是通过给程序中加入扩展语句,把函数封装进编程所必需的“对象“中实现的。面向对象的编程语言,使得复杂的工作条例清晰,编写容易。

  • 以事物为中心来思考和认识问题
  • 按照这些事物的本质特性把它们抽象为对象
  • 对同类型的对象抽象其共性,形成类
  • 类通过接口和外界联系

在面向对象程序设计中,包含了对象,类,封装,继承,多态性等概念

面向对象的知识点:

  • 类与对象
    • 在面向对象中,类是封装数据的基本单位
    • 通过类的方法可以访问类中的数据

   类:

  • 相对对象而言,类似于蓝图
  • 包含方法和数据

对象:

  • 是类的实例
  • 使用关键字 new 创建
  • 对象具有行为

 

  • 把具有共同性质的事物划分为一类,得出一个抽象的概念
  • 类即是具有相同属性和服务的一组对象的集合
  • 为属于该类的全部对象提供了抽象的描述,其内部包括属性和行为两个主要部分

 

对象

  • 对象是现实世界中一个实际存在的事物
  • 对象具有自己的静态特征和动态特征
  • 静态特征用某些数据来描述,动态特征用对象的行为或功能来描述
  • 静态特征描述为属性,动态特征描述为行为

 

类的成员:

  • 类中的常量、变量、属性或事件不能与其他类成员同名
  • 类中的方法名不能和其他类成员同名

 

主要包括三种成员:

字段:实例字段,静态字段

访问实例字段,直接用对象名.字段名,访问静态字段,不能用对象的名称,而要用类名,即类名.字段名

属性:get(读取 return),set(编写  value)

方法:方法的定义和调用

方法必须定义在类中,包括方法的名称、返回类型、参数列表、方法体。调用当前类的方法,直接使用方法名称,调用其他类的方法,先要创建类的实例——对象,通过对象名.方法名()来调用。

类的修饰符:

  • new : 新建类的实例
  • public :公有类,表示外界可以不受限制的访问
  • protected :保护类,表示可以访问该类或从该类派生的类
  • private :私有类,表示只有该类可以访问
  • internal :内部类,表示仅能访问本组件(Application或Library)
  • abstract :抽象类,表示该类是一个不完整类,只有声明而没有具体的实现。一般用来做其他类的基类,而不单独使用。也就是说抽象基类不需要实例化
  • sealed : 密封类,表示该类不能作为其他类的基类,不能派生新的类,但可由其他类继承而来

 

面向对象的主要特点:

封装

  • 面向对象方法的一个重要原则
  • 把对象的全部属性和行为组合起来,形成一个独立单位
  • 尽可能的隐蔽对象的内部细节,只保留有限的外部接口与外部联系

继承

  • 特殊类的对象拥有一般类的全部属性和行为,即为特殊类对一般类的继承
  • 继承对于软件复用有着重要意义

多态性

  • 一般类中定义的属性和行为,被特殊类继承之后,可以具有不同数据类型或表现出不同的行为

1. 类的继承

在前面讲过电视的例子,从黑白发展到彩色,又到高清晰,后一代继承了前一代的功能,但是在功能上又有所发展。在面向对象理论中,这就是面向对象的两个重要特征:继承和多态。我们正是通过面向对象的继承性和多态性,开发设计清晰、稳定,易于扩展并且容易维护的软件。

在现有类(称为直接基类)上建立新类(称为派生类)的处理过程即称为继承。在建立新类的过程中,直接基类不作任何改变,派生类继承它的直接基类的成员,而基类的实例构造函数、静态构造函数和析构函数除外。派生类除了继承它的直接基类的成员外,也可以另外定义新成员,以扩展它的直接基类。

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

Class Student:Person;//继承类

Class Student:Interface1;//继承接口

C#只允许继承一个基类,但允许继承多个接口。如果子类继承了接口,则必须实现接口中定义的公开成员。所谓公开成员,就时在基类中被定义为public的成员,因为public的作用域可以在子类中生效,而private的作用域则不可。

C#中如何实现继承:

实例:定义Person(基类)

       下面我们建立一个Person类,它有三个属性,一个方法,三个私有字段,一个无参数的实例构造函数和一个有三个参数的实例构造函数。

using System;

using System.Windows.Forms;

class Person

{

    private string id;

    private string name;

    private string sex;

    public Person()

    {}

    public Person(string myid,string myname,string mysex)

    {

       ID=myid;

       Name=name;

       Sex=mysex;

    }

    public string Name

    {

       get{return name;}

       set{name=value;}

    }

    public string Sex

    {

       get{return sex;}

       set{sex=value;}

    }

    public string ID

    {

       get{return id;}

       set{id=value;}

    }

    public string PrintPerson()

    {

       return string.Format("{0}  {1}  {2}", ID, Name, Sex);

    }

}

实例:定义Student(1)

       定义一个学生类Student类,由于学生属于人,因此学生具有人的属性。前面我们已经定义了一个Person类,要定义学生类,只需以Person类为直接基类定义一派生类。实现人的属性的代码务须重写,直接继承,这样就可大大节约程序的开发时间。缩短程序的开发周期。

using System;

using System.Windows.Forms;

class Student : Person      //指定派生类与直接基类

{

    private string stuid;

    private string department;

    public string Stuid

    {

        get { return stuid; }

        set { stuid = value; }

    }

    public string Department

    {

        get { return department; }

        set { department = value; }

    }

    public string Printstudent()

    {

        return string.Format("{0} {1}", Stuid, Department);

    }



    public static void Main()

    {

        string output = "";

        //创建新的Student对象

        Student student1;

        student1 = new Student();

        Student student2 = new Student();

        //打印出与此人关联的姓名和年龄

        output=student1.PrintPerson()+"\t";

        output += student1.Printstudent() + "\n";

        //在student1对象上设置一些值

        student1.ID = "12569850";

        student1.Name = "王飞";

        student1.Sex = "男";

        student1.Stuid = "0987655";

        student1.Department = "计算机";

        output = student1.PrintPerson() + "\t";

        output += student1.Printstudent() + "\n";



        student2.Name = "张翔";

        student2.Sex = "女";

        student2.ID = "17683608";

        student2.Stuid = "1004501";

        student2.Department = "应用外语";



        output += student2.PrintPerson() + "\t";

        output += student2.Printstudent() + "\n";



        MessageBox.Show(output, "运行结果");

   }

}

所有类的基类:object

在.NET Framework中,System.Object是一个特殊的类,它是.NET Framework中所有类的鼻祖。也就是整个类型层次结构的根。每个类不管是.NET Framework提供的,还是自行编写的,都是从System.Object类继承而来的。包括前面的Person类,虽然没有为它指定一个基类,但是编译器会自动把它作为object的派生类。

2. 接口

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

interface Iconnection

{

 Public string DatabaseName;

 Public string AddDataBase();

 Public string GetDataBaseConn();

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

C#如何创建接口

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

  • 打开应用程序,在解决方案资源管理器中,右击根目录,在弹出的快捷菜单中,依次选择“添加|新建项”菜单命令,打开项模板对话框。
  • 选中“接口”模板,默认名称为“cs”,单击“添加”按钮,此时在根目录下生成一个“Interface1.cs”类文件,默认代码如下所示:
using System;

using System.Collections.Generic;

using System.Text;

namespace Interface_eg

{

    interface Interface1

    {

    }

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

    {

        public string EmployeeName;//员工姓名

        public void AddEmployee();//添加员工

        public void DelEmployee();//删除员工

        public string EmployeeAddress();//员工住址

    }
  • 按“Ctrl+S”键保存代码
补充:创建和使用接口
  • 创建一项目InerfaceApp
  • 声明接口IThing
namespace InerfaceApp

{

   public  interface IThing

    {

        string Type { get; }

        string TellAboutSelf();

    }

}

(3) 实现接口。

using System;

using System.Windows.Forms;

public class Temperatrue : IThing

{

    protected float m_Value;

    public Temperatrue() { }

    public Temperatrue(float f)

    {

        m_Value = f;

    }

    public float Value

    {

        get { return m_Value; }

        set { m_Value = value; }

    }

    public float Celsius

    {

        get { return (m_Value - 32) * 5 / 9;}

        set { m_Value = value * 9.0f / 5 + 32; }

    }

    public string Type

    {

        get { return "温度"; }

    }

    public String TellAboutSelf()

    {

        return "华氏温度" + string.Format("{0:n1}", Value) + "摄氏温度" + string.Format("{0:n1}", Celsius);

    }

}



public class Manager : IThing

{

    private string name;

    private decimal salary;

    private DateTime bornDay;

    public Manager() { }

    public Manager(string name, decimal salary, int year, int month, int day)

    {

        this.name = name;

        this.salary = salary;

        bornDay = new DateTime(year, month, day);

    }

    public string Name

    {

        get { return name; }

        set { name = value; }

    }

    public decimal Salary

    {

        get { return salary ; }

        set { salary= value; }

    }

    public DateTime BornDay

    {

        get { return bornDay; }

        set { bornDay = value; }

    }

    public string Type

    {

        get { return "经理"; }

    }

    public string TellAboutSelf()

    {

        return "姓名:" + Name + "出生日期:" + BornDay.ToShortDateString() + "基本工资:" + String.Format("{0:c}", salary);

    }

}
  • 添加测试类
namespace InerfaceApp

{

    class InterfaceTest

    {

        static string Showinfo(IThing[] b)

        {

            String output = "";

            for (int i = 0; i < b.Length; i++)

            {

                output +="\n"+b [i].Type +":"+b[i].TellAboutSelf ()+"\n";

            }

            return output ;

        }

        public static void Main(string[] args)

        {

            IThing[] thinges = new IThing[4];

            Manager obj1 = new Manager("王菲", 8000.6M, 1970, 6, 15);

            Manager obj2 = new Manager("李丽", 10000, 1972, 2, 27);

            Temperatrue obj3 = new Temperatrue(32);

            Temperatrue obj4 = new Temperatrue(0);

            thinges[0] = obj1;

            thinges[1] = obj2; 

            thinges[2] = obj3;

            thinges[3] = obj4;

            string output = Showinfo(thinges);

            MessageBox.Show(output, "输出结果");

        }

    }

}

3. 多态

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

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

class ParentClass//父类

{

 public string GetName()

{ return "父级名称"; }

}

class SonClass:ParentClass//子类

{

 public string GetName()

    { return "子级名称"; }

}

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

class ParentClass//父类

{

 public virtual  string GetName()

{ return "父级名称"; }

}

class SonClass:ParentClass//子类

{

 public override string GetName()

    { return "子级名称"; }

}

C#如何实现多态(P70)

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

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

Class Employee

{

 Public virtual string getDepart ()

{ return “总公司”;}

}

(2)创建类“MarketEmployee“,表示市场部员工。它重写了父类的getDepart方法。代码如下:

Class MarketEmployee:Employee

{

 Public override string getDepart ()

{return “市场部”;}

}

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

Employee myee=new Employee();//创建父类

String str1=myee.getDepart();//结果为“总公司“

MarketEmployee yee=new MarketEmployee();//创建子类

String str2=yee.getDepart();//结果为“市场部“。

4. 面向对象开发的简单实例

本节以一个非常简单的案例,介绍如何在日常应用开发中采用面向对象技术。

实现步骤:

  • 新建一个项目“OOPSample
  • 在解决方案资源管理器的根目录下,添加类“cs”,设计员工的共性。
class Employee

    {

        //私有属性的设计

        private int _id;

        private string _name;

        private int _age;

        private string _address;

        public int EmployeeID  //员工号

        {

            get { return _id; }

            set { _id = value; }

        }

        public string Name  //员工姓名

        {

            get { return _name; }

            set { _name = value; }

        }

        public int Age  //员工年龄

        {

            get { return _age; }

            set { _age = value; }

        }

        public string Address  //员工地址

        {

            get { return _address; }

            set { _address = value; }

        }

        public void WorkOn()

        {

            //上班操作的代码

        }

        public void WorkOff()

        {

            //下班操作的代码

        }

}

(3)在根目录下添加一个类“SaleEmployee.cs”,设计销售部员工的特性。

class SaleEmployee:Employee

    {

        private int _salecount;

        public int SaleCount //销售额

        {

            get { return _salecount; }

            set { _salecount = value; }

        }

        public void Sale()

        {

            //销售操作的代码

        }

    }

(4)在根目录下添加一个类“BuyEmployee.cs”,设计采购部员工的特性。



class BuyEmployee:Employee

    {

        public void Buy()

        {

            //采购操作的代码

        }

    }

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

SaleEmployee mysale = new SaleEmployee();//实例化销售部员工类

    mysale.Name = "销售员";

    mysale.Sale(); //销售操作

    mysale.WorkOff(); //下班

    label1.Text=mysale.SaleCount.ToString(); //显示此员工的销售额



    BuyEmployee mybuy = new BuyEmployee();//实例化采购部员工类

    mybuy.Name = "采购员";

    mybuy.WorkOn();//上班

    mybuy.Buy();//采购

上机实训。

class Boat

    {

        private string registrationNo;

        float length;

        string manufacturer;

        int year;

 

        public string RegistrationNo

        {

            get { return registrationNo; }

            set { registrationNo = value; }

        }

        public float Length

        {

            get { return length; }

            set { length = value; }

        }

        public string Manufacturer

        {

            get { return manufacturer ; }

            set {manufacturer = value; }

        }

        public int Year

        {

            get { return year; }

            set { year = value; }

        }

        public Boat() { }

        public virtual string ToallString()

        {

            return string.Format("{0} {1} {2} {3}", RegistrationNo, Length, Manufacturer, Year);

        }

    }

 

    class Sailboat : Boat

    {

        int  keeldepth;

        string id;

        string type;

        public int KeelDepth

        {

            get { return keeldepth ; }

            set { keeldepth  = value; }

        }

        public string ID

        {

            get { return id; }

            set {id = value; }

        }

        public string Type

        {

            get { return type ; }

            set { type = value; }

        }

        public Sailboat() { }

        public override  string ToallString()

        {

            return string.Format("{0} {1} {2} ", KeelDepth ,ID,Type );

        }

    }

    class Powerboat : Boat

    {

        int numberEngins;

        string fuletype;

        public int NumberEngins

        {

            get { return numberEngins ; }

            set { numberEngins  = value; }

        }

        public string FuleType

        {

            get { return fuletype; }

            set { fuletype = value; }

        }

        public Powerboat() { }

        public override  string ToallString()

        {

            return string.Format("{0} {1} ",  NumberEngins ,FuleType );

        }

    }

    class Program

    {

        static void Main(string[] args)

        {

            string output = "";

            Sailboat sboat = new Sailboat();

            sboat.KeelDepth = 10;

            sboat.ID = "123";

            sboat.Type = "inboard";

            output=sboat.ToallString();

            MessageBox.Show(output);

        }

    }
未经允许不得转载:IT技术网站 » C#基于对象的程序设计(二)
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!

 

志在指尖 用双手敲打未来

登录/注册IT技术大全

热门IT技术

C#基础入门   SQL server数据库   系统SEO学习教程   WordPress小技巧   WordPress插件   脚本与源码下载