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 : 密封类,表示该类不能作为其他类的基类,不能派生新的类,但可由其他类继承而来

面向对象的主要特点:

封装

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

继承

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

多态性

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

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

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

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

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);
 }
 }
© 版权声明
好牛新坐标
版权声明:
1、IT大王遵守相关法律法规,由于本站资源全部来源于网络程序/投稿,故资源量太大无法一一准确核实资源侵权的真实性;
2、出于传递信息之目的,故IT大王可能会误刊发损害或影响您的合法权益,请您积极与我们联系处理(所有内容不代表本站观点与立场);
3、因时间、精力有限,我们无法一一核实每一条消息的真实性,但我们会在发布之前尽最大努力来核实这些信息;
4、无论出于何种目的要求本站删除内容,您均需要提供根据国家版权局发布的示范格式
《要求删除或断开链接侵权网络内容的通知》:https://itdw.cn/ziliao/sfgs.pdf,
国家知识产权局《要求删除或断开链接侵权网络内容的通知》填写说明: http://www.ncac.gov.cn/chinacopyright/contents/12227/342400.shtml
未按照国家知识产权局格式通知一律不予处理;请按照此通知格式填写发至本站的邮箱 wl6@163.com

相关文章