面向对象的深入理解三
命名空间,当两个类不在同一个命名空间下的时候,需要我们导入命名空间。导入的快捷键时Shift+alt+F10。这个快捷键用途非常的广泛,包括在实现接口,继承抽象类的时候都是有使用的。(ctrl+.)也行,但是有的时候不管用。
图一、类库与窗体应用程序和winform的区别
问题是现在想在program类中调用类库中的Class1.cs该怎么办呢?
在8.23复习内容下面点击引用-鼠标右键-添加引用,在弹出的对话框中,选中要导入的项目,点击确定。
之后就能导入命名空间了。
图二、导入命名空间
在我们之前的博客:C#中其它一些问题的小节 我们也介绍过导入命名空间,那里面讲的是序列化的时候命名空间的导入。C#中析构函数和命名空间的妙用 中我们介绍的较为基础。现在再看看,是不是我们拓展了一些呢?
变量的作用域问题:
图三、作用域实例一
图四、如何界定变量作用域范围
图五、局部变量
图六、成员变量
bool默认值是false,string默认是null。局部变量没有默认值,所以必须在使用前声明并赋值。
在 C#中的方法(上):中我们提了一下局部变量的问题,还记得两个省长的例子么?
细说封装:
抛开程序的概念,大家想一想生活中的封装是什么?
比如像微软的产品,对于使用者功能都是一样的,但是其内部封装的内容是不一样的。
封装有什么好处:方便
1.属性就是封装,封装的是字段。
属性的封装:封装了变化的东西,对于使用者,只提供统一的访问方式。
2.方法的多个参数封装成了一个对象
3.将一堆代码封装到了一个方法中(猜拳游戏)
4.将一些功能封装到了几个类中(计算器+-*/封装到了一个类
5.将一些具有相同功能的代码封装到了一个程序集中(dll、exe),并且对外提供统一的访问接口。(属性名、方法名等。)
图七、方法的多个参数封装成了一个对象
细说继承
继承跟我们生活中理解的也是一样的。越是子类越具体。子类是用来扩展父类的。
继承是类与类之间的关系。
继承有什么好处呢?
原因之一就是代码重用,原因之二就是多态。
继承的特性:
1.单根性。
2.传递性
图八、继承的单根性
怎么来解决单根性的问题呢?我们后面讲解接口,来解决这个问题。
传递性 例如:体育大学学生继承学生类,学生类又继承了人类
图九、object(基类)
下面我们说说继承中的构造函数问题。
由于构造函数不能被继承,子类当中的构造函数都会默认的继承父类当中的构造函数。
第一种解决办法就是 在父类当中加个无参数的构造函数。
图十、继承中的构造函数问题一
图十一、继承中的构造函数问题二
第二种解决办法就是在子类当中的那个构造函数中用base关键字,调用父类当中的那个有参的构造函数。
现在我们遇到一个问题,我们将子类中构造函数中的调姓名,年龄,还有邮箱的代码注释调。直接在子类当中base关键字后面传入值。
入口函数实例化子类,并附不一样的值给子类。那么,请问在入口函数中的cn.Name中的显示是什么呢?
运行步骤:
入口函数中的实例化川川给了,子类中的name,然后子类调用了父类当中的构造函数,把岩松给了父类中构造函数的name,最后再执行子类中的this.Name=name;,而这几行代码被我注销了。所以,我在入口函数中写的川川没用。最后的显示结果是:岩松。
base把父类当中的构造函数初始化,再初始化下其子类中的户口那个参数。实例化Chinese的川川值压根就没有用到。
如果把子类当中的base改成base(name,age,email)
相当于是子类中的这个构造函数做了一个传递。
这时再运行就是:川川 了。
base关键字作用:
1.调用父类构造函数。
2.调用父类成员*(后面再说)
this关键字的作用:
1.作为当前对象,来调用对象的成员。
2.在调用当前类中的其他构造函数。
下图演示在调用当前类中的其他构造函数
当我们遇到下面的情况时,可以这样使用:
图十二、this的用法一、二
修改启动项方法:
工具---选项---项目和解决方案---生成并运行---对于新解决方案...前打勾
这样就不用老去修改启动项啦。
简写属性的代码段:propfull
练习题当中需要注意的地方:
图十三、继承练习题1(1)
图十四、继承练习题1(2)
图十五、继承练习题1(3)
上面的题目中,总结了一些我们经常会写错得地方。两种方法解决,一个是多练,一个是多理解。
访问修饰符:
1.private 私有的,只能在当前类内部访问。(类中的成员,如果不写访问修饰符,默认的也是私有的。)
2.protected 受保护的,访问修饰符。[范围:1.类内部可以访问。2.所有的子类的内部也可以访问。]
3.internal 表示在当前程序集内部可以访问。 当添加引用的时候,internal的就不能访问了。(怎么样才能访问呢?将internal改成public就行了。)
protected与internal的访问权限谁大?没有什么可比性。
protected可以跨程序集来访问,只要具有父子类关系即可。而internal一旦跨程序集就不能访问了。
4.protected internal ,表示即具有protected访问修饰符的权限,又具有internal的访问修饰符的权限。
5.public 表示公共的,在任何地方都能访问。
类的访问修饰符默认是internal,类中成员的访问修饰符默认是private.
类的访问修饰符只能是public或者internal
上面的关于访问修饰符的文字,可以在写代码的时候,细心的体会。
继承中关于私有成员的问题:
先看下图:
图十六、继承中私有成员问题一
- 得出结论:私有成员不能被子类继承。
- 原因:1.虽然子类继承父类后,在创建子类对象的时候,父类中的那些私有成员,也被分配了内存(子类中也有)。2.但是,继承只是面向对象中的一个概念,目的是为了子类使用(多态、代码重用),私有成员即便继承了,子类中也不能访问,所以在面向对象中,继承了但不能访问,没有意义。
下面看看为什么会存在争议呢?
请看下图所示:
图十七、继承中私有成员存在争议的地方
下面,我们再来看看访问级别约束问题:
图十八、【可访问性不一致错误】的解决办法
图十九、【可访问性不一致错误】的解决办法2
图二十、【可访问性不一致错误】的解决办法3
图二十一、【可访问性不一致错误】的解决办法4
图二十二、里氏替换原则
图二十三、里氏替换赋值问题
图二十四、里氏转换实例一
看看上面的代码,是不是写了很多。目的无非是想调出子类当中的方法。下面我们介绍一种更好的写法:
图二十五、虚方法
图二十六、虚方法实现多态
虚方法总结:
1.在方法的返回值类型前加virtual关键字,这个方法就变成虚方法了。
2.当一个方法是虚方法时,子类才可以重写父类中的这个方法。
3.子类重写父类方法时使用:override关键字。
4.当子类重写了父类中的方法后,通过父类类型变量指向的子类对象。(语言不好表达,代码好表达)
Person p=new Chinese();
p.Say();这时,如果Chinese类中重写了Say方法,则执行结果为子类中重写后的Say()方法,
如果Chinese类并没有重写Say方法,则执行结果还是父类中的Say()
5.虚方法是实现多态的手段之一。
新增内容:
快速重写,写个override+空格+需要重写的方法+回车,就直接写好了。
好了,这篇文章就先写到这儿。
作者近期文章列表:
C#基础教程(完全免费,献给代码爱好者的最好礼物。注:本作者分享自己精心整理的C#基础教程,无任何商业目的。 希望与更多的代码爱好者交流心得,也请高手多多指点!!!) |
|
面向过程,面向对象中高级 | 面向过程,面向对象的深入理解一 |
面向过程,面向对象的深入理解二 | |
winform基础 | Winform基础 |
winform中常用的控件 | |
面向过程 | 三种循环的比较 |
C#中的方法(上) | |
我们常见的数组 | |
面向对象 | 思想的转变 |
C#中超级好用的类 | |
C#中析构函数和命名空间的妙用 | |
C#中超级好用的字符串 | |
C#中如何快速处理字符串 | |
值类型和引用类型及其它 | |
ArrayList和HashTable妙用一 | |
ArrayList和HashTable妙用二 | |
文件管理File类 | |
多态 | |
C#中其它一些问题的小节 | |
GDI+ | 这些年我收集的GDI+代码 |
这些年我收集的GDI+代码2 | |
HTML概述 | 你不能忽视的HTML语言 |
你不能忽视的HTML语言2精编篇 | |
你不能忽视的HTML语言3 |