C#面向对象的一些东西
最近在复习C#面向对象,也就是说常说的3大特性:封装、继承和多态。首先说一下封装,其实封装最大的目的也是为了实现代码的解耦和重用、代码也是安全的(对外它隐藏了具体的实现,就好比我们拿个遥控器就能操作电视机,而无须知道其内部实现);C#中很多地方都用到了封装,可以将一个具体的功能代码封装成一个方法,供外界调用就是一个封装。
再说一下继承吧。首先要搞明白的是,继承是类与类之间的关系,那么必然有一个父类,一个子类(可以理解为父亲和儿子的关系),父类是相对子类更抽象的类,而子类是相对父类更具体的类(可以理解为父类能做的事儿,子类继承后都可以做,这里有一个特例,父类如果将一个方法或字段设为Sealed,私有的,子类是继承不到的;而子类能做的事儿,父类不一定能做,即在子类中新增的方法),C#有2种继承,体现为父类中有虚方法(virtual)、父类是抽象类(abstract),这2种都可以供子类继承,根据2种实现时语法上的不同,他们的区别是:
1.如果一个需求是很模糊,很广泛的,这是考虑抽象类,而不是虚方法。
2.如果一个父类要求有代码实现,那么就必须用虚方法,因为抽象方法是不允许有代码实现的;
3.如果强制要求一个子类必须实现父类中的方法,那么父类必须用抽象类,如果没有这样的要求,那么父类可以用虚方法;
4.抽象类不能被实例化(但可以有构造函数),可以有实例成员也可以有抽象成员。
需要说明的是,假如父类是抽象类,而如果子类也不想实现父类的方法,只要子类也是抽象类即可,这样以来,实现的代码就交给子类的下一代(个)子类来实现。
判断继承关系:
子类 is (a) 父类;
转换,子类 as 父类。(这个方法转换成功,返回父类对象;转换失败,返回null)
继承的好处:
1.代码重用;
2.继承就是为了实现多态而准备的,多态就是一个类的多种状态(说的很模糊);这里提到一个概念,叫“里氏替换原则”,父类变量指向子类对象。多态的目的是,为了程序的可扩展性(开放封闭原则,对修改封闭,对扩展开放);下面用一个具体实例说明问题:
需求是,要实现一个计算器,要求不论多复杂的算法,调用者只需要掉“计算”这个方法就能得到自己想要的结果,而且计算方法还会不断地扩展。这个时候考虑虚方法是不行的,因为虚方法有代码实现,所以采用抽象类是最合适不过的。抽象类的代码如下:
public abstract class Calculator
{
public int Number1
{
get;
set;
}
public int Number2
{
get;
set;
}
//2个构造函数
public Calculator()
{
}
public Calculator(int n1,int n2)
{
this.Number1 = n1;
this.Number2 = n2;
}
public abstract int Jisuan();
}
再定义一个类库,里面的类来实现上面这个类即可(如果上面的类在另外一个类库中,注意引用)。举例:加法
public class AddFa : Calculator
{
public AddFa(int n1,int n2):base(n1,n2)
{
}
public override int Jisuan()
{
return Number1 + Number2;
}
}
这个时候,用一个控制台来测试上面的加法类:
static void Main(string[] args)
{
Console.WriteLine("请输入第一个数:");
int number1 = int.Parse(Console.ReadLine());
Console.WriteLine("请输入操作符:");
string op = Console.ReadLine();
Console.WriteLine("请输入第二个数:");
int number2 = int.Parse(Console.ReadLine());
Calculator cal = MCop(op, number1, number2);
int? iResult = cal.Jisuan(); //这里调用的是子类的计算方法
if (iResult!=null)
{
Console.WriteLine("计算结果是:{0}",iResult.ToString());
}
Console.ReadKey();
}
/// <summary>
/// 简单工厂设计模式(返回值是一个子类,“产品类”;Calculator是父类,“工厂类”,父类变量指向子类对象)
/// </summary>
/// <param name="op"></param>
/// <param name="number1"></param>
/// <param name="number2"></param>
/// <returns></returns>
static Calculator MCop(string op, int number1, int number2)
{
Calculator cal1 = null;
switch (op)
{
case "+": cal1 = new AddFa(number1, number2); break;
case "-": cal1 = new JianFa(number1, number2); break;
}
return cal1;
}
注意,当下面的方法MCop执行完毕后,返回的是产品类,再在主函数中调Jisuan(),就得到想要的结果(“产品”),这就是“简单工厂设计模式”。
============================================================================================
Static关键字: 静态成员(静态字段、静态方法)
1.类中静态成员不能通过类的实例对象名来访问,只能通过类名来访问。
2.在静态函数中不能使用this,因为this代表类的对象;
3.静态成员在整个程序中是共享的,一个地方改变了,其他用到它的地方都会发生改变;而且静态成员占用的内存资源直到程序退出才释放;而实例成员超出其作用域就会释放掉,一个实例成员发生变化,不影响其他实例。
4.静态类中只能包含静态成员,而普通类(不含Static),既可以包含静态成员,也可以包含实例成员。
5.静态类不能被继承,因为他是抽象的(abstract,不能实例化)也是密封的(Sealed,不能被继承).
6.静态类有静态构造函数,其必须加Static关键字;静态构造函数是由系统来调用,而不是程序员来调用的。
7.静态类中的静态成员不能有访问修饰符,也不能有参数(不知道谁传参数进去),默认是Private(私有的).
8.静态类只能继承自Object类,不能实现任何接口(接口中的成员都是实例成员)。
静态类使用不多,那么它的应用场景有:
一般工具类(SQLHelper)、工具方法写成静态的,共有的、不变的属性也写成静态的;其余的属性考虑到内存占用情况,写成普通的(实例的)。
============================================================================================
new关键字的用法:
1.实例化,创建对象;
2.如果在继承中,将子类的同名方法加一个new关键字,则表示隐藏父类继承过来的方法(因为没有通过override重写父类中的方法,故通过父类类型变量调用相同方法时访问的是父类自己的方法,而用子类类型变量调用则访问的是子类中的方法),简单点说,就是父类中的方法和子类中的方法不再有任何关系,跟继承不一样。
C#面向对象的一些东西的更多相关文章
- 巨蟒python全栈开发-第16天 核能来袭-初识面向对象
一.今日内容总览(上帝视角,大象自己进冰箱,控制时机) #转换思想(从面向过程到面向对象) 1.初识面向对象 面向过程: 一切以事物的发展流程为中心. 面向对象: 一切以对象为中心,一切皆为对象,具体 ...
- JS面向对象系列教程 — 对象的基本操作
面向对象概述  面向对象(Object Oriented)简称OO,它是一种编程思维,用于指导我们如何应对各种复杂的开发场景. 这里说的对象(Object),意思就是事物,在面向对象的思维中,它将一 ...
- C#基础-面向对象详解
面向对象详解 一.什么是面向对象 1>面向对象是一种程序设计思想 2>面向过程和面向对象是什么? 例如要把大象放冰箱怎么做? 面向过程:打开冰箱门->把大象扔进去->关上冰箱门 ...
- 1. web前端开发分享-css,js入门篇
关注前端这么多年,没有大的成就,就入门期间积累了不少技巧与心得,跟大家分享一下,不一定都适合每个人,毕竟人与人的教育背景与成长环境心理活动都有差别,但就别人的心得再结合自己的特点,然后探索适合自己的学 ...
- WPF基础知识、界面布局及控件Binding(转)
WPF是和WinForm对应的,而其核心是数据驱动事件,在开发中显示的是UI界面和逻辑关系相分离的一种开放语言.UI界面是在XAML语言环境下开发人员可以进行一些自主设计的前台界面,逻辑关系还是基于c ...
- C#面向接口编程详解(1)——思想基础
我想,对于各位使用面向对象编程语言的程序员来说,“接口”这个名词一定不陌生,但是不知各位有没有这样的疑惑:接口有什么用途?它和抽象类有什么区别?能不能用抽象类代替接口呢?而且,作为程序员,一定经常听到 ...
- MSMQ消息队列 用法
引言 接下来的三篇文章是讨论有关企业分布式开发的文章,这三篇文章筹划了很长时间,文章的技术并不算新,但是文章中使用到的技术都是经过笔者研究实践后总结的,正所谓站在巨人的肩膀上,笔者并不是巨人,但也希望 ...
- WPF基础知识、界面布局及控件Binding
WPF是和WinForm对应的,而其核心是数据驱动事件,在开发中显示的是UI界面和逻辑关系相分离的一种开放语言.UI界面是在XAML语言环境下开发人员可以进行一些自主设计的前台界面,逻辑关系还是基于c ...
- java 接口(基础思想一)
我想,对于各位使用面向对象编程语言的程序员来说,“接口”这个名词一定不陌生,但是不知各位有没有这样的疑惑:接口有什么用途?它和抽象类有什么区别?能不能用抽象类代替接口呢?而且,作为程序员,一定经常听到 ...
随机推荐
- 字符串逆转(递归和非递归java)
package 乒乒乓乓; public class 递归逆转字符串 { //非递归逆转 public static String reverse(String s) { ...
- normalization归一化
简单的举个例子:一张表有两个变量,一个是体重kg,一个是身高cm.假设一般情况下体重这个变量均值为60(kg),身高均值为170(cm).1,这两个变量对应的单位不一样,同样是100,对于身高来说很矮 ...
- Android动态加载so文件
在Android中调用动态库文件(*.so)都是通过jni的方式,而且往往在apk或jar包中调用so文件时,都要将对应so文件打包进apk或jar包,工程目录下图: 以上方式的存在的问题: 1.缺少 ...
- HW2.5
import java.util.Scanner; public class Solution { public static void main(String[] args) { Scanner i ...
- Codeforces126B - Password(KMP)
题目大意 给定一个字符串S,要求你找到一个最长的子串,它既是S的前缀,也是S的后缀,并且在S的内部也出现过(非端点) 题解 KMP的失配函数f[i]的非零值就是前i个字符的一个最长前缀且也是后缀的字符 ...
- 局域网内Linux服务器时间同步
局域网内Linux服务器时间同步 1.将一台能够上网的服务器作为时间服务器: # /usr/bin/rdate -s time-b.timefreq.bldrdoc.gov //将时间服务器与互 ...
- ZOJ2834--Maximize Game Time(树形DP)
写之前觉得很恶心,写完了觉得挺好玩了,1A,棒棒哒~ 题解全在代码注释中了,想清楚思路一路写下了果然没怎么卡 ^_^ /**************************************** ...
- C# 读取 timestamp 时间戳 值为byte[] 类型时转换为时间戳字符串
C# 中如何读取出来的时间戳为 byte[] 类型的话,用以下方式转换成 16进制字符串 string tmpUfts = "0x"+ BitConverter.ToString( ...
- S2SH商用后台权限系统第三讲
个位博友: 您好!今天我们做下登录页面,已经如何登录系统.我们的登录页面很简单,用户名.密码.验证码.下面首先描述下验证码的概念,验证码是为了防止机器人恶意登录.我们这里的验证码采用4位数字,当然你也 ...
- TransactionScope 对该事务的状态无效 和一些注意事项
使用TransactionScope 的时候要操作同一种数据库操作方式,不能一个方法用ado.net ,另外一个方法用EF,那样会报 "该事务管理器已经禁止了它对远程/网络事务的支持&quo ...