C#面向对象
◇对象包括属性和方法,属性是指对象固有的特征,方法则是对象的行为。
【例如将手机看作是一个对象,手机的大小、颜色、品牌都可以看作是一个特征,即属性,而打电话、发短信、上网是手机的行为,即方法。】
◇面向对象语言的三大特征分别是封装、继承、多态。
C#类的定义(class)
类的访问修饰符 修饰符 类名
{
类的成员
}
其中:
类的访问修饰符:用于设定对类的访问限制,包括 public、internal 或者不写,用 internal 或者不写时代表只能在当前项目中访问类;public 则代表可以在任何项目中访问类。
修饰符:修饰符是对类本身特点的描述,包括 abstract、sealed 和 static。abstract 是抽象的意思,使用它修饰符的类不能被实例化;sealed 修饰的类是密封类,不能 被继承;static 修饰的类是静态类,不能被实例化。
类名:类名用于描述类的功能,因此在定义类名时最好是具有实际意义,这样方便用户理解类中描述的内容。在同一个命名空间下类名必须是唯一的。
类的成员:在类中能定义的元素,主要包括字段、属性、方法。
C#类中的成员访问修饰符、修饰符
类中的成员包括字段、属性、方法。每个类成员在定义时需要指定访问修饰符、修饰符。
类中成员的访问修饰符有 4 个,具体用法如下。
1) public
成员可以被任何代码访问。
2) private
成员仅能被同一个类中的代码访问,如果在类成员前未使用任何访问修饰 符,则默认为private。
3) internal
成员仅能被同一个项目中的代码访问。
4) protected
成员只能由类或派生类中的代码访问。派生类是在继承中涉及的,将在后面详细介绍。
字段的定义与前面介绍的变量和常量的定义类似,只是在变量或常量前面可以加上访问修饰符、修饰符。
在修饰字段时通常用两个修饰符,即readonly (只读)和static (静态的)。
使用 readonly 修饰字段意味着只能读取该字段的值而不能给字段赋值。
使用 static 修饰的字段是静态字段,可以直接通过类名访问该字段。
需要注意的是常量不能使用 static 修饰符修饰。
定义字段的语法:
访问修饰符 修饰符 数据类型 字段名;
例如:
namespace code_1
{
class Test
{
private int id; //定义私有的整型字段 id
public readonly string name; //定义公有的只读字符串类型字段 name
internal static int age; //定义内部的静态的整型字段 age
private const string major = "计算机"; //定义私有的字符串类型常量 major
}
}
C#类中方法的定义
访问修饰符 修饰符 返回值类型 方法名(参数列表)
{
语句块;
}
其中:
1) 访问修饰符
所有类成员访问修饰符(即:public、private、internal、protected)都可以使用,如果省略访问修饰符,默认是 private。
2) 修饰符
在定义方法时修饰符包括 virtual(虚拟的)、abstract(抽象的)、override(重写的)、static(静态的)、sealed(密封的)。override 是在类之间继承时使用的。
3) 返回值类型
用于在调用方法后得到返回结果,返回值可以是任意的数据类型,如果指定了返回值类型,必须使用 return 关键字返回一个与之类型匹配的值。如果没有指定返回值类型,必须使用 void 关键字表示没有返回值。
4) 方法名
对方法所实现功能的描述。方法名的命名是以 Pascal 命名法为规范的。
5)参数列表
在方法中允许有 0 到多个参数,如果没有指定参数也要保留参数列表的小括号。参数的定义形式是“数据类型参数名”,如果使用多个参数,多个参数之间需要用逗号隔开。
例如:
namespace code_1
{
class Test
{
private int id; //定义私有的整型字段 id
public readonly string name; //定义公有的只读字符串类型字段 name
internal static int age; //定义内部的静态的整型字段 age
private const string major = "计算机"; //定义私有的字符串类型常量 major
private void PrintMsg()
{
Console.WriteLine("编号:" + id);
Console.WriteLine("姓名:" + name);
Console.WriteLine("年龄:" + age);
Console.WriteLine("专业:" + major);
}
//乘法
private double Multiply(double num1,double num2)
{
return num1 * num2;
}
}
}
C# get和set访问器:获取和设置字段(属性)的值
public 数据类型 属性名
{
get
{
获取属性的语句块;
return 值;
}
set
{
设置属性得到语句块;
}
}
其中:
1) get{}
get 访问器,用于获取属性的值,需要在 get 语句最后使用 return 关键字返回一个与属性数据类型相兼容的值。
若在属性定义中省略了该访问器,则不能在其他类中获取私有类型的字段值,因此也称为只写属性。
2) set{}
set 访问器用于设置字段的值,这里需要使用一个特殊的值 value,它就是给字段赋的值。
在 set 访问器省略后无法在其他类中给字段赋值,因此也称为只读属性。
例如:
namespace code_1
{
class Book
{
private int id;
private string name;
private double price;
//设置图书编号属性
public int Id
{
get
{
return id;
}
set
{
id = value;
}
}
//设置图书名称属性
public string Name
{
get
{
return name;
}
}
//设置图书价格属性
public double Price
{
get
{
return price;
}
set
{
price = value;
}
}
}
}
从上面的实例可以看出,在定义字段属性时,属性的作用就是为字段提供 get、set 访问器,由于操作都比较类似,在 C# 语言中可以将属性的定义简化成:
public int Id{get; set;}
public string Name{get; set;}
public double Price{get; set;}
C#调用类成员
调用类的成员实际上使用的是类的对象,对于创建类的对象,首先可以将类理解成一个模板,类的对象则是按照这个模板定制的一个对象。
语法:类名对象名 = new 类名();
例如:Book book = new Book();
如果将类中的成员使用修饰符 static 声明,则在访问类成员时直接使用“类名.类成员”的方式即可。
例如:Book.xxx();
C#构造函数(构造方法)
访问修饰符 类名 (参数列表)
{
语句块;
}
这里构造方法的访问修饰符通常是public类型的,这样在其他类中都可以创建该类的对象。
如果将访问修饰符设置成private类型的,则无法创建该类的对象。构造方法中的参数与其他方法一样,都是 0 到多个参数。
此外,构造方法是在创建类的对象时被调用的。通常会将一些对类中成员初始化的操作放到构造方法中去完成。
例如:
class User
{
public User(string name, string password, string tel)
{
this.Name = name;
this.Password = password;
this.Tel = tel;
}
public string Name { get; set; }
public string Password { get; set; }
public string Tel { get; set; }
public void PrintMsg()
{
Console.WriteLine("用户名:" + this.Name);
Console.WriteLine("密 码:" + this.Password);
Console.WriteLine("手机号:" + this.Tel);
}
}
调用:
class Program
{
static void Main(string[] args)
{
User user = new User("小明","123456","13131351111");
user.PrintMsg();
}
}
C#析构函数(方法)
析构方法是在垃圾回收、释放资源时使用的。
~类名()
{
语句块;
}
在析构方法中不带任何参数,它实际上是保证在程序中会调用垃圾回收方法 Finalize()。
C#方法重载(函数重载)
在讲解《C#构造方法》时提到定义构造方法时提到可以定义带 0 到多个参数的构造方法,但构造方法的名称必须是类名。实际上,这就是一个典型的方法重载,即方法名称相同、参数列表不同。
参数列表不同主要体现在参数个数或参数的数据类型不同。在调用重载的方法时系统是根据所传 递参数的不同判断调用的是哪个方法。
例如:
class SumUtils
{
public int Sum(int a,int b)
{
return a + b;
}
public double Sum(double a,double b)
{
return a + b;
}
public string Sum(string a,string b)
{
return a + b;
}
}
C#方法的参数(实参和形参)
方法中的参数分为实际参数和形式参数,实际参数被称为实参,是在调用方法时传递的参数;形式参数被称为形参,是在方法定义中所写的参数。
在C#语言中,方法中的参数除了定义数据类型外,还可以定义引用参数和输出参数。引用参数使用 ref 关键字定义,输出参数使用 out 关键字定义。
引用参数在方法中使用时必须为其值,并且必须是由变量赋予的值,不能是常量或表达式。
如果需要将方法中的每一个参数都设置为 ref 类型参数,则需要在每一个参数前面加上 ref 关键字修饰。
在使用输出参数时,必须在方法操作结束前为带输出参数的形式参数赋值。
在调用含有带输出参数的方法时,必须在传递参数时使用 out 关键字,但不必给输出参数赋值。
C# lambda表达式
访问修饰符 修饰符 返回值类型 方法名(参数列表) => 表达式;
例如:
class LambdaClass
{
public static int Add(int a, int b) => a + b;
}
调用:
Console.WriteLine(LambdaClass.Add(100, 200));
C#递归
如计算 5 的阶乘,则是 5*4*3*2*1 的结果。实现的代码如下。
class FactorialClass
{
public static int Factorial(int n)
{
if(n == 0)
{
return 1;
}
return n * Factorial(n - 1);
}
}
调用:
int rs = FactorialClass.Factorial(5);
Console.WriteLine("结果是:" + rs);
C#嵌套类
在C#中嵌套类相当于类中的成员,能使用类成员的访问修饰符和修饰符。但是,在访问嵌套类中的成员时必须加上外层类的名称。
例如:
class OuterClass
{
public class InnerClass
{
public string CardId { get; set; }
public string Password { get; set; }
public void PrintMsg()
{
Console.WriteLine("卡号为:" + CardId);
Console.WriteLine("密码为:" + Password);
}
}
}
调用:
OuterClass.InnerClass outInner = new OuterClass.InnerClass();
outInner.CardId = "622211100";
outInner.Password = "123456";
outInner.PrintMsg();
从该实例中可以看出,如果在其他类中调用嵌套类的成员,需要使用“外部类.嵌套类”的方式创建嵌套类的对象,从而通过嵌套类的对象调用其成员。
如果调用的是嵌套类中的静态成员,直接通过“外部类 . 嵌套类 . 静态成员”的方式调用即可。
C# partial部分类
一个类可以由多个部分类构成,定义部分类的语法:
访问修饰符 修饰符 partial class 类名{……}
在这里,partial 即为定义部分类的关键字。部分类主要用于当一个类中的内容较多时将相似类中的内容拆分到不同的类中,并且部分类的名称必须相同。
除了定义部分类外,还可以在部分类中定义部分方法,实现的方式是在一个部分类中定义一个没有方法体的方法,在另一个部分类中完成方法体的内容。
部分方法用的不是特别多,这里咱们了解即可。
使用部分方法需要注意如下 3 点:
1、部分方法必须是私有的,并且不能使用 virtual、abstract、override、new、sealed、extern 等修饰符。
2、部分方法不能有返回值。
3、在部分方法中不能使用 out 类型的参数。
C# Console类:控制台输入输出
Console 类主要用于控制台应用程序的输入和输岀操作。
Write
向控制台输出内容后不换行
WriteLine
向控制台输出内容后换行
Read
从控制台上读取一个字符
ReadLine
从控制台上读取一行字符
C# Math类
Math 类主要用于一些与数学相关的计算,并提供了很多静态方法方便访问,常用的方法如下表所示。
Abs
取绝对值
Ceiling
返回大于或等于指定的双精度浮点数的最小整数值
Floor
返回小于或等于指定的双精度浮点数的最大整数值
Equals
返回指定的对象实例是否相等
Max
返回两个数中较大数的值
Min
返回两个数中较小数的值
Sqrt
返回指定数字的平方根
Round
返回四舍五入后的值
C# Random类
Random 类是一个产生伪随机数字的类,它的构造函数有两种。
New Random();
New Random(Int32)。
前者是根据触发那刻的系统时间做为种子,来产生一个随机数字,后者可以自己设定触发的种子,一般都是用 UnCheck((Int)DateTime.Now.Ticks) 做为参数种子。
因此如果计算机运行速度很快,如果触发 Randm 函数间隔时间很短,就有可能造成产生一样的随机数,因为伪随机的数字,在 Random 的内部产生机制中还是有一定规律的,并非是真正意义上的完全随机。
Random 类中提供的 Next、NextBytes 以及 NextDouble 方法可以生成整数类型、byte 数组类型以及双精度浮点型的随机数,详细说明如下表所示。
Next()
每次产生一个不同的随机正整数
Next(int max Value)
产生一个比 max Value 小的正整数
Next(int min Value,int max Value)
产生一个 minValue~maxValue 的正整数,但不包含 maxValue
NextDouble()
产生一个0.0~1.0的浮点数
NextBytes(byte[] buffer)
用随机数填充指定字节数的数组
例如:
class Program
{
static void Main(string[] args)
{
Random rd = new Random();
Console.WriteLine("产生一个10以内的数:{0}", rd.Next(0, 10));
Console.WriteLine("产生一个0到1之间的浮点数:{0}", rd.NextDouble());
byte[] b = new byte[5];
rd.NextBytes(b);
Console.WriteLine("产生的byte类型的值为:");
foreach(byte i in b)
{
Console.Write(i + " ");
}
Console.WriteLine();
}
}
C# DateTime类
DateTime 类用于表示时间,所表示的范围是从 0001 年 1 月 1 日 0 点到 9999 年 12 月 31 日 24 点。
在 DateTime 类中提供了静态属性 Now,用于获取当前的日期和时间,如:DateTime.Now
DateTime 类提供了 12 个构造方法来创建该类的实例,但经常使用不带参数的方法创建 DateTime 类的实例。
在 DateTime 类中提供了常用的属性和方 法用于获取或设置日期和时间,如下表所示。
Date
获取实例的日期部分
Day
获取该实例所表示的日期是一个月的第几天
DayOfWeek
获取该实例所表示的日期是一周的星期几
DayOfYear
获取该实例所表示的日期是一年的第几天
Add(Timespan value)
在指定的日期实例上添加时间间隔值 value
AddDays(double value)
在指定的日期实例上添加指定天数 value
AddHours(double value)
在指定的日期实例上添加指定的小时数 value
AddMinutes(double value)
在指定的日期实例上添加指定的分钟数 value
AddSeconds(double value)
在指定的日期实例上添加指定的秒数 value
AddMonths(int value)
在指定的日期实例上添加指定的月份 value
AddYears (int value)
在指定的日期实例上添加指定的年份 value
例如1:使用 DateTime 类获取当前时间,分别输出该日是当月的第几天、星期几以 及一年中的第几天,并计算 30 天后的日期。
class Program
{
static void Main(string[] args)
{
DateTime dt = DateTime.Now;
Console.WriteLine("当前日期为:{0}", dt);
Console.WriteLine("当前时本月的第{0}天", dt.Day);
Console.WriteLine("当前是:{0}", dt.DayOfWeek);
Console.WriteLine("当前是本年度第{0}天", dt.DayOfYear);
Console.WriteLine("30 天后的日期是{0}", dt.AddDays(30));
}
}
例如2:两个日期的差可由时间间隔类 TimeSpan 的对象来存放。假设计算现在距离2018年6月1日儿童节的天数,代码如下。
class Program
{
static void Main(string[] args)
{
DateTime dt1 = DateTime.Now;
DateTime dt2 = new DateTime(2019, 6, 1);
TimeSpan ts = dt2 - dt1;
Console.WriteLine("间隔的天数为{0}天", ts.Days);
}
}