c#学习笔记一 基础知识

1.命名空间

C#程序利用命名空间进行组织,命名空间既可以用作程序的内部组织系统,也可以用作向外部公开的组织系统(即一种向其它程序公开自己拥有的程序元素的方法)。

如果要调用某个命名空间中的类或方法,首先需要使用using指令引入命名空间,using指令将命名空间内的类型成员导入当前编译单元。using 命名空间名。

 

2.数据类型

C#数据类型分为两种,值类型和引用类型。值类型直接存储数据;引用类型存储对其数据的引用,又称对象。值类型可以通过执行装箱和拆箱操作来按对象处理。

值类型:整形、浮点型、布尔型、struct

引用类型:string和object,用new创建对象实例

c#的类型系统是统一的,object类型是所有类型的父类(预定义类型、用户定义类型、引用类型、值类型)。

变量的复制:

int v1 = 0;    整型

int v2 = v1;   //值赋值,值并不保持一致

Point p1 = new Point(); 类

Point p2 = p1; //引用赋值,值保持一致

例子:

int intOne = 300; //直接定义

float theFloat = 1.12f;

Console.WriteLine("intOne={0}", intOne); //注意这种输出方式

Console.ReadLine(); //目的是使程序暂停,以便观察。按回车键退出

结构类型示例:

 

3.变量声明

与C++的变量声明相仿,

int a = 99;

string str = "hello";

 

4.数据类型转换

(1)隐式类型转换:

(2)显式类型转换:强制类型转换

double x = 198802.5;

int y = (int)x;     //方式一

int y = Convert.ToInt32(x);  //使用Convert关键字的

 

string str = Console.ReadLine();
int year = Int32.Parse(str);  //从字符串中提取整型

 

5. 装箱和拆箱

装箱:把值类型转换为引用类型,装箱后值的改变互不影响。

int i = 2011;

object obj = i;  //对值类型装箱操作

拆箱:将引用类型转换为值类型,两个阶段:(1)检查对象实例,看是否是值类型的装箱值;(2)将实例的值赋值给值类型的变量

int i = 2011;

object obj = i;  //装箱

int j = (int)ojb; //拆箱 

 

6.特殊运算符

(1)is 检查变量是否为指定的类型

int i = 0;

bool result = i is int;

(2)条件运算符 ?:  

 

(3)new,创建新的数据类型实例

string[] str = new string[5];

str[0] = "i";

str[1] = "am";

 

(4)typeof 获得系统原型对象的类型

Type myType = typeof(int);

console.writeLine("类型:{0}", myType);

输出为:类型: System.Int32

 

判断素数的例子:着重在于其数据类型转换、输入输出处理

 

递归算法的斐波那契函数

 

7. 面向对象程序设计

Object-Oriented Programming, OOP

结构struct的声明可以不用new关键字,值类型

C#也只支持单继承,想多继承的话就是用接口interface

7.1 接口:

接口的相关陈述

1.一个接口定义了一个契约。

2.接口可以包容方法、C# 属性、事件、以及索引器。

3.在一个接口声明中,我们可以声明零个或者多个成员。

4.所有接口成员的默认访问类型都是public

5.如果在接口成员声明中包括了任何修饰符,那么会产生一个编译器错误。

6.与一个非抽象类类似,一个类必须提供接口中所有成员的实现,只要这些成员在这个类的基类中出现过。

 7 当基类型列表包含基类和接口时,基类必须是列表中的第一项。  

 8 实现接口的类可以显式实现该接口的成员。显式实现的成员不能通过类实例访问,而只能通过接口实例访问

 

示例:

 

 

7.2 抽象类

abstract 修饰的类为抽象类,只是表达一种抽象的概念。它只能用作基类。抽象类与非抽象类在以下方面是不同的:

  •     抽象类不能直接实例化,并且对抽象类使用 new 运算符是编译时错误。虽然一些变量和值在编译时的类型可以是抽象的,但是这样的变量和值必须或者为 null,或者含有对非抽象类的实例的引用(此非抽象类是从抽象类派生的)。
  •     允许(但不要求)抽象类包含抽象成员。
  •     抽象类不能被密封。

当从抽象类派生非抽象类时,这些非抽象类必须具体实现所继承的所有抽象成员,从而重写那些抽象成员

抽象方法:

  • 抽象方法必须声明在抽象类中。
  • 声明抽象方法时不能使用virtual、static、private关键字

当从抽象类派生非抽象类时,需要在非抽象类中重写抽象方法,提供具体实现。重写抽象方法时使用override关键字

 

抽象类与接口

