深入.NET平台和C#编程
一. netFrameWork框架
运行在操作系统上,是.net的基础环境它由两部分组成,分别是CLR,FCL
1、CLR:公共语言运行时
运行环境
基本规范:
.1、CTS:规范类型(type)
C#:int--->int32
java:int/Integer-->int32
Convert.ToInt32()
.2、CLS:规范语法(language)
.3、MSIL:中间语言
java/C#数组:
2、FCL:框架类库
表示一部分已经被封装好的功能的集合
用法:引用命名空间
3、面向对象的回顾
定义: 类是对象的抽象,对象是类的具体
类的三大特性:
(1)类的特性:封装:将一些特性私有化,将底层(实现过程)藏起来(实现方案:将内容用方法包装)
private int age;
public int Age
{
get{}
set
{
if(age > 10){有错}
}
}
(2) 继承:子承父业
(3)多态:一个事物的多种形态
定义类:
public class 类名
{
字段私有
属性:get[只读]、set[只写]
方法
}
public class 示例
{
private string _name;
public string Name
{
get { return Name; }
set { _name = value; }
}
}
class Student
{
public int ID;
public string name;
public int age;
public string address;
}
static void Main(string[] args)
{
Student stu = new Student();
Console.Write("请输入编号:");
stu.ID = Convert.ToInt32(Console.ReadLine());
Console.Write("请输入姓名:");
stu.name= Console.ReadLine();
Console.Write("请输入年龄:");
stu.age = Convert.ToInt32(Console.ReadLine());
while (stu.age <= 18)
{
Console.WriteLine("学员年龄必须大于等于18岁");
Console.Write("请重新输入年龄:");
stu.age = Convert.ToInt32(Console.ReadLine());
}
Console.Write("我的家庭住址为:");
stu.address = Console.ReadLine();
string XxI = string.Format("我的编号为{0},姓名为{1},年龄为{2},家庭住址为{3}",
stu.D,stu.name,stu.age,stu.address);
Console.WriteLine(XxI);
Console.ReadLine();
}
类成员:字段,属性,方法
类怎么使用:
通 过 对 象 类 名 对 象 名 = n e w 类 名 ( ) ; 对 象 : 对 象 名 . 属 性 [ 调 用 g e t 方 法 ] 、 对 象 名 . 属 性 = [ 调 用 s e t 方 法 ] 对 象 名 . 方 法 ( ) ; 通过对象 类名 对象名 = new 类名(); 对象: 对象名.属性[调用get方法]、对象名.属性=[调用set方法] 对象名.方法(); 通过对象类名对象名=new类名();对象:对象名.属性[调用get方法]、对象名.属性=[调用set方法]对象名.方法();
二.深入C#数据类型
数据类型
1、基本数据类型
1.包括的数据类型
数值:int,long,double,float
字符:char
布尔:bool
枚举:enum
结构:struct
2、命名空间:System.ValueType
3、保存方式:值保存在栈里面
2、引用数据类型
1.包括的数据类型
class(string)
数组
集合
委托
接口
2.命名空间:syste.Object;
3.值保存在堆里面
struct结构
(应用在静态动作比较多的情况)
1.定义
类似类,但struct是基本数据类型,而类是引用数据类型
.1使用关键字struct
.2字段不能赋初始值
.3不能手写无参构造函数
.4结构里有多少个字段,定义构造函数就要有多少个参数
2.struct的使用
.1可以new出来,也可以不new出来
[注意:如果不new直接赋初始值会语法报错]
.2结构在使用的时候要给所有字段赋初始值,不然会语法报错
示例:
public class StuClass
{
#region 构造函数---》方法,new对象用的,主要作用给字段赋值
/// <summary>
/// 作用:new对象的
/// 如果不手写,那么会有一个默认的无参隐藏构造函数
/// 一旦手写构造函数,不存在默认构造函数
/// 构造函数:有参构造,无参构造函数
/// java:
/// Scanner in = new Scanner(System.in)
/// String str = new String();
/// String str = new String("sdf");
/// </summary>
public StuClass() { }
#endregion
#region 字段+属性
private String _name = "asdf";
public string Name { get => _name; set => _name = value; }
#endregion
#region 方法
public void ShowInfo()
{
Console.WriteLine("自我介绍!");
}
#endregion
}
public struct StStruct
{
#region 构造函数
//结构在使用的时候,所有字段必须赋值
//定义构造函数的时候,必须给所有的字段赋值;不能手写无参构造函数
//public StStruct() { }
public StStruct(int age, String name)
{
this._age = age;
this._name = name;
}
#endregion
#region 字段+属性
public int _age;
//结构:不需要get、set属性
public int Age { get => _age; set => _age = value; }
//结构在定义字段时候不能有初始值
//public String _name = "df";
public String _name;
public string Name { get => _name; set => _name = value; }
#endregion
#region 方法
public void ShowInfo()
{
Console.WriteLine("自我介绍!");
}
#endregion
}
3.注意使用的事项
1、结构只保存栈
2、如果字段太多,频繁相互指向,不建议
如果没有字段,自己使用自己的值—》性能比较优化
堆:空间大速度慢
栈:空间小速度快
参数传递
1.值传递
1.基本数据类型:形参所做改变不会影响实参
2.引用数据类型:形参所做改变会影响实参[同一个堆里面],string除外
同一个堆也就是 对象不能直接 用=值
图片:
2.引用传递[地址传递]
1.形参所做修改会影响实参
2.形参和实参都要在前面加ref
3.、加了ref,表示,当前变量,指针,指向前一个变量的地址
图片:
装拆箱
装箱:基本数据---》引用--->自动转换
int i = 0;
Object obj = i;
拆箱:引用---》基本
Object obj = 100;
int i=Convert.ToInt32(obj);
示例;
static void Main(string[] args)
{
Console.WriteLine("********************设置计算机ID前***********************");
Console.WriteLine("计算机型号\t计算机ID\t购买时间");
Computer[] computers = new Computer[3];
Computer cm1 = new Computer();
cm1.Type = "hpCQ-217TX";
cm1.Datetime = "2013-10-5";
computers[0] = cm1;
Computer cm2 = new Computer();
cm2.Type = "Mc240CH/A";
cm2.Datetime = "2013-10-5";
computers[1] = cm2;
Computer cm3 = new Computer();
cm3.Type = "SYNW18/W";
cm3.Datetime = "2013-10-5";
computers[2] = cm3;
for (int i = 0; i < computers.Length; i++)
{
Console.WriteLine(computers[i].Type+"\t\t\t"+computers[i].Datetime);
}
Console.WriteLine();
Console.WriteLine("********************设置计算机ID后***********************");
Console.WriteLine("计算机型号\t计算机ID\t购买时间");
Random rd = new Random();
for (int i = 0; i < computers.Length; i++)
{
int sjshu = rd.Next(1000, 9999);
computers[i].Id += computers[i].Type + "-" + sjshu;
Console.WriteLine(computers[i].Type + "\t" +computers[i].Id+"\t"+ computers[i].Datetime);
}
Console.ReadLine();
}
三.使用集合组织相关信息
基本定义:
1、集合:保存一组大小不固定的值
2、类似数组:
3、泛型跟非泛型:
泛型:限定了数据类型
非泛型:没有限定数类型
ArrayList
ArrayList:没有限定数据类型—>涉及到频繁的拆箱装箱,类型转换
1、创建对象
ArrayList list = new ArrayList();
2、属性:
Count–》得到长度
3、方法:
Add(Object value)–>添加
RemoveAt(int index)–>移除的是下标
Remove(Object value)—>移除的是值
Clear()—>清空所有的
[int index]–>1、获取值;2、赋值【注意:下标一定是已经存在的】
4、遍历
for
for(int i = 0; i < list.Count;i ++)
{
Object obj = list[i];
Console.WriteLine(obj );
}
foreach
foreach(Object value in list)
{
Console.WriteLine(value );
}
List
List:限定了数据类型
1、创建对象
List list = new List();
T:任意数据类型
List可以实现ArrayList的效果–》List也可以保存任意值
List
List list = new List(); //不放T数据类型,error,编译报错
2、属性:
Count–》得到长度
3、方法:
Add(Object value)–>添加
RemoveAt(int index)–>移除的是下标
Remove(Object value)—>移除的是值
Clear()—>清空所有的
[int index]–>1、获取值;2、赋值【注意:下标一定是已经存在的】
4、遍历:
for:
for(int i = 0; i < list.Count; i++)
{
list[i]
}
foreach
foreach(T value in list)
{
value
}
示例:
HealthCheckSet set;
//采用泛型集合List保存所有的体检项目
List<HealthCheckItem> AllItems = new List<HealthCheckItem>();
//采用泛型集合List保存套餐中的体检项目
List<HealthCheckItem> items = new List<HealthCheckItem>();
#region 创建所有检查项目,并保存在AllItems集合中
public void AllItemsd()
{
height = new HealthCheckItem("身高","用于检查身高",5);
weight = new HealthCheckItem("体重","用于检查体重",5);
Gang = new HealthCheckItem("肝","用于检查肝功能",50);
B超 = new HealthCheckItem("B超","用于检查B超",30);
ekg = new HealthCheckItem("心电图", "用于检查心电图", 50);
bloodPressure = new HealthCheckItem("血压", "用于检查血压", 20);
bloodTest = new HealthCheckItem("血常规","用于检查血常规", 20);
AllItems.Add(height);
AllItems.Add(weight);
AllItems.Add(Gang);
AllItems.Add(B超);
AllItems.Add(ekg);
AllItems.Add(bloodPressure);
AllItems.Add(bloodTest);
}
#endregion
#region 创建一组默认套餐设置
private void InerSet()
{
//创建1种默认套餐对象
items = new List<HealthCheckItem>();
items.Add(height);
items.Add(weight);
items.Add(B超);
set = new HealthCheckSet("入学体检", items);
//计算套餐价格
set.CalcPrice();
this.HealthSet.Add("入学体检", set);
}
#endregion
#region 加载体检套餐
private void TjianTC()
{
this.cboSets.Items.Clear();
this.cboSets.Items.Add("请选择");
foreach (string key in HealthSet.Keys)
{
this.cboSets.Items.Add(key);
}
this.cboSets.SelectedIndex = 0;
}
#endregion
#region 加载事件
private void frmMain_Load(object sender, EventArgs e)
{
this.lblSetName.Text = " ";
this.lblSetPrice.Text = " ";
this.btnAdd2.Enabled = true;
this.btnClear.Enabled = true;
AllItemsd();//创建所有检查项目,并保存在AllItems集合中
InerSet();//创建一组默认套餐设置
TjianTC();// 加载体检套餐
}
#endregion
#region 更新套餐检查项目
private void UpdateSet(HealthCheckSet set)
{
this.dgvTj.DataSource = new BindingList<HealthCheckItem>(set.Items);
}
#endregion
Hashtable
1、创建对象
Hashtable ht = new Hashtable();
2、属性
Count–》得到长度
Keys—>得到当前Hashtable里面所有的键
Values–>得到当前hashtabale里面所有的值
3、方法
Add(Object key, Object value)
Remove(Object key)–>根据key移除
Clear()清空
5、遍历:
1、遍历所有key
foreach(Object key in ht.Keys)
{
key + ht[key]
}
2、遍历所有的value
foreach(Object value in ht.Values)
{
value
}
4、key是唯一
Dictionary
1、创建对象
Dictionary<Tkey, Tvalue> dic = new Dictionary<TKey, Tvalue>();
2、属性
Count–》得到长度
Keys—>得到当前Hashtable里面所有的键
Values–>得到当前hashtabale里面所有的值
3、方法
Add(Object key, Object value)
Remove(Object key)–>根据key移除
Clear()清空
ContainsKey(TKey key);–》判断key是否已经存在,存在返回true
5、遍历:
1、遍历所有key
foreach(T key in ht.Keys)
{
key + ht[key]
}
2、遍历所有的value
foreach(T value in ht.Values)
{
value
}
4、key是唯一
3、null不能作为key,编译的报错,运行的时候
示例:
//使用Dictionary字典保存套餐集合
public Dictionary<string, HealthCheckSet> HealthSet = new Dictionary<string, HealthCheckSet>();
#region 创建所有检查项目,并保存在AllItems集合中
public void AllItemsd()
{
height = new HealthCheckItem("身高","用于检查身高",5);
weight = new HealthCheckItem("体重","用于检查体重",5);
Gang = new HealthCheckItem("肝","用于检查肝功能",50);
B超 = new HealthCheckItem("B超","用于检查B超",30);
ekg = new HealthCheckItem("心电图", "用于检查心电图", 50);
bloodPressure = new HealthCheckItem("血压", "用于检查血压", 20);
bloodTest = new HealthCheckItem("血常规","用于检查血常规", 20);
AllItems.Add(height);
AllItems.Add(weight);
AllItems.Add(Gang);
AllItems.Add(B超);
AllItems.Add(ekg);
AllItems.Add(bloodPressure);
AllItems.Add(bloodTest);
}
#endregion
#region 创建一组默认套餐设置
private void InerSet()
{
//创建1种默认套餐对象
items = new List<HealthCheckItem>();
items.Add(height);
items.Add(weight);
items.Add(B超);
set = new HealthCheckSet("入学体检", items);
//计算套餐价格
set.CalcPrice();
this.HealthSet.Add("入学体检", set);
}
#endregion
自定义泛型:
作用:
保证类里面的变量数据类型更加灵活
语法:
public class 类名
{
}
四.深入类的方法
重载
1.特点与运用
1、在同一个类中
2、相同的方法名
3、不同的参数,或者个数不相同
4、对应的参数下标的—》参数类型不同
同类中方法后面的参数个数不同
同类中方法后面的参数个数相同,数据类型不同
2、类的成员
1、.同类中不能有相同名字的字段
2、一般不能有相同的方法名,在重载状态下允许相同方法名
3、存在意义
为了解决方法名太多的问题
void Add(int i, int j){}
void Add(int i, int j,int k){}
4、调用规则与注意事项
根据参数[个数+类型]调用
【不能】以【返回值类型】来决定是否是重载
【不能】以【访问修饰符】来决定是否是重载
构造函数
1、语法和作用
访问修饰符 类名(){}
注意:
1、类似方法,只是少了一个返回值
2、方法名有要求:跟类名一致
3、构造函数也是会被重载
用来new对象,兼职:给成员变量赋值(作用)
2、分类
显示方式:
隐式:隐藏的无参
1、就是创建一个类,没有手写构造函数的时候当前类自带的构造函数
2、就是无参的构造函数
显示:自定义构造
就是自定义构造函数
参数的格式:
有参
无参
3、特点(C#和Java)
只要定了一个类:如果没有手写构造函数,那么这个类会自带一个无参的构造函数,并且这个构造函数比隐藏
只要你手写了构造函数,那么这个类就不会存在隐藏构造函数【不会有默认的无参构造函数】
对象交互
面向对象的方法
1.封装
隐藏实现细节,公开某种功能作为与外界的通信的通道
2.消息传递
每个对象都有特定的功能 ,相对其它对象而言,它的功能就是为其它对象提供的服务
示例:
public class Client
{
public Client customer;//顾客
public int id;
public string mealLisst;
}
public class Order
{
public Client customer;//顾客
public int id;
public string mealLisst;
}
public class Waitress
{
private Order order;
public void GetOrder(Order order)
{
this.order = order;
}
}
`