深入理解OOP(第一天):多态和继承(初期绑定和编译时多态)
在本系列中,我们以CodeProject上比较火的OOP系列博客为主,进行OOP深入浅出展现。
无论作为软件设计的高手、或者菜鸟,对于架构设计而言,均需要多次重构、取舍,以有利于整个软件项目的健康构建,有些经验是前辈总结的,我们拿来使用即可,有些是团队知识沉淀的,总之复用前人好的思想有利于减少返工。当然,在面试的时候,如果能围绕OOP大谈特谈,自然会加分多多的。
开始阅读本系列博客的预备知识,多态、封装、面向对象编程等,请通过MSDN学习。如下图的术语,您应该耳熟能详的。本系列文章使用C#作为唯一编程语言。
深入理解OOP(四):多态和继承(C#中的抽象类)
深入理解OOP(五):C#中的访问修饰符(Public/Private/Protected/Internal/Sealed/Constants/Static and Readonly Fields)
深入理解OOP(六):枚举(实用方法)
深入理解OOP(七):属性(实用方法)
深入理解OOP(八):索引器(实用方法)
深入理解OOP(九):事件(深入理解)
OOP
是什么OOP,以及OOP的优势是什么?
OOP代表的是面向对象编程(Object-Oriented Programming),它基于对象的整体进行编程,取代了基于过程函数的编程思想。具体实现是围绕对象进行数据、函数封装,而不是基于逻辑关系。OOP中的对象直达的是一个特定的类型、或者某类型的实例对象、更多时候是一个class。每个class对象的结构基本相似,但是有各自特有的属性和数据值。对象之间可通过对外的接口进行访问:方法、属性等。基于OOP的这些优势,独立的对象可以修改而不会影响到其他对象,这样会比较方便的升级软件减少潜在的bug。软件系统随着时间的推移,会变得越来越大,OOP编程思想有效的提高了系统代码的可读性和管理性。
OOP的概念是什么?
下面用5个术语来说明OOP的具体概念是什么:
- 数据抽象(Data Abstraction):数据抽象是对需要操作的物体进行建模的出发点,既对使用对象进行了抽象,隐藏了内部的细节(对使用的最终用户而言)。用户可以非常方便的使用class的方法、数据,而不用关心数据创建、运行逻辑的背后复杂的过程。我们以真实世界为例,当你骑一辆自行车的时候,不用考虑变速齿轮的原理如何驱动链条、车轮吧。
- 继承(Inheritance):继承是OOP概念中最流行的一个概念。继承给程序员提供了可复用代码的优势。基类定义好函数逻辑,子类通过继承,可实现直接访问--就想子类自身的方法一样方便。
- 数据封装(Data Encapsulation):对class的成员变量、成员函数通过访问控制符进行包装,则称为数据封装。访问控制符有public、Protected、Private、Internal 4种类型。
- 多态(Polymorphism):对象可通过传递不同参数实现相同的动作,这种行为我们称之为多态。我们以真实世界为例,“开车”这个方法,对不同类型的用户要提供不同的参数实现多态,如Car.Drive(Man), Car.Drive(Woman)等。
- 消息通信(Message Communication):消息通信意味着通过通过消息进行class函数的调用、执行。
多态(Polymorphism)
在本节,我们分别用代码片段来阐述各自类型的多态类型:函数重载、早期绑定、编译器的多态。
先创建一个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();
overload.DisplayOverload("method overloading");
overload.DisplayOverload("method overloading", );
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 = ;
} 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传递参数修饰符也不能作为重载签名。
多态中Params 参数的作用
一个函数可包含如下4种类型的参数传递:
- 值传递 (pass by value)
- 引用传递 (Pass by reference)
- 作为output参数 (As an output parameter)
- 使用参数数组 (Using parameter arrays)
我们运行如下代码:
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(, "Akhil", "Mittal", "OOP");
DisplayOverload(, "Akhil");
DisplayOverload();
} 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();
DisplayOverload(, );
DisplayOverload(, , , );
} 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关键字,并用它来实现多态。
本文要点归纳如下:
- C#函数重载的签名规则是用参数的类型和数量判断,而不是函数的名字。
- 函数返回值不作为重载签名。
- 修饰符不作为签名的一部分,如static
- 同函数中,多个参数名称要唯一
- ref、out是引用传递,传递的是参数的内存地址
- params 作为参数关键词,仅能用于函数的最后一个参数
原文地址:http://www.codeproject.com/Articles/771455/Diving-in-OOP-Day-Polymorphism-and-Inheritance-Ear
译文地址:http://www.cnblogs.com/powertoolsteam/p/Diving-in-OOP-Day-Polymorphism-and-Inheritance-Ear.html
深入理解OOP(第一天):多态和继承(初期绑定和编译时多态)的更多相关文章
- c#中运行时编译时 多态
c#中运行时编译时 多态 public class aa { } public class bb:aa { } public class cc { public static void Main( ...
- Java编译时多态和运行时多态
来源:https://blog.csdn.net/wendizhou/article/details/73733061 编译时多态:主要是方法的重载,通过参数列表的不同来区分不同的方法. 运行时多态: ...
- 深入浅出OOP(一): 多态和继承(早期绑定/编译时多态)
在本系列中,我们以CodeProject上比较火的OOP系列博客为主,进行OOP深入浅出展现. 无论作为软件设计的高手.或者菜鸟,对于架构设计而言,均需要多次重构.取舍,以有利于整个软件项目的健康构建 ...
- 深入理解OOP(三):多态和继承(动态绑定和运行时多态)
在前面的文章中,我们介绍了编译期多态.params关键字.实例化.base关键字等.本节我们来关注另外一种多态:运行时多态, 运行时多态也叫迟绑定. 深入理解OOP(一):多态和继承(初期绑定和编译时 ...
- 深入理解OOP(四): 多态和继承(抽象类)
在本文中,我们讨论OOP中的热点之一:抽象类.抽象类在各个编程语言中概念是一致的,但是C#稍微有些不一样.本文中我们会通过代码来实现抽象类,并一一进行解析. 深入理解OOP(一):多态和继承(初期绑定 ...
- 深入理解OOP(二):多态和继承(继承)
本文是深入浅出OOP第二篇,主要说说继承的话题. 深入理解OOP(一):多态和继承(初期绑定和编译时多态) 深入理解OOP(二):多态和继承(继承) 深入理解OOP(三):多态和继承(动态绑定和运行时 ...
- C#面向对象(OOP)入门—第一天—多态和继承(方法重载)
面向对象是什么 面向对象是一种基于对象的编程方法,它取代了仅仅依靠方法和流程的编程方式.面向对象的编程语言中,对象(object)其实就是指特定类型.或某个类的实例.面向对象使得编程人员更容易组织和管 ...
- 深入浅出OOP(三): 多态和继承(动态绑定/运行时多态)
在前面的文章中,我们介绍了编译期多态.params关键字.实例化.base关键字等.本节我们来关注另外一种多态:运行时多态, 运行时多态也叫迟绑定. 运行时多态或迟绑定.动态绑定 在C#语音中,运行时 ...
- 深入理解Java面向对象三大特性 封装 继承 多态
1.封装 封装的定义: 首先是抽象,把事物抽象成一个类,其次才是封装,将事物拥有的属性和动作隐藏起来,只保留特定的方法与外界联系 为什么需要封装: 封装符合面向对象设计原则的第一条:单一性原则,一个类 ...
随机推荐
- 0003 64位Oracle11gR2不能运行SQL Developer的解决方法
"应用程序开发"下的"SQL Developer"双击不可用,出现“Windows正在查找SQLDEVELOPER.BAT"的提示,如下图: 搜索博客 ...
- Ambari工具之认识学习01
随着大数据的越发流行,大大小小的互联网公司都开始参与一些大数据相关的业务,都想从中分一杯羹.Hadoop是大数据的典型代表,也可以说现在的领头大哥,很多互联网巨头都在使用hadoop,包括BAT等大公 ...
- C# .NET 动态调用webservice的三种方式
转载自 百度文库 http://wenku.baidu.com/link?url=Q2q50wohf5W6UX44zqotXFEe_XOMaib4UtI3BigaNwipOHKNETloMF4ax4W ...
- 学习shell中遇到的一些基础问题总结
今天入门Shell脚本编程:今天的目标是完成冒泡排序,遇到了很多问题,总结了一下: 我从c转到shell遇到了这样的一些情况: 1:首先这几个符号非常重要 $变量:把变量的值拿出来使用(所以赋值语句应 ...
- POJ 3449 Geometric Shapes --计算几何,线段相交
题意: 给一些多边形或线段,输出与每一个多边形或线段的有哪一些多边形或线段. 解法: 想法不难,直接暴力将所有的图形处理成线段,然后暴力枚举,相交就加入其vector就行了.主要是代码有点麻烦,一步一 ...
- 三维网格形变算法(Gradient-Based Deformation)
将三角网格上的顶点坐标(x,y,z)看作3个独立的标量场,那么网格上每个三角片都存在3个独立的梯度场.该梯度场是网格的微分属性,相当于网格的特征,在形变过程中随控制点集的移动而变化.那么当用户拖拽网格 ...
- NOIP2012pj文化之旅[floyd]
描述 有一位使者要游历各国,他每到一个国家,都能学到一种文化,但他不愿意学习任何一种文化超过一次,即如果他学习了某种文化,则他就不能到达其他有这种文化的国家.不同的国家可能有相同的文化.不同文化的国家 ...
- POJ1065Wooden Sticks[DP LIS]
Wooden Sticks Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 21902 Accepted: 9353 De ...
- Sphinx和coreseek检索引擎
Sphinx是检索英文用,coreseek是检索中文用. Sphinx(斯芬克斯)是一个基于SQL的全文检索引擎,可以结合MySQL,PostgreSQL做全文搜索,它可以提供比数据库本身更专业的搜索 ...
- 在Ubuntu14.04下安装vsftp服务器
猜想在Ubuntu下搭建ftp服务器来实现windows和ubuntu下文件互传是一件很简单的事儿,但是在网上找了好几篇文章都不行,故自己在这里总结一下方法. 首先安装vsftp服务器 sudo ap ...