面向对象、类、字符串

1. 面向对象:

对于一个程序员,万物皆对象,你能看到的摸到的感觉到的都是对象。

我们生活中一个对象一般用特征和行为:

例如:张老师 特征,姓名 身高 体重 

 行为,说话 走路 吃饭

在程序中,描述一个对象用属性和方法:

属性就是用来描述对象的特征的

例如:杨老师的属性: 姓名     身高    体重  性别

  属性的值: 杨中科  178cm  72kg  男

我们用属性来描述对象,对于不同对象的属性可以相同,但属性的值不同

方法:说明了就是指这个对象的行为,动作

例如:杨老师的方法:

讲课  吃饭  睡觉  说话  走路  唱歌等等

2. 类:

我们研究了具有相同属性和相同方法的这些对象,对这些对象做进一步抽象,抽象出一个新的概念:类的概念

类:类是模子,确定对象将拥有的特征(属性)和行为(方法)

比如说:

人类是一个类,凡是人类都应该有姓名,性别,年龄这3个属性,有说话,走路2个方法

张三这个对象属于人类,那么我们就应该知道张三一定具有姓名性别年龄3个属性,并且有说话走路的方法。

人类是个类 张三是个对象    类是对象(张三)的类型

int a;int是类型,a是变量

我们可以用类在声明对象:

人类 张三;这就定义了一个张三对象,这个对象是人类这个类型

对象可以叫做类的实例(instance)。

张三这个对象属于人类,那么就可以说:张三是人类的实例

定义类的语法:

[访问修饰符] class 类名

{//类的开始

成员;

......

}//类的结束

[访问修饰符] 可以省略,省略internal,如果不想省略,则写public

class定义类的关键字

类名:为你定义一个类起一个名字,名字的命名要符合变量的命名规则,类的命名规则一般要采用pascal命名法

{}是这个类的起始和结束位置

成员: 变量 和 方法

如果变量和方法有static修饰叫静态变量和静态方法。静态的通过类来访问:类名:方法名 类名:变量名

如果变量和方法没有static修饰叫实例变量和实例方法

在类中定义的变量,我们一般叫做字段

一般我们把一个类定义在一个单独的一个文件中,类的名称和文件的名称一般相同。

从类产生对象的语法:

类名 对象名=new 类名();

属性:对象名.属性名

在类中定义的方法和变量,如果前面没有访问修饰符,则默认private,即私有的,只能在自己的类中访问。

要想在其他类中也能访问到,那么这个变量和方法前要加public,说明在其他类中也能访问到。

如果一个方法前有static修饰符,那么这个方法叫静态方法,我们通过类名.方法名();直接访问

如果一个方法前没有static修饰符,那么这个方法叫实例方法,如何访问?两步:

1)产生这个类的对象

2)用 对象名.方法名();  对象名.变量名

在类的内部定义变量和方法,如果不写访问修饰符,则这个访问修饰符为private

public:表示这个方法和变量可以在任何地方被访问到

private:表示这个方法和变量只能在本类中访问到

对于字段,在实例化对象时,会被赋初值

 

字段定义成public时会出现以下问题:

1)被用户赋了不符合实际的值,比如年龄赋值-18

2)不想被别人修改的值,会被别人任意修改

我们用属性来解决上面的问题,属性一般是用于保护一个私有变量的,使这个私有变量在赋值或取值时能够检查一下,并能对这个私有变量进行访问权限上的限制

有get或set的方法就叫属性。

Public修饰的字段都要写成属性:

例图:

 

属性按其功能分为

只读 get  只写set  读写set get

3. 类的构造方法

上图中在赋值时,重复的书写对象名,我们可以用构造方法解决。

假如我们有一个属性,不允许用户随意改动,我们一般把这个属性定义为只读类型的属性,那么这个只读类型的属性就不能在实例化后进行对他赋值了,那么我们如何对他初始化呢?我们可以用构造方法来进行初始化。

我们定义好一个类,如果没有写构造方法,那么编译器就会自动在类中给我们添加一个没有参数的构造方法

一旦我们写了一个构造方法,那么编译器就不会在给我们添加一个没有参数的构造方法了。

在创建类的对象的时候,就是在调用没有参数的构造方法。所以我们可以说构造方法就是创建类的实例。

那么什么是构造方法呢?

1)创建一个对象必须调用构造方法

2)构造方法与类同名,且没有返回值,连void都不用写

构造方法用来创建对象,并且可以在构造方法中对对象进行初始化。

构造方法可以有参数,new对象的时候传递参数即可

如果不指定构造方法,则类有一个默认的无参构造方法;如果指定了构造方法,则不再有默认的无参构造方法,如果需要无参构造方法,则需要自己来写。

构造方法可以重载,也就是有多个不同参数的构造方法

指示代词:this 表示当前实例  例图:

4. 命名空间

命名空间用于解决:

