一,面向对象
(一),为什么需要面向对象
生活中所有的东西都是一个个的对象(万物皆对象),为了描述他们方便,我们就用面向对象的方法来解决
(二),什么是面向对象编程
根据具体的实际生活,设计相对应的类或对象出来,按照生活中的流程或逻辑来操作程序中的类或对象,这样更直观更方便。
(三),面向对象的三大特征
1,封装:封装的类=数据+对此数据所进行的操作(即算法)
2,继承:此特性可以将现实中的事物抽象为类,而且可以将事物之间的派生关系也一并模拟出来。它还是一个可以重用已有代码而不破坏已有代码的方法
3,多态:基类拥有的特性,子类一定有;但子类可以拥有基类没有的特性
二,类
(一)类的基本了解
类:根据实际情况定义的一种复杂的类型
包括两大部分:字段--成员变量(名词或形容词) 方法--成员函数(动词)
(二)类的定义
类的关键词:class
[public/private] class 类名
{
[public/private] 变量类型 变量名; //成员变量的定义;(字段的定义)
public 属性类型 属性名 //属性的定义;
{
get{}
set{}
}
[public/private] 返回类型 函数名(形参列表) //成员函数的定义;(方法的定义)
{
}
}
在类的成员(成员变量,成员函数)前面经常会加访问修饰符(public private protected)
public:公有的,所有的类都可以访问
private:私有的,只有在本类中才可被访问
protected:受保护的,只有在子类中才可被调用
类的封装:不要随便把成员变量设成public,一般需要设成private或protected,通成员方法或成员属性来实现对成员变量的合法访问。
(三)类的使用:
类的实例化 - 生成对象。
类名 引用名 = new 类名();
调用对象的成员:
引用名.成员变量名
引用名.属性名
引用名.成员方法名()
例如:Dog d=new Dog();
d.Name = "旺财";
d.Owner = "张三";
d.Run();
(四)附加
C#中的变量的类型:
1、值类型:
int float double char bool struct datetime
2、引用类型:
string 数组 自定义的类。
模型图:堆空间:所有值类型的变量都是在栈空间中分配的
栈空间:所有引用类型变量所引用的对象,其内存都是在堆空间中分配的
用模型图解释:
A a1 = new A();
A a2 = new A();
Console.WriteLine(a1== a2); //结果为什么是false?
三,类的成员--属性:对成员变量进行访问的端口,用来给私有的成员变量进行安全的赋值取值
(一)定义:
public 属性类型 属性名
{
get //读取部份。
{
return 成员变量名.
}
set //设置部份
{
成员变量名 = value;
}
}
public int Height
{
get
{
return _Height;
}
set
{
if(value>0 && value<300)
{
_Height = value;
}
else
{
Console.WriteLine("Error");
}
}
}
(二)属性的使用
Console.WriteLine(r.Height); - 调用属性的get部分
r.Height = 180; -属性在等号的左边则调用属性的set部分。
四,类的方法——成员函数——方法重载
方法名相同,参数不同(参数类型不同,参数个数不同)——形成了方法的重载
重载的好处:方法命名和记忆方便了;提高代码重用性,减少重复,代码结构更合理
多个重载方法被调用的时候,首先找方法名,然后再根据参数找对应的重载方法。
五,构造函数:对象在实例化的时候自动被调用的函数。无法使用代码显式调用当前对象的构造函数。
通常在构造函数中用来对对象进行初始化的工作(给成员变量赋初始值)
定义
[public/private] 类名()
{
}
特点:1,对象在实例化的时候被自动调用;
2,它是最早被调用的成员函数。 new 类名()——其实就是对构造函数的调用
3,构造函数可以重载
如何调用同一个类中的其它的构造函数?
class ChiBang
{
public string _Type;
public string _Count;
}
class FeiXingQi
{
public FeiXingQi(string name)
{
Name = name;
}
public FeiXingQi(string name,int count,string type):this(name)
{
_ChiBang = new ChiBang();
_ChiBang._Type = type;
_ChiBang._Count = count;
}
}
this代表的当前的对象。this()调用当前对象的其它构造函数。this.xxxx调用当前对象的其它成员。
注意:调用其它构造函数的this() ,不要写在构造函数的{}里面。写在构造函数的声明后面。
4.如果不显式声明构造函数,系统会自动加一个默认的构造函数。一旦显式声明构造函数了,系统将不会再自动生成默认构造函数。
六,静态成员
在面向对象的程序中,对类的实例和静态成员,有以下的访问规则:
1,位于同一类中的实例方法可直接相互调用
2,类的字段(包括实例字段和静态字段)可以被同一类中的所有实例方法直接访问
3,类中的静态方法只能直接访问类静态字段(要想在静态方法中访问实例数据,可通过实例化出该对象即可)
注意:静态成员是属于类的,不管我们造多少个对象,静态成员在内存中永远只是占一个区域
实例成员是属于对象的,每个对象都会有对应实例成员的存储区域
调用实例成员:对象名.实例成员名
调用静态成员:类名.静态成员名
******注意:静态方法中只能调用静态的成员。实例方法可以调用实例成员也可以调用静态成员。
七,继承
(一)什么是继承
1,父类中的相关成员会自动派生到子类中去
2,子类可以扩展父类的相关成员
3,子类可以代替父类来使用,但是父类不能代替子类来使用
(二)继承的语法
class 子类:父类
{
}
(三)继承的法则
1,成员变量的继承
(1)可定义为public或者是protected,则子类都可以访问
(2)如果同名则隐藏。子类与父类各自用各自的成员
2,属性的继承
(1)属性一般只用public来修饰
(2)如果同名则隐藏。子类与父类各自用各自的成员
3,方法的继承
(1)可定义为public或者是protected,则子类都可以访问
(2)如果同名则隐藏。子类与父类各自用各自的成员
(3)重写:I,把父类的方法设为虚方法,virtual——这代表此父类方法可以被重写
II,在子类中用override来重写父类的方法——子类确认要重写
注意: I.如果父类方法中没有声明virtual,子类中有override重写它,会报错。
II.如果父类中声明了virtual,子类中没有override去重写它,不会报名,但会被隐藏。
III.虚方法一虚到底。子类即使override父类的虚方法,子类的这个方法依然还是虚方法。子类的子类还可以override该虚方法
4,构造函数的继承
(1)如果父类没有写构造函数,或者父类构造函数没有参数,则子类的构造函数没有特殊要求。
(2)如果父类的构造函数都有参数,子类构造函数必须向父类构造函数中传递值。base();
注:在子类中调用父类的方法时,可以使用base.xxxx来调用。一般用调用父类被重写的方法。
八,多态:主要是在继承的基础上实现出来的
1,多态的分类:
(1)静态多态(编译多态):是用方法的重载来实现的
(2)动态多态(运行多态):是用继承和重写来实现的
2,抽象类:对事物进行高度的抽象,抽象到一定程度,无法去具体描述。抽象类是无法被实例化的类,不能被new出来
抽象方法:只有方法的声明,没有方法的实现。即只有函数名,输入形参,返回类型,没有函数体(关键词abstract)
抽象类与抽象方法的关系:
(1)含有抽象方法的类一定是抽象类
(2)抽象类不一定包括抽象方法。
遇到抽象类一般有两种处理思路:(1)找到该抽象类的派生类,使用其派生类(2)自己继承此抽象类,实现其派生类
对于抽象方法,子类也必须使用override来实现父类中的抽象方法。
九,接口:只有方法和属性的声明,没有实现的方法,也没有成员变量
语法——定义接口:interface 接口名
{
返回类型 方法名()
属性类型 属性名
{
get;
set;
}
}
实现接口:class 类名:接口名,接口名,.......
{
}
interface 接口名:接口名,接口名,......
{
}
接口的实现可以实现多个接口。
每一个类只能有一个父类,但可以同时实现多个接口。
例:
interface Openable
{
void Open();
}
class Window : Openable
{
}
相关的类只要实现接口,就是该接口下的一个子类,其他设备或程序在调用的时候,只要基于接口调用即可,相应的设备或程序就会被调用到
十,命名空间,项目程序集
1,命名空间:namespace
作用:对类进行逻辑上(在同一根目录下)的分类管理。在同一个命名空间下,类名不许重复。
使用:(1)在代码开头,用using xxxx;把命名空间导进来,以后再用该命名空间下类的时候可以省去命名空间
(2)每次使用类的时候,在类之前写上命名空间,即 使用类的完全限定名。如果所有的不同的命名空间中出现了重名的类,在使用类的时候就需要使用完全限定名
命名空间与java的包是不同的,java的包既有逻辑位置也有物理位置。.net的命名空间仅仅是逻辑上的概念
如何设置默认命名空间?
在解决方案管理器的项目图标上右击,选择属性,设置默认命名空间。
2,项目:主要是用来管理项目所有的文件的
3,程序集:就是程序编译运行时的中间代码(IL),后缀名为.exe 或.dll
C#语言是两步编译:第一步:从源代码编译成中间代码(IL)第二步:运行的时候从IL编译成二进制