目录:

【C#小知识】C#中一些易混淆概念总结--------数据类型存储位置,方法调用,out和ref参数的使用

【C#小知识】C#中一些易混淆概念总结(二)--------构造函数,this关键字,部分类,枚举

【C#小知识】C#中一些易混淆概念总结(三)--------结构,GC回收,静态成员,静态类

【C#小知识】C#中一些易混淆概念总结(四)---------解析Console.WriteLine()

----------------------------------------------分割线--------------------------------------------------

这一系列的文章在园子里还是比较受欢迎的。有一些留言指出了其中理论性的错误,还有问自己是否毕业,怎么写出来这些文章的,有没有培训过等等问题。

下面就一并的回答这些问题吧。

1)自己今年六月份毕业,现在在帝都实习。不过在学校已经做过一些C#开发了,现在也是做.NET开发工作。

2)文章中很多知识是自己以前在网上下载的视频教程,学习过程中所记的笔记。也就是在年前的时候,突然有一天发现自己的笔记本记了差不多块一本了,之前也没时间整理过,所以就想着把它们整理成博客文章,顺便温习一下这些笔记知识。

3)有园友问自己是不是在传智培训过。首先说我没有培训过,但是非常感谢传智公开的一些自学教程。因为自己也是这些视频的受益者,学到了很多知识,养成了一些好的学习习惯。

4)在整理笔记的过程中遇到了很多问题,其中自己参考了《C#本质论》,《CLR via C#》还有就是MSDN的官方文档。

3)不管怎样还是会遇到一些自己解决不掉或者弄不清楚的问题,这个过程使用了Google搜索并和请教了一些园友。

4)错误总是会存在。谢谢看我博客的读者你们的细心,指出了我博文中的错误。确定这些错误后,我都立即修改了自己的文章。

---------------------------------------------分割线-----------------------------------------------------

今天开始上班了。这几天研究学习了一下思维导图,感觉用它整理自己的知识非常的方便。所以,以后写博客完成一个知识点,都会用思维导图做一个总结。也能让大家对所要读的内容有一个整体的把握。

我用的思维导图软件是FreeMind(免费的,但是得装JDK),因为刚开始学习使用,很多操作技巧不是很熟练,做出来的导图估计也不是很好,希望大家见谅。

首先,里氏替换原则。

这是理解多态所必须掌握的内容。对于里氏替换原则维基百科给出的定义如下:

为什么子类可以替换父类的位置,而程序的功能不受影响呢?

当满足继承的时候,父类肯定存在非私有成员,子类肯定是得到了父类的这些非私有成员假设,父类的的成员全部是私有的,那么子类没办法从父类继承任何成员,也就不存在继承的概念了)。既然子类继承了父类的这些非私有成员,那么父类对象也就可以在子类对象中调用这些非私有成员。所以,子类对象可以替换父类对象的位置。

来看下面的一段代码:

 class Program
{
static void Main(string[] args)
{
Person p = new Person(); Person p1 = new Student(); Console.ReadKey();
}
} class Person
{
    //父类的私有成员
    private int nAge; public Person()
{
Console.WriteLine("我是Person构造函数,我是一个人!");
} public void Say()
{
Console.WriteLine("我是一个人!");
} } class Student : Person
{
public Student()
{
Console.WriteLine("我是Student构造函数,我是一个学生!");
} public void SayStude()
{
Console.WriteLine("我是一个学生!");
}
} class SeniorStudent : Student
{
public SeniorStudent()
{
Console.WriteLine("我是SeniorStudent构造函数,我是一个高中生!");
}
public void SaySenior()
{
Console.WriteLine("我是一个高中生!");
}
}

我们运行打印出的结果是:

根据前面的构造函数的知识很容易解释这个结果。那么我们在Main()函数中添加如下的代码:

static void Main(string[] args)
{
Person p = new Person();
p.Say();
  
Person p1 = new Student();
p1.Say();
Console.ReadKey();
}

在访问的过程中,可以发现p只可以访问父类的say

而p1也只可以访问父类的Say方法

其实在上面的代码中,就满足了里氏替换原则。子类的Student对象,替换了父类Person对象的位置。

那么它们在内存中发生了些什么呢?如下图:

由上可以知道,当一个父类的变量指向一个子类对象的时候只能通过这个父类变量调用父类成员,子类独有的成员无法调用。

同理我们可以推理出,子类的变量是不可以指向一个父类的对像的

但是当父类变量指向一个子类变量的时候,可以不可以把父类的变量转化成子类的对象呢?看下图

