《叩开C#之门》系列之对象封装与C#的类

保暖秋衣扎着腰

保暖秋衣扎着腰

2016-02-19 15:09

下面这个《叩开C#之门》系列之对象封装与C#的类教程由图老师小编精心推荐选出,过程简单易学超容易上手,喜欢就要赶紧get起来哦!

  面向对象思想有三个核心要素:封装、继承与多态。如能正确理解这三要素,那么基本上可以算是在编程中建立了面向对象思想。在第二节中我曾介绍,在C#中,所有数据类型的实例都是对象,不过最能体现对象特质的类型,还是类,同时它也是C#中最重要、最频繁使用的类型。接下来,我将通过介绍C#的类,来充分理解对象封装的概念。

  所谓对象,形象地说,我们可以把它理解为一块积木。设计积木的人需要设计积木的外观与形状,还有内部的材质。堆积木的人对于内部的材质并不关心,他们只需要根据不同的外观与形状来决定堆放的位置。因此,对于开发者而言,要设计面向对象的程序,同时会是两个迥然不同的身份:设计者与使用者。

  先谈谈使用者。使用者的身份,就是利用已经提供给你的所有对象,根据需求,设计出自己需要实现的程序。就如堆积木的过程。这恰恰是面向对象编程的优势所在,那就是对象的重用。已经设计好的对象,可以被不同的使用者调用,这些功能既然已经实现,对于使用者而言,当然就免去了自己去设计的过程。正如堆积木那样,既然有了现成设计好的积木,使用者所要做的工作就是把这些积木最后组合起来,堆成不同的形状。.Net Framework所提供的类库,就是这样的积木。

  例如我们想把一个int类型转换成字符型,就没有必要自己去实现这种转换,直接调用.Net Framework提供的功能就可以了:

  

int i = 10;string s = i.ToString();

  再比如我们想弹出一个Windows消息框,同样可以直接使用.Net Framework现有的类库:

  

MessageBox.Show(Message);

  在上述的例子中,i和MessageBox都是一个对象。

  再谈谈设计者的身份。虽然.Net Framework的类库功能已经非常强大,但它不可能考虑到业务的方方面面,如果需要使用一个根本就不存在的对象,此时就需要自己来设计了。例如图书管理系统,可能就需要用户,图书等对象。这就需要开发者自己来设计这些对象。

  既然最能体现对象思想的类型是类,我就来介绍一下C#中的类类型。C#中类的关键字是class。在一个class对象中,主要分为field(字段)、property(属性)和method(方法),前面两个对应的是对象的属性,而method则对应对象的行为。一个典型的class定义如下所示:

  

public class User{ private string m_name; private string m_password; private int m_tryCounter; public string Name {  get {return m_name;}  set {m_name = value;} } public string Password {  get {return m_password;}  set {m_password = value;} } public void SignIn() {  if (m_tryCounter  3)  {   if (IsValid())   {    m_tryCounter = 0;    Console.WriteLine("User {0} was signed in.", m_name);   }   else   {    m_tryCounter++;    Console.WriteLine("User {0} is invalid. Can’t Sign in.", m_name);   }  }  else  {   Console.WriteLine("You try to sign in more than 3 times. You are be denied.");  } } public void SignOut() {  m_tryCounter = 0;  Console.WriteLine("User {0} was signed out.", m_name); } private bool IsValid() {  if (m_name.ToUpper() == "ADMIN" && m_password == "admin")  {   return true;  }  else  {   return false;  } }}

  字符串m_name,m_password,m_tryCounter就是类User的字段,Name,Password是类User的属性,而SignIn、SignOut和IsValid则是类User的方法。

  关于field,property和method,我会在之后的文章中介绍,这里主要介绍的是在这个类中出现的修饰符public、private等相关的知识。

  前面说到对象好比是一个积木,设计者需要定义好这个积木的外观和形状,也要考虑积木内部的制作,例如选用的材质,以及是空心还是实心。如果将这个积木剖开来看,实际上该对象应分为内、外两层。由于使用者只关心外部的实现,因此设计者就需要考虑,哪些实现应暴露在外,哪些实现应隐藏于内。这就体现了对象的封装的思想。

  封装对象,并非是将整个对象完全包裹起来,而是根据具体的需要,设置使用者访问的权限。在C#中,分别用修饰符public,internal,protected,private设定,分别修饰类的字段、属性和方法,甚至于类对象本身:

  public:表明所有对象都可以访问;

(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)

  protected internal:表明同一个程序集内的对象,或者该类对象以及其子类可以访问;