相同点:
    (1) 都可以被继承
    (2) 都不能被实例化
    (3) 都可以包含方法声明
    (4) 派生类必须实现未实现的方法
 区 别:
    (1) 抽象基类可以定义字段、属性、方法实现。接口只能定义属性、索引器、事件、和方法声明,不能包含字段
    (2) 抽象类是一个不完整的类,需要进一步细化,而接口是一个行为规范。微软的自定义接口总是后带able字段,证明其是表述一类“我能做。。。”
    (3) 接口可以被多重实现,抽象类只能被单一继承
    (4) 抽象类更多的是定义在一系列紧密相关的类间,而接口大多数是关系疏松但都实现某一功能的类中
    (5) 抽象类是从一系列相关对象中抽象出来的概念, 因此反映的是事物的内部共性;接口是为了满足外部调用而定义的一个功能约定, 因此反映的是事物的外部特性
    (6) 接口基本上不具备继承的任何具体特点,它仅仅承诺了能够调用的方法   
    (7) 接口可以用于支持回调,而继承并不具备这个特点
    (8) 抽象类实现的具体方法默认为虚的,但实现接口的类中的接口方法却默认为非虚的,当然您也可以声明为虚的
    (9) 如果抽象类实现接口,则可以把接口中方法映射到抽象类中作为抽象方法而不必实现,而在抽象类的子类中实现接口中方法     使用规则:
    1、抽象类主要用于关系密切的对象,而接口最适合为不相关的类提供通用功能
    2、如果要设计大的功能单元,则使用抽象类;如果要设计小而简练的功能块,则使用接口。
    3、如果预计要创建组件的多个版本,则创建抽象类。接口一旦创建就不能更改。如果需要接口的新版本,必须创建一个全新的接口。
    4、如果创建的功能将在大范围的全异对象间使用,则使用接口;如果要在组件的所有实现间提供通用的已实现功能,则使用抽象类。
    5、分析对象,提炼内部共性形成抽象类,用以表示对象本质,即“是什么”。为外部提供调用或功能需要扩充时优先使用接口
    6、好的接口定义应该是具有专一功能性的,而不是多功能的,否则造成接口污染。 如果一个类只是实现了这个接口的中一个功能,而不得不去实现接口中的其他方法,就叫接口污染
    7、尽量避免使用继承来实现组建功能,而是使用黑箱复用,即对象组合。因为继承的层次增多,造成最直接的后果就是当你调用这个类群中某一类,就必须把他们 全部加载到栈中!后果可想而知。(结合堆栈原理理解)。同时,有心的朋友可以留意到微软在构建一个类时,很多时候用到了对象组合的方法。比如 asp.net中,Page类,有Server Request等属性,但其实他们都是某个类的对象。使用Page类的这个对象来调用另外的类的方法和属性,这个是非常基本的一个设计原则

参考:

http://www.cnblogs.com/lovemyth/archive/2008/09/08/828909.html

http://blog.csdn.net/fxh_hua/archive/2009/08/20/4464739.aspx

 

7.3 密封类

关键字 sealed

密封类用来限制扩展性,如果密封了某个类,则该类不可被继承;如果密封了某个成员,则派生类不能重写该成员的实现。

 

get、set访问器
C#里分字段和属性,都是成员变量,字段是私有的,在程序内部使用,而属性则是对外提供访问字段的权限(外是指这个类以外的其他类),可能你会问为什么不直接把字段写成PUBLIC的对外公开,如果这样做了就失去了可控性,比如要让一个字段,在外部访问时只能读取而不能修改,那么就可以只写get。又比如,赋值的时候不是什么值都能赋的,要做限制就可以在set中控制。不然的话,别人给这个段赋值多少就是多少。要是你写的程序被人破解,那你这值就被随便改了。没安全性可言,一点也不可控。说白了属性就是用来控制外部访问的。

字段与属性
字段是 private,内部使用。属性是 public 或 protected,对外公开。
通常应仅为具有私有或受保护可访问性的变量使用字段。
字段是一种数据类型的变量,属性是为该字段提供只读,只写,读写功能,可自定义取值赋值的操作(get,set)。

代码演示
int someIntField = 1; 字段
int someIntProperty 属性,设置字段访问属性
{
    set { someIntField = value; }
    get { return somrIntField; }
}

 

覆盖和重写

子类对父类中的虚方法的处理有重写(override)和覆盖(new)
覆盖的意思是子类里面写了一个和父类同名的方法;重写是子类继承了父类里的虚方法
override是重写一个virtual方法,这样将能够体现面向对象中的“多态性”;new是真正的覆盖,没有“多态性”。
重写是实现多态的途径。 比如B继承了A,A里面有一个叫aa的虚方法,B重写了它,如果你声明了A a= new B()那么在你调a.aa()的时候其实是调用了B类里面的aa方法

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值