在本系列中,咱们以CodeProject上比较火的OOP系列博客为主,进行OOP深刻浅出展示。程序员
不管做为软件设计的高手、或者菜鸟,对于架构设计而言,均须要屡次重构、取舍,以有利于整个软件项目的健康构建,有些经验是前辈总结的,咱们拿来使用便可,有些是团队知识沉淀的,总之复用前人好的思想有利于减小返工。固然,在面试的时候,若是能围绕OOP大谈特谈,天然会加分多多的。面试
开始阅读本系列博客的预备知识,多态、封装、面向对象编程等,请经过MSDN学习。以下图的术语,您应该耳熟能详的。本系列文章使用C#做为惟一脚本语言。编程
OOP表明的是面向对象编程(Object-Oriented Programming),它基于对象的总体进行编程,取代了基于过程函数的编程思想。具体实现是围绕对象进行数据、函数封装,而不是基于逻辑关系。OOP中的对象直达的是一个特定的类型、或者某类型的实例对象、更多时候是一个class。每一个class对象的结构基本类似,可是有各自特有的属性和数据值。对象之间可经过对外的接口进行访问:方法、属性等。基于OOP的这些优点,独立的对象能够修改而不会影响到其余对象,这样会比较方便的升级软件减小潜在的bug。软件系统随着时间的推移,会变得愈来愈大,OOP编程思想有效的提升了系统代码的可读性和管理性。数组
下面用5个术语来讲明OOP的具体概念是什么:架构
数据抽象(Data Abstraction):数据抽象是对须要操做的物体进行建模的出发点,既对使用对象进行了抽象,隐藏了内部的细节(对使用的最终用户而言)。用户能够很是方便的使用class的方法、数据,而不用关心数据建立、运行逻辑的背后复杂的过程。咱们以真实世界为例,当你骑一辆自行车的时候,不用考虑变速齿轮的原理如何驱动链条、车轮吧。函数
继承(Inheritance):继承是OOP概念中最流行的一个概念。继承给程序员提供了可复用代码的优点。基类定义好函数逻辑,子类经过继承,可实现直接访问--就想子类自身的方法同样方便。学习
数据封装(Data Encapsulation):对class的成员变量、成员函数经过访问控制符进行包装,则称为数据封装。访问控制符有public、Protected、Private、Internal 4种类型。this
多态(Polymorphism):对象可经过传递不一样参数实现相同的动做,这种行为咱们称之为多态。咱们以真实世界为例,“开车”这个方法,对不一样类型的用户要提供不一样的参数实现多态,如Car.Drive(Man), Car.Drive(Woman)等。spa
消息通讯(Message Communication):消息通讯意味着经过经过消息进行class函数的调用、执行。架构设计
在本节,咱们分别用代码片断来阐述各自类型的多态类型:函数重载、早期绑定、编译器的多态。
先建立一个console 工程,并命名为InheritanceAndPolymorphism,而后添加类Overload.cs,再添加
DisplayOverload
函数。
DisplayOverload( + DisplayOverload( + DisplayOverload( a, + a +
在Program.cs添加以下代码:
Main(= ,
运行程序,结果以下:
DisplayOverload 100
DisplayOverload method overloading
DisplayOverload method overloading100
Overload类中的
DisplayOverload提供了3类不一样的重载函数:方法名相同,参数类型和个数不一样。C#中的这种方式成为重载,既咱们不须要为每类函数定义不一样名字的函数,仅须要改变函数参数类型和个数便可实现,这个也成为函数签名。
用不一样的返回值能够否? 咱们试试下面的代码:
DisplayOverload(){ }
确定的结果是,Visual Studio会给予以下的报错信息:
Error: Type 'InheritanceAndPolymorphism.Overload' already defines a member called 'DisplayOverload' with the same parameter types
从上面的结果可知:返回值不做为多态函数签名。
咱们再运行以下的代码:
DisplayOverload( DisplayOverload( DisplayOverload( a){ }
结果依然是报错:
Error: Type 'InheritanceAndPolymorphism.Overload' already defines a member called 'DisplayOverload' with the same parameter types
结论:static的可见函数修饰符不做为重载签名。
运行下面的代码,试试out、ref能否做为重载签名。
DisplayOverload( DisplayOverload( = DisplayOverload( a) { }
结果是以下的报错:
Error: Cannot define overloaded method 'DisplayOverload' because it differs from another method only on ref and out
结论:ref、out传递参数修饰符也不能做为重载签名。
一个函数可包含以下4种类型的参数传递:
值传递 (pass by value)
引用传递 (Pass by reference)
做为output参数 (As an output parameter)
使用参数数组 (Using parameter arrays)
咱们运行以下代码:
DisplayOverload( a, Display(
不出意外,得到以下报错信息:
Error1: The parameter name 'a' is a duplicate
Error2: A local variable named 'a' cannot be declared in this scope because it would give a different meaning to 'a', which is already used in a 'parent or current' scope to denote something else
在相同的做用域中,参数名称必须是惟一的。
在Overload.cs文件中,添加以下代码:
name = name, Display2( x, = = =
Main(=
Akhil
Akhil 1
Akhil 2
Akhil3
结论:咱们经过ref引用传递了name的内存地址,故修改x、y的值至关于直接修改name的值,故结果运行如上。
下面这段代码演示了params关键字的做用:
在Overload.cs文件添加以下代码:
, , , , DisplayOverload( a, ( str + +
在Program.cs文件添加以下代码:
Main(=
Akhil 100
Mittal 100
OOP 100
Akhil 200
C#提供了params动态参数数组机制,很是方便的在运行时动态传递不一样数量的同类型参数。
注:params关键词仅能做为函数的最后一个参数适用。
咱们再试试params关键字的函数签名和非params关键字函数签名的优先级顺序:
, , , , DisplayOverload( x, + x + + DisplayOverload(
Program.cs文件添加以下代码:
Main(=
运行结果以下:
parameterArray
The two integers 200 300
parameterArray
从运行结果看,C#很是巧妙的进行非params函数的精准匹配优先,如1个int类型\3个int类型,则用params类型匹配;2个int类型,用明肯定义的函数进行匹配。
在本节中,咱们进行OOP系列的第一篇,主要说明了编译器的多态,它也称为早期绑定或者方法重载。同时,咱们也学习C#中威力强大的params关键字,并用它来实现多态。
本文要点概括以下:
C#函数重载的签名规则是用参数的类型和数量判断,而不是函数的名字。
函数返回值不做为重载签名。
修饰符不做为签名的一部分,如static
同函数中,多个参数名称要惟一
ref、out是引用传递,传递的是参数的内存地址
params 做为参数关键词,仅能用于函数的最后一个参数
原文地址:http://www.codeproject.com/Articles/771455/Diving-in-OOP-Day-Polymorphism-and-Inheritance-Ear