结构(struct):一次性声明多个不同类型的变量
声明的位置:将结构声明到命名空间的下面,类的外面,标识这个命名空间下,所有的类 都可使用这个结构
初始化结构成员可通过两种方式来完成
一是:使用参数化构造函数,即使用new关键字
二是:在声明结构后分别访问成员(如果只给部分字段复制会报错)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _1_结构的使用
{
//最好将结构声明在此位置,因为所有的类都可以访问
public struct Clerk //构造函数的声明
{
//声明变量
public string name;
public int age;
public string department;
public char gender;
}
class Program
{
//如果把结构声明在这个位置,只有当前类或其继承类才能使用
static void Main(string[] args)
{
//构造方法的使用
Clerk zs = new Clerk();
zs.name = "张三";
zs.age = 25;
zs.department = "采购部";
zs.gender = '男';
Console.WriteLine(zs.name+"\t"+zs.age + "\t" + zs.department + "\t" + zs.gender);
Console.ReadKey();
}
}
}
如果希望得到一个固定集合的值,就采用枚举
声明方式
【public】 enum 枚举名
{
值1
值2
值3
……
}
声明位置:将枚举声明到命名空间的下面,类的外面,表示这个命名空间下所有的类 都可使用这个枚举
枚举就是一个变量类型,int doubule string decimal
只是枚举声明、赋值、使用的方式跟哪些普通的变量类型不一样,通过**“枚举名.”**的方式引用
默认情况下,每个值都会根据定义的顺序从0开始,自动赋予每个值一个整型。
枚举与int相互转换,要获得枚举的值,只要展缓为sting类型。
枚举与string相互转换
如果将字符串转换成枚举类型则需要下面这样一行代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _2_枚举
{
//在此处声明枚举,它与结构作用类似,所以位置一样,但同时,枚举也可以在结构中被调用
public enum Gender
{
男,
女
}
public enum department
{
//每个值都会根据定义的顺序从0开始,自动赋予每个值一个整型。
人力资源部, //0
财务部, //1
测试部, //2
研发部, //3
产品部=10, //此处是认为指定了一个整数,而不再是默认的顺序了
总裁部
}
class Program
{
static void Main(string[] args)
{
//枚举的调用
Gender zsgender = Gender.男;
Console.WriteLine(zsgender);
Console.WriteLine((int)zsgender); //将枚举转换为整型
Console.WriteLine(zsgender.ToString()); //将枚举转换为字符串
department zsdepartment = department.财务部;
Console.WriteLine(zsdepartment);
Console.WriteLine((int)zsdepartment); //此处输出为3,
department lsdepartment = department.产品部;
Console.WriteLine(lsdepartment);
Console.WriteLine((int)lsdepartment); //此处输出为10,
int myint = 10;
Console.WriteLine((department)myint); //将整型转换为枚举,此处输出是产品部
//将枚举转换为字符串,不能用(string),只能用.Tostring或convert.Tostring()
Console.WriteLine(lsdepartment); //在输出时,输出语句已自动将枚举类型转换为字符串乐行
Console.WriteLine(lsdepartment.ToString());
Console.WriteLine(Convert.ToString(lsdepartment));
//将字符串转换为枚举值
string mystr = "产品部";
Console.WriteLine((department)Enum.Parse(typeof(department), mystr));
string mystr2 = "产品部部";
Console.WriteLine((department)Enum.Parse(typeof(department), mystr2)); //此处会报异常
Console.ReadKey();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _5_类的声明
{
//声明一个类
class clerk
{
}
class Program
{
static void Main(string[] args)
{
}
}
}
类的声明一般不用上面方法声明而是:(快捷键 shift+alt+c)
类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _5_类的声明
{
//枚举
public enum Gender
{
男,
女
}
class clerk
{
//方法中可以存放字段,可以存放属性,还可以存放方法
//在类中声明的变量称为字段
//变量只能存放一个值,字段可以存放多个值,字段是用来存放数据的
//字段的命名规范:_cameCase(下划线非必须)
public string _name;
public Gender _gender;
public int _age;
public string _department;
public int _workYear;
//静态方法只能调用静态成员,非静态方法可以调用任何成员
public void Write()
{
Console.WriteLine("我叫{0},我是{1}生,我{2}岁了,我在{3}任职,我工作了{4}年", _name, _gender, _age, _department, _workYear);
}
public void Write2()
{ //this代表实例化的对象
Console.WriteLine("我叫{0},我是{1}生,我{2}岁了,我在{3}任职,我工作了{4}年", this._name, this._gender, this._age, this._department, this._workYear);
}
}
}
Main方法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _5_类的声明
{
//声明一个类
class clerk1
{
}
class Program
{
static void Main(string[] args)
{
//将类实例化, 就是将类指定给某个对象
clerk zsClerk = new clerk();
zsClerk._name = "张三";
zsClerk._gender = Gender.男;
zsClerk._department = "人力部";
zsClerk._age = 40;
zsClerk._workYear = 25;
string mystring = "张三";
//调用非静态方法
zsClerk.Write();
//再次实例化
clerk lsClerk = new clerk();
lsClerk._name = "李四";
lsClerk._age = 30;
lsClerk._gender = Gender.女;
lsClerk._workYear = 3;
lsClerk._department = "财务部";
mystring = "李四";
lsClerk.Write();
lsClerk.Write2(); //此命令行说明this关键字
//以下输出是说明字段可以存放多个值,变量只能存放一个值
Console.WriteLine(zsClerk._name);
Console.WriteLine(lsClerk._name);
Console.WriteLine(mystring);
Console.WriteLine(mystring);
Console.ReadKey();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _6_属性
{
class Clerk
{
//类中可以存放的成员
//字段:采用_camelClass命名方式
//属性:采用PascalCase命名方式
//方法
private string _name;
public string Name
{
//自动属性,主要是为了预留,以便以后限定属性
get;
set;
}
private char _gender;
//有了属性以后,我们往往都会通过属性来访问字段
//打个比方说:属性是男人,负责外部事务,字段是女人负责内部事务
//属性通常声明为public,字段声明private()
//在外部访问类中的字段,都是通过属性来实现的
//通常我们将get与set称为访问器
//属性分为4种
// 1)
public char Gender
{
get //get 可以用于对取值进行限定 _age
{
if (_gender != '男' || _gender != '女') _gender = '男';
return _gender;
}
set //set 可以用于对赋值进行限定 value
{ _gender = value; } //value是属性里面内置的一个变量,不能人为改变的名称
}
private int _age;
public int Age
{
get
{
return _age;
}
set
{
if (value < 0 || value > 120) value = 0; // 限定赋值
_age = value;
}
}
private string _department;
public string Department
{
get;
set;
}
public int _workYear;
public int WorkYear
{
get;
set;
}
public void Wrte()
{
Console.WriteLine("我叫{0},我是{1}生,我{2}岁了,我在{3}任职,我工作了{4}年", this.Name, this.Gender, this.Age, this.Department, this.WorkYear);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _6_属性
{
class Program
{
static void Main(string[] args)
{
//将类实例化,并分别赋值,并调用其中的方法
Clerk zsClerk = new Clerk();
zsClerk.Name = "张三";
zsClerk.Age = 25;
zsClerk.Department = "人力部";
zsClerk.WorkYear = 5;
zsClerk.Gender = '男';
zsClerk.Wrte();
Console.ReadKey();
}
}
}
构造函数和析函数共性:编写代码时,如果没有提供它们,则编译器自动添加
构造函数是一个特殊的方法
- 构造函数没有返回值,连void也不能写,必须public
- 构造函数的名称必须跟类名一样
作用:帮助我们初始化对象(给对象的每个属性一次的赋值)
创建对象的时候会执行构造函数,构造函数是可以重载的
类当中会有一个默认的无参数的构造函数,当你写一个新的构造函数之后,不管是由参数还是无参数的,那个默认的无参数的构造函数都被覆盖掉。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _8_构造函数和析构函数
{
public enum Gender
{
男,
女
}
class Clerk
{
private string _name;
public string Name
{
get;
set;
}
private Gender _gender;
public Gender Gender
{
get
{
return _gender;
}
set
{
_gender = value;
}
}
private int _age;
public int Age
{
get
{
return _age;
}
set
{
_age = value;
}
}
private string _department;
public string Department
{
get
{
return _department;
}
set
{
_department = value;
}
}
private int _workYear;
public int WorkYear
{
get
{
return _workYear;
}
set
{
_workYear = value;
}
}
public void Write()
{
Console.WriteLine("我叫{0},我是{1}生,我{2}岁了,我在{3}任职,我工作了{4}年", this.Name, this.Gender, this.Age, this.Department, this.WorkYear);
}
//构造函数
public Clerk(string name, Gender gender, int age, string department, int workYear)
{
this.Name = name;
this.Age = age;
this.Gender = gender;
this.Department = department;
this.WorkYear = workYear;
}
public Clerk(string name, Gender gender, int age) //构造函数重载
{
this.Name = name;
this.Age = age;
this.Gender = gender;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _8_构造函数和析构函数
{
class Program
{
static void Main(string[] args)
{
//Clerk zsClerk = new Clerk();
//zsClerk.Name = "张三";
//zsClerk.Gender = Gender.男;
//zsClerk.Age = 30;
//zsClerk.Department = "测试部";
//zsClerk.WorkYear = 10;
//zsClerk.Write();
Clerk zsClerk = new Clerk("张三",Gender.男,25,"测试部",5);
zsClerk.Write();
Clerk lsClerk = new Clerk("张三", Gender.男, 25);
lsClerk.Write2();
Console.ReadKey();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _8_构造函数和析构函数
{
public enum Gender
{
男,
女
}
class Clerk
{
private string _name;
public string Name
{
get;
set;
}
private Gender _gender;
public Gender Gender
{
get
{
return _gender;
}
set
{
_gender = value;
}
}
private int _age;
public int Age
{
get
{
return _age;
}
set
{
_age = value;
}
}
private string _department;
public string Department
{
get
{
return _department;
}
set
{
_department = value;
}
}
private int _workYear;
public int WorkYear
{
get
{
return _workYear;
}
set
{
_workYear = value;
}
}
public void Write()
{
Console.WriteLine("我叫{0},我是{1}生,我{2}岁了,我在{3}任职,我工作了{4}年", this.Name, this.Gender, this.Age, this.Department, this.WorkYear);
}
public void Write2()
{
Console.WriteLine("我叫{0},我是{1}生,我{2}岁了", this.Name, this.Gender, this.Age);
}
//构造函数
public Clerk(string name, Gender gender, int age, string department, int workYear)
{
this.Name = name;
this.Age = age;
this.Gender = gender;
this.Department = department;
this.WorkYear = workYear;
}
public Clerk(string name, Gender gender, int age) //构造函数重载
{
this.Name = name;
this.Age = age;
this.Gender = gender;
}
//如果系统中没有指定析构函数,那么编译器有GC来决定什么时候释放资源
//Garage Collection
~Clerk() //析构函数
{
Console.WriteLine("我是析构函数,看我什么时候调用");
//在使用完当前类的时候,会调用析构函数
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _8_构造函数和析构函数
{
class Program
{
static void Main(string[] args)
{
//Clerk zsClerk = new Clerk();
//zsClerk.Name = "张三";
//zsClerk.Gender = Gender.男;
//zsClerk.Age = 30;
//zsClerk.Department = "测试部";
//zsClerk.WorkYear = 10;
//zsClerk.Write();
Clerk zsClerk = new Clerk("张三",Gender.男,25,"测试部",5);
zsClerk.Write();
Clerk lsClerk = new Clerk("张三", Gender.男, 25);
lsClerk.Write2();
Console.ReadKey();
}
}
}
面向对象的三个基本特征是封装、继承、多态
实例:三个类:
Clerk: _name, Name; _department, Department 可以声明为父类
Sales:_name, Name; _department, Department, _salesTarget,SalesTarget 声明为子类,继承Clerk
Technical Support:_name, Name; _department, Department; _satisfactionRate, SatisfactionRate 声明为子类,继承Clerk
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _10_类的继承
{
class clerk
{
private string _name;
//private是私有,所以不允许被子类访问
public string Name
{
get { return _name; }
set { _name = value; }
}
private string _department;
public string Department
{
get
{
return _department;
}
set
{
_department = value;
}
}
public void CSayHello()
{
Console.WriteLine("大家好我是{0}的{1}",this.Name, this.Department);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _10_类的继承
{
//继承Clerk类
class sales:clerk
{
private int _salesTarget;
public int SalesTarget
{
get
{
return _salesTarget;
}
set
{
_salesTarget = value;
}
}
public void SSayHello()
{
Console.WriteLine("大家好,我是{0}的{1},我的销售目标是{2}",this.Department, this.Name, this.SalesTarget);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _10_类的继承
{
class TechnicalSupport:clerk
{
private double _statisfactionRate;
public double StatisfactionRate
{
get
{
return _statisfactionRate;
}
set
{
_statisfactionRate = value;
}
}
public void TSSayHello()
{
Console.WriteLine("大家好,我是{0}的{1},我的服务满意率为{2}",this.Name,this.Department,this.StatisfactionRate);
}
}
}
- 派生类定义与基类同名的成员,则覆盖基类成员
- 派生类自然继承类的成员,但不能继承基类的构造函数成员 解决此问题有两种方法:
- 在父类中定义一个无参构造函数,或在子类中定义自己的构造函数
- 使用关键字:base()
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _10_类的继承
{
class Program
{
static void Main(string[] args)
{
clerk zsclerk = new clerk("张三", "人事部");
sales zssales = new sales("张三", "人事部",2500);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _10_类的继承
{
class clerk
{
private string _name;
//private是私有,所以不允许被子类访问
public string Name
{
get { return _name; }
set { _name = value; }
}
private string _department;
public string Department
{
get
{
return _department;
}
set
{
_department = value;
}
}
public void CSayHello()
{
Console.WriteLine("大家好我是{0}的{1}",this.Name, this.Department);
}
//构造函数
//子类中不能继承父类中的构造函数,但会默认第调用父类中的无参构造函数
//两种方法子类继承父类的构造函数
//1)在父类中再写一个无参的构造函数,在没个子类当中都需要进行一次构造函数的重写与各个字段的赋值
//2) 使用关键字:base()
public clerk(string name, string department)
{
this.Name = name;
this.Department = department;
}
public clerk() { }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _10_类的继承
{
//继承Clerk类
class sales:clerk
{
private string _name;
//new关键字可以用来隐藏基类中同名成员
//new实例化对象
public new string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
private int _salesTarget;
public int SalesTarget
{
get
{
return _salesTarget;
}
set
{
_salesTarget = value;
}
}
public void SSayHello()
{
Console.WriteLine("大家好,我是{0}的{1},我的销售目标是{2}",this.Department, this.Name, this.SalesTarget);
}
//子类构造函数方式一
//public sales(string name, string department, int salesTarget)
//{
// this.Name = name;
// this.Department = department;
// this.SalesTarget = salesTarget;
//}
//子类构造函数方式而
public sales(string name, string department, int salesTarget):base(name,department)
{
this.SalesTarget = salesTarget;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _10_类的继承
{
class TechnicalSupport : clerk
{
private double _statisfactionRate;
public double StatisfactionRate
{
get
{
return _statisfactionRate;
}
set
{
_statisfactionRate = value;
}
}
public void TSSayHello()
{
Console.WriteLine("大家好,我是{0}的{1},我的服务满意率为{2}", this.Name, this.Department, this.StatisfactionRate);
}
public TechnicalSupport(string name, string department, double satisfactionRate) : base(name, department)
{
this.StatisfactionRate = satisfactionRate;
}
}
}
如果用户希望一个类不被作为基类使用,那么久须使用sealed关键字
唯一的限制是抽象类不能作为封闭的类使用,因为抽象类的本质决定它们必须被作为基类使用。
封闭类的作用是防止意外的派生操作。具体地说,因为编译器确定这个类没有任何派生类,所以可以将封闭类实例上的虚拟函数成员调用转换为非虚拟调用。
虚方法:将父类的方法标记为虚方法,使用关键字virtual,此方法在子类中可以重写(使用关键字override)
抽象类与抽象方法:如果我们不需要使用父类创建对象,它的存在只是为共子类继承。可以将父类写成抽象类(关键字abstract)类,将父类方法写成抽象方法,子类中的方法仍用关键字override重写
接口实现
我们选择使用虚拟方法实现多态还是抽象类抽象方法实现多态,取决于我们是否需要使用基类实例化的对象
main方法调用
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _13类的多态
{
class Program
{
static void Main(string[] args)
{
//虚方法实现多态
clerk myclerk = new clerk();
projectManager mypm = new projectManager();
clerk[] clerks = { myclerk, mypm };
foreach (clerk outclerk in clerks)
{
outclerk.WorkPlan();
}
foreach (clerk outclerk in clerks)
{
outclerk.WorkPlan2();
}
Console.ReadKey();
}
}
}
基类及虚方法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _13类的多态
{
class clerk
{
public void WorkPlan()
{
Console.WriteLine("我是职员,我需要工作计划");
}
public virtual void WorkPlan2()
{
Console.WriteLine("虚方法下,职员的工作计划");
}
}
}
派生类及虚方法重写
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _13类的多态
{
class projectManager:clerk
{
public new void WorkPlan()
{
Console.WriteLine("我是项目经理,我也需要工作计划");
}
public override void WorkPlan2()
{
Console.WriteLine("虚方法下,项目经理工作计划");
}
}
}
Main方法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _13类的多态
{
class Program
{
static void Main(string[] args)
{
//抽象方法实现多态(抽象类是不允许创建实例的)
Drink myMilk = new Milk();
Drink myTea = new Tea();
Drink[] drinkArry = { myMilk, myTea };
foreach (Drink outDrink in drinkArry) outDrink.drink();
Console.ReadKey();
}
}
}
基类(抽象类)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _13类的多态
{
abstract class Drink //抽象类
{
//里用抽象来实现,类抽象化,方法抽象化,并且方法中不能有方法体{}
public abstract void drink(); //抽象方法,抽象方法不能包含方法体
//{
// Console.WriteLine("我是饮料我可以解渴");
//}
}
}
派生类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _13类的多态
{
class Milk:Drink
{
public override void drink()
{
Console.WriteLine("我是牛奶,我可以解渴");
}
}
}
派生类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _13类的多态
{
class Tea:Drink
{
public override void drink()
{
Console.WriteLine("我是茶,我可以解渴");
}
}
}
在使用类与对象的情况下,很少再使用结构