面向对象的引用
例:
class person
{
//这里和在Main中写 string name="sun";bool gender;不一样,这里是在声明类的字段
public string name="sun";//这也不是在声明变量,这是在声明字段
public bool gender;
public int height = Convert.ToInt32("130");//给字段赋值可以调用一行代码
//赋值代码会在对象创建的时候执行
//易错:类的定义只能定义字段、方法等,不能直接写其他代码
//Console.WriteLine("");
//调用者只能通过方法来请求对象改变它的状态,是否改变
//改变多少是类自己决定的,这是为什么字段不能public的原因
//不至于出现升高为负的情况
public void Feed(string foodname)
{
if (foodname == "金克拉")
{
height = height + 10;
}
else if (foodname == "碧生源")
{
if(height <=1)
{
return ;
}
height = height - 1;
}
}
public void SayHello()
{
Console.WriteLine("你好");
}
int GetHeight()
{
return 180;
}
}
面向对象的属性
属性开头字母大写,字段开头字母小写
可以为set、get设置访问级别
例子,限制非法值的设置简化set、get:public int Age{get;set;}。
适合于set、get中没有特殊逻辑代码的情况。
允许外部访问的值一定要声明为属性。
字段和属性的区别是什么?属性看似字段、不是字段,可以进行非法值控制,可以设置只读。
例:
static void Main(string[] args)
{
Person p = new Person();
p.Job = "waitor";
Console.WriteLine(p.Job);
Console.WriteLine(p.EyeCount );
// p.EyeCount = 3;
p.Age = 18;
Console.WriteLine(p.Age);
Console.ReadKey();
}
class Person
{
private string name;
public string Name//属性不会存储值,而是由相应的字段存储值
{
get
{
return name;
}
set
{
this.name = value;
}
}
//编译器的技巧。语法糖:编译器玩花招,让程序员用起来方便。
public int Age//如果暂时没有对非法值控制,只是普通的属性,可以用这种简写
{
get;
set;
}
public int EyeCount//不写set就是只读属性
{
get
{
return 2;//属性返回的值不一定非要存到私有字段中,怎么处理无所谓
}
}
private string job;
public string Job
{
get
{
//当读取Job属性的时候执行的代码
return job;
}
set
{
//和使用字段相比,用属性可以拒绝非法值
if (value == "waitor")
{
this.job = "靓仔";
return;
}
this.job = value;//value是设置的值,名字是固定的
//当设置Job属性的时候执行的代码
}
}
}
例2:
static void Main(string[] args)
{
Person p = new Person();
p.Age = 30;
p.Age = p.Age + 1;
Console.WriteLine (p.Age);
p.Name = "tom";
Console.ReadKey();
}
例3:面向对象版聊天机器人
机器人有不同的名字、维护自己的FullLevel,可以SayHello(我叫***),可以喂食(Eat(int foodCount)),可以对它说话(Speak),对异常情况(错误的喂饭数字,喂的太多撑死了)进行处理,有两个机器人供选择,一开始通过1、2数字选择聊天机器人。
先创建一个类
class Pet
{
private int health=20;//字段中可以不赋值
private int fullLevel=20;
private int age=2;
public void Speak(string s)
{
if (health <= 0)
{
Console.WriteLine("我已死,请烧纸");
return;
}
if (fullLevel <= 1)
{
Console.WriteLine("别BB了,请喂我吃的");
return;
}
health = health - 1;
fullLevel = fullLevel - 1;
if (s.Contains("妈") || s.Contains("草泥马") || s.Contains("fuck"))
{
Console.WriteLine("请文明用语");
return;
}
else if (s.Contains("你好") || s.Contains("hello") )
{
Console.WriteLine("你好");
return;
}
else if (s.Contains("名字") || s.Contains("叫什么"))
{
Console.WriteLine("我叫滚滚");
return;
}
else
{
Console.WriteLine("听不懂");
return;
}
}
public void Wash()
{
health = health + 5;
}
public void PlayBall()
{
if (health <= 0)
{
Console.WriteLine("我已死,请烧纸");
return;
}
if (fullLevel<=0)
{
Console.WriteLine("我饿死了,玩不动了");
return;
}
health = health + 10;
fullLevel -= 5;
}
public void Feed(int foodcount)
{
if (health <= 0 || fullLevel <= 0)
{
Console.WriteLine("我都死了,还喂我东西");
return;
}
if (foodcount <=0)
{
Console.WriteLine("你是什么意思");
}
if (foodcount > 5)
{
health = -1;
Console.WriteLine("撑死了");
}
else
{
fullLevel = fullLevel + foodcount;
}
}
public string Report()
{
return string.Format("health={0},fullLevel={1}, age={2}",health,fullLevel ,age );
}
}
编写程序:
static void Main(string[] args)
{
Pet pet = new Pet();//写到while里面,所有while循环都操作这个宠物
while (true)
{
Console.WriteLine("请执行操作(1、说话 2、洗澡 3、玩球 4、喂饭 )");
string key = Console.ReadLine();
if (key =="1")
{
Console.WriteLine("快说吧!");
string dialog = Console.ReadLine();
pet.Speak(dialog);
}
else if (key == "2")
{
pet.Wash();
}
else if (key == "3")
{
pet.PlayBall();
}
else if (key == "4")
{
Console.WriteLine("输入喂的数量:");
string count = Console.ReadLine();
pet.Feed(Convert .ToInt32 (count ));
}
else
{
Console.WriteLine("会选吗?");
}
Console.WriteLine(pet .Report());
}
Console.ReadKey();
}
构造函数
例:构造函数
static void Main(string[] args)
{
Pet p1 = new Pet();
Pet p2 = new Pet( 30);
Console.WriteLine(p1.Health);
Console.ReadKey();
}
}
class Pet
{
private int health;
private int fulllevel;
//构造函数没有返回值、方法名和类一致。
//当对象被创建的时候(new)构造函数被执行
//如果不指定构造函数,则类有一个默认的无参构造函数。
//如果指定了构造函数,则不再有默认的无参构造函数,
//如果需要无参构造函数,则需要自己来写。
public Pet()
{
this.health = 20;
this.fulllevel = 100;
}
public Pet(int health)
{
this.health = health;
}
public int Health
{
get
{
return health;
}
}
}
继承
定义类的时候不指定父类,则父类是Object类。Object类是任何类的直接或者间接父类。所有类都是Object的子类。
转换和as 转换的区别:如果转换失败()会报异常,而as则会返回null。
if (p1 is Chinese)//is运算符结果就是bool,表示是否是指定的类型。is用来判断变量指向的对象是否是指定的类型或者指定类型子类类型。as可以起到判断类型和转换的双重作用。
例:
static void Main(string[] args)
{
//Chinese c=new Chinese ();
//Japanese j = new Japanese();
//j.GuiZi();
Chinese c = new Chinese();
//Chinese c1 = c;//指向c1指向c
//c1.Run();//执行c1所指向的Run方法
//父类的变量可以指向子类的变量
Person p1 = c;//c从变量看是一个Chinese,所有可以把person标签贴到c上
c.Run();
p1 = new Japanese();
//p1从变量看是一个person,就不能擅自把Chinese标签贴到p1上
//Chinese c2 = (Chinese)p1;//如果转换失败则抛异常
// p1.GuiZi();//不能调用,只能调用Person类的方法
//把子类的变量指向父类的变量就不成功,必须显示转换
Chinese c3 = p1 as Chinese;
//as转换如果失败不报错,给值是null
if (p1 is Japanese)//is是运算结果为bool的运算符,表示p1指向的对象是否是指定的类型
{
Console.WriteLine("日本");
}
else if (p1 is Chinese)
{
Console.WriteLine("中国人");
}
if (p1 is Japanese)
{
Japanese jp = (Japanese)p1;
jp.GuiZi();
}
Japanese jp2 = p1 as Japanese;
if(jp2 !=null)
{
jp2.GuiZi();
}
Console.ReadKey();
}
class Person
{
public string Name
{
get;
set;
}
public string Age
{
get;
set;
}
public void Run()
{
Console.WriteLine("paopao");
}
}
class Chinese : Person //:后为父类的名字
{
public string HuKou
{
get;
set;
}
}
class Japanese : Person
{
public void GuiZi()
{
Console.WriteLine("小日本鬼子");
}
}