1)类冲突,当出现同名的类时,我们只要把同名的类放在不同的命名空间下就可以了。

2)把类分门别类的放在不同的命名空间下

在一个命名空间中,能不能访问另一个命名空间中的类?

1)在相同命名空间中的类可以直接访问

2)在不同命名空间中的类,有2种访问方法:

A. 写全称     命名空间名.类名

B. 在程序的开头导入命名空间   using + 要导入的命名空间名称

例图:

命名空间的起别名:

访问修饰符internal只能在本程序集中访问,和类在同一个级别,或者说在命名空间内,定义的内容(枚举、结构)如果不写访问修饰符,都是internal,表示只能在本项目中访问。

由static修饰的属性叫静态属性,没有static修饰的属性叫实例属性:

1)调用方式不一样:

静态属性      类名.属性名     进行访问

实例属性      实例化类或者实例名.属性名   进行访问

2)其实静态的属性在内存中只有一份,我们可以认为属于类,实例属性:每创建一个类的实例,就会在内存中创建一份实例属性

静态方法和实例方法的区别和上面的一样:

调用:类名.方法名      静态方法不允许直接访问实例的变量和方法

静态的在什么地方都能访问,实例的只能在实例中访问

静态方法中只能访问静态成员

实例方法中既能访问静态成员,也能访问实例成员

5. 字符串

string可以看做是char数组的只读数组。

C#中字符串有一个重要的属性:不可变性。字符串一旦声明就不可再改变。

String类的属性:

Length:字符串的长度

方法:

ToLower();  得到字符串的小写形式

ToUpper();  得到字符串的大写形式

a.Compare(b)比较a与b的大小,a大则返回一个<0的数,b大则返回一个>0的数,a=b,则返回0

一切类型都可以通过ToString()方法转换成字符串类型 。

Split(params char[]); 按指定的字符数分隔字符串

public string [] Split( char [] separator,StringSplitOptions options) ;

string Replace(string oldValue, string newValue)返回把当前对象中的字符第一个参数的内容替换成第二个参数内容的字符串

String Substring(int startIndex)截取字符串,startIndex要截取字符串的起始下标

String Substring(int startIndex,int length)截取多少个字符串

bool Contains(string value) 判断字符串中是否含有子串 value

bool StartsWith(string value) 判断字符串是否以子串 value 开始;

bool EndsWith (string value) 判断字符串是否以子串 value 结束;

int IndexOf(string value) :取子串 value 第一次出现的位置。 如果找不到则返回 -1

Int IndexOf(string value,int startIndex) 如果找不到则返回 -1

Trim(); 去前后两边的空格

 

字符串的使用(常用方法)

1、字符串的定义

语法:

string <name>;

<name> = <value>;

string <name> = <value>;

 

字符串是引用类型,在定义

string <name>;

的时候在栈空间中,定义了一个<name>的空间,该空间存放一个地址

当写到

<name> = "The C# Programming Language";

的时候,会在堆内存分配一个空间,存放字符串"The C# Programming Language",并将首地址赋值给<name>

因此<name>指向定义的字符串

2、字符串的声明

字符串string对应MSIL(CTS)中的String,实际上是一个类

那么以前了解到,类需要使用new <构造方法>()来进行实例化,同样字符串也行(这里只介绍一种)

string <name> = new string(new char[] {...});

注:这里String与string得到的效果一样

这里有个应用

字符串是不可变的,在内存中字符串一旦生成,将不会改变

即使之前使用的str1 + str2也只是生成了另一个字符串

那么要修改字符串,怎么处理呢?

这里有个方法

<strName>.ToCharArray();

该方法会将字符串,变成一个char类型的数组,因此需要用一个char类型的数组接收

例:修改一个字符串里面的内容

char[] ch = <strName>.ToCharArray();

// 处理字符数组,完成修改目的

<strName> = new string(ch);

3、字符串可以用索引访问

字符串,原本就是排在一起的字符,C#提供了用“下标”(索引)来访问字符串中的字符

例如:

string str = "jiangkun";

这里内存中将“j”分配编号0,“i”分配编号1,然后依次增加...

因此,如果需要访问k,数一数,编号是5,所以可以这么来

char temp = str[5];

那么得到的就是字符“k”

字符串也有一个Length属性,可以得到字符串的长度

4、常见的字符串方法

4.1 字符串大小写(字符)

string <strName>.ToUpper();

string <strName>.ToLower();

例:在等待用户输入的时候,常常不考虑用户输入的用户名大小(或一个程序中规定使用的大小写)

可以将用户的输入全部转换成小写、或大写再来进行比较

如:

Console.WriteLine("请输入用户名");

string uid = Console.ReadLine().ToLower();

// 再将uid与系统中的数据进行比较

4.2 移除首尾指定字符

方法原型

string <strName>.Trim(); // 移除首尾的空格

string <strName>.TrimStart(); // 移除开头的空格