(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)

  internal:表明只有同一个程序集的对象可以访问;

  protected:表明只有该类对象及其子类对象可以访问;(关于继承,会在以后介绍)

  private:表明只有对象本身在对象内部可以访问;

  可以看出,public的开放性最大,其次是protected internal,private的开放性最小。internal和protected居中。那么,internal和protected哪一个开放范围更大呢?我认为,没有完全绝对的结论。它们的范围前者体现一个横向的概念,后者则体现纵向的概念。如果是internal,那么外部程序集对象自然不能访问,但只要是居于同一个程序集中,则所有对象都可以访问它;如果是protected,那么即使是外部程序集对象,只要它继承了该对象,就可以访问,而即使是同一程序集,如果对象不是该类对象的子类,也是无法访问的。打一个比方,在我们的传统文化中,是非常强调宗族观念的,一个宗族的族长,对于本族人而言,权力极大,甚至掌握了生杀大权。以一个州府的范围为例,internal就好比是知府大人,只要是该州府的百姓,都属于他的管辖范围,而不管他是哪一个宗族。protected则好比是宗族的族长,只要是这个宗族的成员,都要服从他,哪怕该成员属于其他州府。我以前看过《雍正王朝》,其中就有这样一个情节,身为皇子的胤祯,竟然无法挽救自己心爱女人的命运,因为这个女人违反了她们宗族的族规,最后眼看着她被活活烧死,却只能黯然神伤,梦里萦回。

  以前面定义的User类而言,所有的字段m_name,m_password,m_tryCounter都是private的,因此User类的外部调用者无法调用它们,但请注意User类内部的方法比如SignIn或者属性Name,却完全可以调用。同样的,private方法IsValid,可以被SignIn方法调用,但对于外部调用者而言,则是无法调用的。而对于public属性Name,Password,public方法SignIn和SignOut,外部的调用者是可以访问的。在后面的演练中,我们能够看出这之间的区别。通过这样分层次的封装,就可以充分保证对象的重用性和安全性。

  那么对于类类型而言,如何确定它们的访问权限呢?这要根据实际的需求来看了。假定这个User类是用于一个电子商务网站。那么电子商务系统在设计过程中,就需要调用到User类对象。显然,登录与退出功能是必须提供给外部使用者的,例如登录页面就会使用到User类。而IsValid()方法用于验证用户的合法性,虽然也非常必要,但该功能仅仅用于登录的时候核实用户身份,也就是说,IsValid方法只会被SignIn方法使用,但外部实用者却并不关心,因此,设置为private就是合理的。同样的道理,字段m_tryCounter也是如此。但如果需求发生改变,验证用户的功能不仅仅是登录的时候需要使用,在添加商品到购物车,下订单,付款的时候,都需要该功能,那么IsValid方法,就有必要修改为public方法了。

  所以,在设计程序的时候,除了要考虑识别对象,还要充分考虑该对象的封装。类对象内的字段、属性和方法,包括类本身,哪些应该暴露在外,哪些应该被隐藏,都需要根据实际的需求,给与正确的设计。

  演练:

  (一)设计类User,并调用该类

  1、打开Visual Studio.Net,选择File菜单的new,选择Project;

  2、选择Visual C# Projects中的Console Application。在Location中,定位你要保存的项目的路径,而名字则为SecondExample。该名字此时既是解决方案的名字,同时也是该项目的名字。

  3、用鼠标右键单击项目名,在弹出的对话框中,将Assembly Name命名为SecondExample,将Default Namespace命名为:BruceZhang.com. SecondExample。

  4、用鼠标右键单击项目名,选择Add菜单项的Add Class:

  5、在弹出的对话框中,将文件的名字命名为User.cs,如图:

  6、点击Open按钮后,项目中就添加了一个新的文件User.cs。打开该文件,将public class User中的内容,修改为前面文中定义好的User类。

  7、修改原有默认的Class1.cs(如果是Visual Studio 2005,则默认为Program.cs)文件名为App.cs,然后将文件内容修改为:

  

class App{/// summary/// The main entry point for the application./// /summary[STAThread]static void Main(string[] args){User user = new User();//用户名和密码均错误;user.Name = "Bruce";user.Password = "test";for (int i=0;i=4;i++){user.SignIn();}user.SignOut();//用户名正确,密码错误;user.Name = "admin";user.Password = "test";for (int i=0;i=4;i++){user.SignIn();}user.SignOut();//用户名和密码正确;user.Name = "admin";user.Password = "admin";for (int i=0;i=4;i++){user.SignIn();}user.SignOut();//注意此时是无法调用这样的字段和方法的;//user.m_name;//user.m_password;//user.IsValid();Console.ReadLine();}}

  8、运行。

展开更多 50%)
分享

猜你喜欢

《叩开C#之门》系列之对象封装与C#的类

编程语言 网络编程
《叩开C#之门》系列之对象封装与C#的类

叩开C#之门系列之C#与面向对象编程语言

编程语言 网络编程
叩开C#之门系列之C#与面向对象编程语言

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

叩开C#之门系列之几个重要名词

编程语言 网络编程
叩开C#之门系列之几个重要名词

叩开C#入门系列之几个重要名词

编程语言 网络编程
叩开C#入门系列之几个重要名词

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

C#简介- 类和对象 选自《C#编程语言详解》 送给新手

电脑网络
C#简介- 类和对象 选自《C#编程语言详解》 送给新手

C#中结构与类的区别

电脑网络
C#中结构与类的区别

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

完整介绍Excel End(xlUp).Row

完整介绍Excel End(xlUp).Row

Mysql入门系列:获得和安装samp_db样例数据库分发包

Mysql入门系列:获得和安装samp_db样例数据库分发包
下拉加载更多内容 ↓