在本系列中,我们以CodePRoject上比较火的OOP系列博客为主,进行OOP深入浅出展现。
无论作为软件设计的高手、或者菜鸟,对于架构设计而言,均需要多次重构、取舍,以有利于整个软件项目的健康构建,有些经验是前辈总结的,我们拿来使用即可,有些是团队知识沉淀的,总之复用前人好的思想有利于减少返工。当然,在面试的时候,如果能围绕OOP大谈特谈,自然会加分多多的。
开始阅读本系列博客的预备知识,多态、封装、面向对象编程等,请通过MSDN学习。如下图的术语,您应该耳熟能详的。本系列文章使用C#作为唯一编程语言。
深入理解OOP(一):多态和继承(初期绑定和编译时多态)
深入理解OOP(二):多态和继承(继承)
深入理解OOP(三):多态和继承(动态绑定和运行时多态)
深入理解OOP(四):多态和继承(C#中的抽象类)
深入理解OOP(五):C#中的访问修饰符(Public/Private/Protected/Internal/Sealed/Constants/Static and Readonly Fields)
深入理解OOP(六):枚举(实用方法)
深入理解OOP(七):属性(实用方法)
深入理解OOP(八):索引器(实用方法)
深入理解OOP(九):事件(深入理解)
OOP代表的是面向对象编程(Object-Oriented Programming),它基于对象的整体进行编程,取代了基于过程函数的编程思想。具体实现是围绕对象进行数据、函数封装,而不是基于逻辑关系。OOP中的对象直达的是一个特定的类型、或者某类型的实例对象、更多时候是一个class。每个class对象的结构基本相似,但是有各自特有的属性和数据值。对象之间可通过对外的接口进行访问:方法、属性等。基于OOP的这些优势,独立的对象可以修改而不会影响到其他对象,这样会比较方便的升级软件减少潜在的bug。软件系统随着时间的推移,会变得越来越大,OOP编程思想有效的提高了系统代码的可读性和管理性。
下面用5个术语来说明OOP的具体概念是什么:
在本节,我们分别用代码片段来阐述各自类型的多态类型:函数重载、早期绑定、编译器的多态。
先创建一个console 工程,并命名为InheritanceAndPolymorphism,然后添加类Overload.cs,再添加
DisplayOverload
函数。
public class Overload { public void DisplayOverload(int a){ System.Console.WriteLine("DisplayOverload " + a); } public void DisplayOverload(string a){ System.Console.WriteLine("DisplayOverload " + a); } public void DisplayOverload(string a, int b){ System.Console.WriteLine("DisplayOverload " + a + b); } }
在Program.cs添加如下代码
class Program{ static void Main(string[] args) { Overload overload = new Overload(); overload.DisplayOverload(100); overload.DisplayOverload("method overloading"); overload.DisplayOverload("method overloading", 100); Console.ReadKey(); }}
运行程序,结果如下:
DisplayOverload 100
DisplayOverload method overloading
DisplayOverload method overloading100
Overload类中的
DisplayOverload提供了3类不同的重载函数:方法名相同,参数类型和个数不同。C#中的这种方式成为重载,既我们不需要为每类函数定义不同名字的函数,仅需要改变函数参数类型和个数即可实现,这个也成为函数签名。
用不同的返回值可以否? 我们试试下面的代码:
public void DisplayOverload() { }public int DisplayOverload(){ }
肯定的结果是,Visual Studio会给予如下的报错信息:
Error: Type 'InheritanceAndPolymorphism.Overload' already defines a member called 'DisplayOverload' with the same parameter types
从上面的结果可知:返回值不作为多态函数签名。
我们再运行如下的代码:
static void DisplayOverload(int a) { }public void DisplayOverload(int a) { }public void DisplayOverload(string a){ }
结果依然是报错:
Error: Type 'InheritanceAndPolymorphism.Overload' already defines a member called 'DisplayOverload' with the same parameter types
结论:static的可见函数修饰符不作为重载签名。
运行下面的代码,试试out、ref可否作为重载签名。
private void DisplayOverload(int a) { }private void DisplayOverload(out int a) { a = 100; }private void DisplayOverload(ref int a) { }
结果是如下的报错:
Error: Cannot define overloaded method 'DisplayOverload' because it differs from another method only on ref and out
结论:ref、out传递参数修饰符也不能作为重载签名。
一个函数可包含如下4种类型的参数传递:
我们运行如下代码:
public void DisplayOverload(int a, string a) { } public void Display(int a) { string a; }
获得如下报错信息:
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文件中,添加如下代码:
public class Overload { private string name = "Akhil"; public void Display() { Display2(ref name, ref name); System.Console.WriteLine(name); } private void Display2(ref string x, ref string y) { System.Console.WriteLine(name); x = "Akhil 1"; System.Console.WriteLine(name); y = "Akhil 2"; System.Console.WriteLine(name); name = "Akhil 3"; } }
在Program.cs中添加如下代码:
class Program { static void Main(string[] args) { Overload overload = new Overload(); overload.Display(); Console.ReadKey(); } }
运行结果如下:
Akhil
Akhil 1
Akhil 2
Akhil3
结论:我们通过ref引用传递了name的内存地址,故修改x、y的值相当于直接修改name的值,故结果运行如上。
下面这段代码演示了params关键字的作用:
在Overload.cs文件添加如下代码:
public class Overload { public void Display() { DisplayOverload(100, "Akhil", "Mittal", "OOP"); DisplayOverload(200, "Akhil"); DisplayOverload(300); } private void DisplayOverload(int a, params string[] parameterArray) { foreach (string str in parameterArray) Console.WriteLine(str + " " + a); } }
在Program.cs文件添加如下代码:
class Program { static void Main(string[] args) { Overload overload = new Overload(); overload.Display(); Console.ReadKey(); } }
运行结果如下:
Akhil 100
Mittal 100
OOP 100
Akhil 200
C#提供了params动态参数数组机制,非常方便的在运行时动态传递不同数量的同类型参数。
注:params关键词仅能作为函数的最后一个参数适用。
我们再试试params关键字的函数签名和非params关键字函数签名的优先级顺序:
public class Overload { public void Display() { DisplayOverload(200); DisplayOverload(200, 300); DisplayOverload(200, 300, 500, 600); } private void DisplayOverload(int x, int y) { Console.WriteLine("The two integers " + x + " " + y); } private void DisplayOverload(params int[] parameterArray) { Console.WriteLine("parameterArray"); } }
Program.cs文件添加如下代码:
class Program { static void Main(string[] args) { Overload overload = new Overload(); overload.Display(); Console.ReadKey(); } }
运行结果如下:
parameterArray
The two integers 200 300
parameterArray
从运行结果看,C#非常巧妙的进行非params函数的精准匹配优先,如1个int类型/3个int类型,则用params类型匹配;2个int类型,用明确定义的函数进行匹配。
在本节中,我们进行OOP系列的第一篇,主要说明了编译器的多态,它也称为早期绑定或者方法重载。同时,我们也学习C#中威力强大的params关键字,并用它来实现多态。
本文要点归纳如下:
原文地址:http://www.codeproject.com/Articles/771455/Diving-in-OOP-Day-Polymorphism-and-Inheritance-Ear
译文地址:http://www.VEVb.com/powertoolsteam/p/Diving-in-OOP-Day-Polymorphism-and-Inheritance-Ear.html
新闻热点
疑难解答