string <strName>.TrimEnd(); // 移除结尾的空格

如果要指定移除的内容,可添加一个char数组作为参数

string <strName>.Trim(char[] ch);

例:在用户输入的时候,一般不考虑输入两边的空格,而使用Trim()方法

4.3 字符串的比较

Compare()方法

方法原型

int string.Compare(string str1,string str2);

按照字典排序比较

当str1 > str2时,返回1

当str1 = str2时,返回0

当str1 < str2时,返回-1

注:int string.Compare(string str1,string str2,bool ignoreCase)表示是否区分大小写

这里true表示不区分大小写,默认为false

Equals()方法

方法原型

bool <strName>.Equals(string str);

比较如果相等返回true,否则返回false

注:bool <strName>.Equals(string str, StringComparison.OrdinalIgnoreCase)表示不区分大小写

注:如果仅仅比较两个字符串是否相等,还是使用“==”比较简单

例如:

Console.WriteLine("请输入一个字符串");

string str1 = Console.ReadLine();

Console.WriteLine("请输入第二个字符串");

string str2 = Console.ReadLine();

// 不考虑大小写的比较

bool isEqual = str1.ToLower() == str2.ToLower();

4.4 字符串的合并与分割

合并Join方法

将数组strArr中的内容拼接成一个字符串,并在对应数组的每两项间添加分隔符str

string.Join(str,strArr);

方法原型

string string.Join(string str,string[] strArr);

字符串分割Split方法

方法原型:

string[] <strName>.Split(params char[] separator);

将字符串<strName>以separator数组中的字符分割,分割后得到的内容存到一个数组中

例:

// 分析这句话,提取这句话的单词

string str = "Hello, How are you?";

string[] words = str.Split(' ',',','?');

注:返回的数组中可以有空字符串项,如果要去掉这些空字符串项,可以使用

string[] <strName>.Split(char[] separator,StringSplitOptions.RemoveEmptyEntries);

因此例子可改为

string str = "Hello, How are you?";

string[] words = str.Split(new char[]{' ',',','?'},StringSplitOptions.RemoveEmptyEntries);

4.5 字符串查找

Contains方法

方法原型:

bool <strName>.Contains(string str);

表示字符串<strName>中是否包含str,如果包含,返回true,否则返回false

例:

Console.WriteLine("随便输入一串字母");

string str = Console.ReadLine();

if(str.Contains("abc"))

{

Console.WriteLine("字符串{0}中包含{1}",str,"abc");

}

else

{

Console.WriteLine("字符串{0}中不包含{1}",str,"abc");

}

IndexOf方法

常用的两种形式:

int <strName>.IndexOf(string str); // 从头开始,出现第一次的下标

int <strName>.IndexOf(string str,int startIndex); // 从startIndex开始,出现第一次的下标

如果没有找到则返回-1

例:

string str = "C#语言基础,讲师蒋坤";

int res1 = str.IndexOf("蒋坤");

int res2 = str.IndexOf("蒋 坤");

Console.WriteLine(res1 + "\n" + res2);

注:LastIndexOf方法从最后一个开始匹配

IndexOpAny方法

方法原型:

int <strName>.IndexOfAny(char[] anyOf);

寻找字符数中的所有内容,返回第一个的位置

同样有两个参数的重载

int <strName>.IndexOfAny(char[] anyOf, int startIndex);

4.6 求子字符串

方法原型

string <strName>.Substring(int startIndex, int length);

从字符串<strName>的startIndex位置开始提取长度为length的字符串,如果省略第二个参数表示一直到最后

4.7 字符串的插入、移除和替换

4.7.1 插入

在字符串<strName>的index位置上插入str,原来的字符依次后移,变成一个新的字符串

<strName> = <strName>.Insert(index,str);

方法原型为:

string <strName>.Insert(int index, string str);

4.7.2 移除

在字符串<strName>中移除从startIndex开始,长度为length的字符串,剩下的字符按原序合并为一个新的字符串

<strName> = <strName>.Remove(startIndex,length);

方法原型为:

string <strName>.Remove(int startIndex, int length);

注:如果省略第二个参数,将移除startIndex后的所有字符串

4.7.3 替换

将字符串<strName>中的oldChar替换为newChar

<strName> = <strName>.Replace(oldChar,newChar);

方法原型:

string <strName>.Replace(char oldChar, char newChar);

同样,这个替换的字符也可以是字符串

string <strName>.Replace(string oldValue, string newValue);

4.8 判断结束与开始

判断字符<strName>串是否以某字符串开始或结束

bool <strName>.StartsWith(string str);

bool <strName>.EndsWith(string str);

注:字符串具有不可变性,对字符串的修改,实际上都是重新得到一个字符串,重新赋值

string str = string.Format("格式化字符串,含有{0}占位符的字符串", params object[] args);

posted @ 2012-03-04 22:03  何冬冬  阅读(633)  评论(0编辑  收藏  举报