关于引用类型的两种转换方式:

由上面的代码我们已经知道了一种转换,就是在变量钱直接加需要转换的类型,如下代码:

Student s2 = (Student)p1;

那么第二种转换方式就是使用as关键字,如下代码:

 //将指向子类对象的变量转化成子类类型
Student s2 = (Student)p1; //使用as关键字,转换失败返回一个null值
Student s3 = p1 as Student;

使用as关键字和第一种强制转换的区别就是,第一种如果转换失败会抛异常,第二种转换失败则返回一个null值。

思维导图总结如下:

 二,虚方法

使用virtual关键字修饰的方法,叫做虚方法(一般都是在父类中)。

看下面的一段代码:

class Person
{
private int nAge;
public Person()
{
Console.WriteLine("我是Person构造函数,我是一个人!");
} //这里定义了一个虚方法
public virtual void Say()
{
Console.WriteLine("我是一个人!");
} } class Student : Person
{
//子类使用override关键字改写了父类的虚方法
public override void Say()
{
Console.WriteLine("我是一个学生!");
}
public Student()
{
Console.WriteLine("我是Student构造函数,我是一个学生!");
} public void SayStude()
{
Console.WriteLine("我是一个学生!");
}
}

紧接着在main()函数中添加如下的代码:

static void Main(string[] args)
{
Person p = new Person();
p.Say(); Person p1 = new Student();
p1.Say(); Student s = new Student();
s.Say();
Console.ReadKey();
}

打印结果如下:

我们很明显的可以发现,第二个表达式满足里氏替换原则,p1.Say()执行的应该是父类的Say()方法,但是这里却执行了子类的Say()方法。

这就是子类使用override关键字的Say()方法覆盖了父类的用Virtual关键字修饰的Say()方法。

我们使用动态图片看一下调试过程,

①首先是没有使用任何关键字:

由上可以看出直接跳入父类,执行了父类的Say()方法;

②再看使用virtual和override关键字的动态调试图片,如下

可以看到直接到子类去执行override关键字修饰的Say()方法。

那么如果父类使用virtual关键字修饰,而子类没有重写该方法时会怎么样呢?如下面的代码:

class Program
{
static void Main(string[] args)
{ Person p1 = new Student();
p1.Say();
Console.ReadKey();
}
} class Person
{
private int nAge;
public Person()
{
Console.WriteLine("我是Person构造函数,我是一个人!");
} //这里定义了一个虚方法
public virtual void Say()
{
Console.WriteLine("我是一个人!");
} } class Student : Person
{
//子类中没有出现override关键字修饰的方法 public void SayStude()
{
Console.WriteLine("我是一个学生!");
}
}

执行结果如下:

所以,如果子类找不到override方法,则会回溯到该子类的父类去找是否有override方法,知道回溯到自身的虚方法,并执行。

虚方法知识总结的思维导图如下:


毕业实习交流群:221376964。你也可以关注我的新浪微博进行交流。

版权声明:本文为博主原创文章,未经博主允许不得转载。

【C#小知识】C#中一些易混淆概念总结(六)---------解析里氏替换原则,虚方法 分类: C# 2014-02-08 01:53 1826人阅读 评论(0) 收藏的更多相关文章

  1. 【C#小知识】C#中一些易混淆概念总结(二)--------构造函数,this关键字,部分类,枚举 分类: C# 2014-02-03 01:24 1576人阅读 评论(0) 收藏

    目录: [C#小知识]C#中一些易混淆概念总结--------数据类型存储位置,方法调用,out和ref参数的使用 继上篇对一些C#概念问题进行细节的剖析以后,收获颇多.以前,读书的时候,一句话一掠而 ...

  2. iOS中UITextField 使用全面解析 分类: ios技术 2015-04-10 14:37 153人阅读 评论(0) 收藏

    //初始化textfield并设置位置及大小   UITextField *text = [[UITextField alloc]initWithFrame:CGRectMake(20, 20, 13 ...

  3. 解决ORA-29857:表空间中存在域索引和/或次级对象 & ORA-01940:无法删除当前连接的用户问题 分类: oracle sde 2015-07-30 20:13 8人阅读 评论(0) 收藏

    今天ArcGIS的SDE发生了一点小故障,导致系统表丢失,所以需要重建一下SDE数据库,在删除SDE用户和所在的表空间过程中遇到下面两个ORA错误,解决方法如下: 1)删除表空间时报错:ORA-298 ...

  4. VS2010中使用命令行参数 分类: c/c++ 2014-07-11 22:24 634人阅读 评论(0) 收藏

    在Linux下编程习惯了使用命令行参数,故使用VS2010时也尝试了一下. 新建项目,c++编写程序如下: #include<iostream> #include<fstream&g ...

  5. C/C++中const的用法 分类: C/C++ 2015-07-05 00:43 85人阅读 评论(0) 收藏

    const是C语言的关键字,经C++进行扩充,变得功能强大,用法复杂.const用于定义一个常变量(只读变量),当const与指针,引用,函数等结合起来使用时,情况会变得复杂的多.下面将从五个方面总结 ...

  6. 认识C++中的临时对象temporary object 分类: C/C++ 2015-05-11 23:20 137人阅读 评论(0) 收藏

    C++中临时对象又称无名对象.临时对象主要出现在如下场景. 1.建立一个没有命名的非堆(non-heap)对象,也就是无名对象时,会产生临时对象. Integer inte= Integer(5); ...

  7. Java获取项目中的路径 分类: Java Game 2014-08-14 10:17 122人阅读 评论(0) 收藏

    在项目中经常需要获取某个文件的路径: 在这里提供一些获取路径的方法.. 1.此种方式获取的路径,是当前类所在的路径: UserDAOTest.class.getResource("UserD ...

  8. 如何在hadoop中控制map的个数 分类: A1_HADOOP 2015-03-13 20:53 86人阅读 评论(0) 收藏

    hadooop提供了一个设置map个数的参数mapred.map.tasks,我们可以通过这个参数来控制map的个数.但是通过这种方式设置map的个数,并不是每次都有效的.原因是mapred.map. ...

  9. JAVA swing中JPanel如何实现分组框的效果以及设置边框颜色 分类: Java Game 2014-08-16 12:21 198人阅读 评论(0) 收藏

    代码如下: import java.awt.FlowLayout; import java.awt.Frame; import java.awt.GridLayout; import javax.sw ...

随机推荐

  1. NHibernate的搭建

    1.新建项目 Business:业务逻辑类 Data:数据层,存放数据库的操作及Nhibernate辅助类 Domain:数据实体和数据库映射文件 2.使用NuGet下载Nhibernate 数据库配 ...

  2. C++ 中的运算符的优先级

    C++ 中的运算符的优先级 直接看图

  3. 【Win10】开发中的新特性及原有的变更

    声明:本文内容适用于 Visual Studio 2015 RC 及 Windows 10 10069 SDK 环境下,若以后有任何变更,请以新的特性为准. 一.Password 控件的小眼睛属性的变 ...

  4. SoapUI5.1.2安装和破解教程

    一.SoapUI简介 soapui提供一个工具通过soap/http来检查,调用,实现web service和web service的功能/负载/符合性测试. 该工具既可作为一个桌面应用软件使用,也可 ...

  5. 使用Linq对Hashtable和Dictionary<T,T>查询的效率比较

    近期做版本迭代任务,有一个在店铺头部展示店主所在的城市名称和省份名称的需求,店主信息表中保存了店主所在的城市Id和省份Id,由于原有业务复杂,要尽量减少Sql执行时间,所以不考虑join城市地区详细表 ...

  6. [JS] Ajax请求会话过期处理

    对于页面来说,处理session过期比较简单,一般只需在过滤器里面判断session用户是否存在,不存在则跳转页面到登陆页即可. 对于Ajax请求来说,这个办法则无效,只能获取到登录页的html代码. ...

  7. Layui 手册一

    icon-图标 1:√2:×3:问号4:锁5:哭脸6:笑脸7:感叹号 使用layer.msg('',{ icon:1 });  目前只提供7种图标可选,用的适当还是很好看的. 表格刷新 parent. ...

  8. 编程哲学之C#篇:02——学习思维

    <代码大全>的第二章:介绍隐喻(类比)的思维方式, <经济学原理>的第二章:介绍怎么像经济学家一样思考, <计算机的心智操作系统之哲学原理>的第一章:介绍学习操作系 ...

  9. s11 day Linux 和nginx 部署

      https://www.cnblogs.com/pyyu/p/9481344.html ,开机初始化的配置 iptables -F 清空防火墙 /etc/init.d/iptables stop ...

  10. Sbulime Text 2 修改选中字符串的颜色

    Sublime Text 2 > Preferences > Browse Packages... 假设当前试用的 Color Scheme 是 Monokai,则在 Color Sche ...