面向对象的基础内容
1.面向对象的概念
说到面向对象,不由自主的想起面向过程,面向过程就是通过分析问题的步骤,然后通过步骤一步一步完成,使用的时候就分别调用函数就可以了。而面向对象就是把要解决的问题按照一定的规则划分独立的对象,然后分别调用对象的方法去调用来解决问题。这样一来,如果当程序需要修改一些内容时,可以通过修改个别对象就可以实现了,也使得我们的程序更加便利快捷。
2.面向对象的三大性质
面向对象有三大性质:封装性,继承性,多态性
2.1封装性
封装是面向对象的核心,它把对象的特征和行为封装起来,不需要让外界知道具体的过程。
比如你打开游戏想登录,你只需要点登录的按钮即可,不需知道游戏登陆内部的工作原理。
封装还可以通过访问修饰符来对对象的特征和行为进行访问,提高代码的安全性。
2.2继承性
继承是类与类之间的继承,常见的是子类继承父类,子类可以通过继承,具备父类所有的特征和行为,也可以在继承父类的基础上进行扩展。
比如一个代表英雄的类,具备它的特征和行为,而表示战士的不仅仅包括他的特征和行为,还可以添加他独特的技能,这个时候,就可以让战士继承英雄的类,让他具备英雄原有的特征和行为,同时也可以添加它独特的技能。
继承不仅仅提高了代码的复用率,还可以大大的减少了程序员的时间。
2.3多态性
多态指的是一类事物有多种形态,在同一操作作用在不一样的对象中得到的结果也不同。
比如这个单词“tolerance ”,在心里学上是“包容” 的意思,在理工科上就是 “公差”的意思。
多态可以提高代码的的灵活性
3.类与对象
类与对象,其中类是对某一事物的抽象描述,而对象用于表示现实中事物的个体。
图3-1 类与对象的关系演示
在图3-1中,我们可以把玩具模型当作一个类,将玩具看作对象,从玩具模型和玩具中我们可以得知。类是对象的模板,对象是类的一个实例,并且一个类可以有多个对象。
3.1类的定义
在程序中创建对象,首先定义一个类(定义类需要用到关键词class声明),类是对象的抽象,可以描述对象的特征和行为。
下面将演示如何创建一个类,先在解决方案consoleApp1中创建一个项目名ConsoleApp1控制台应用程序,右击改项目,在选择【添加(D)】找到【类】进行添加。如图所示:
代码片
namespace ConsoleApp1
{
public class Class //定义Class类,关键词public为修饰符
{
public int age; //定义int 类型的age
public void Speak() //定义speak()方法
{
Console.WriteLine("大家好,我今年"+age+"岁!");
}
}
}
以上代码定义了一个class类,其中class是类名,age是字段,Speak()方法。在Speak()方法中可以直接访问age字段。
3.2对象的创建和使用
应用程序想要完成具体的功能,仅有类是不够的,还需要根据类创建实例对象,在C#程序使用关键词new来创建对象,具体格式如下:
类名 对象名称 = new 类名();
例如创建Class类的实例,具体代码如下:
Class m=new Class();
上述代码中,"new Class"用于Class类的一个实例对象,"Class m"则是声明了一个Class类的变量m,中间的等于用来将Class对象在内的地址赋予给变量m。
创建Class对象后,可以通过对象的引用来访问对象所有的成员,具体格式如下:
对象引用.对象成员
例如创建Class类的实例,具体代码如下:
m.age=18;
m.Speak();
运行结果如下:
3.3类的设计
在C#中,对象是类实例出来的,所以类的设计非常重要,下面让我们通过一个案例来详细学习如何设计一个类。
假如要在程序中描述一个学校学生的信息,首先要设计一个学生(Student)的类,在这个类中定义两个个字段name和class1分别表示学生的名字和班级号,定义一个introduce()方法来让学生自我介绍。
根据条件,先设计Student类,解决方案consoleApp2中创建一个项目名ConsoleApp2控制台应用程序,右击改项目,在选择【添加(D)】找到【类】进行添加。在Student.cs中编写以下代码:
代码片
namespace ConsoleApp2
{
public class Student //定义Student类,关键词public为修饰符
{
public string name; //定义string类型的name
public int class1; //定义int 类型的class
public void introduce()
//定义speak()方法 在中打印name和class1的值
{
Console.WriteLine("老师同学好!",我叫"+name+",所在班级是"+class1+");
}
}
}
上述代码中,创建了一个Student的类,改类中定义了两个字段nama和class,其中name字段为string类型,C#中使用string类型的变量来引用字符串,例如:
string name=“王大福”;
3.4类的属性
通过上面的学校可知,字段在赋值不能有效的控制,例如把学生的班级赋值为-2,会导致不符合逻辑的代码,接下来演示一个例子,具体代码如下:
代码片
namespace ConsoleApp2
{
internal class Program
{
static void Main(string[] args)
{
Student stu = new Student(); //创建学生Studentd对象
stu.name = "王大福"; //对name赋值
stu.class1 = -2; //对class1赋值
stu.introduce(); //调用introduce()方法
Console.ReadLine();
}
}
}
结果如下:
在代码中,将sud的对象的字段class1赋值一个负数是不符合实际情况的,使用为了避免这种情况的出现,在设计一个类时,应该对字段的访问进行一些限定,不可以被外界随意访问,这时候就可以使用属性。
在程序中可以使用修饰符private并通过get访问器和set访问器来对字段进行读写操作,从而保护类内部数据的安全。可以将属性分为以下三种:
3.4.1读写属性
读写属性即get访问器、set访问器的属性,具体格式如下:
public [数据类型] [属性名] {
get { //返回参数值 }
set { //设置隐式参数value个字段赋值 }
}
3.4.2只读属性
只读属性即可get访问器的属性,具体格式如下:
public [数据类型] [属性名] {
get { //返回参数值 }
}
3.4.3只写属性
只写属性即可get访问器的属性,具体格式如下:
public [数据类型] [属性名] {
set { //设置隐式参数value个字段赋值 }
}
以上的三种属性中,读写属性是最常见的。如果这三个属性不需要书写任何逻辑,则可简写成自动属性。在get访问器和set访问器中后面不加大括号,后面直接加";"。
代码片
namespace ConsoleApp1
{
public class Student
{
private string name = "王大福"; //定义私有字段name
public string Name //定义共有字段Name封装name
{
get { return name; } //只读属性
}
private int class1; //定义私有字段class1
public int Class1 //定义共有字段Class1封装class1
{
get { return class1; } //读写属性
set {
if (value <= 0) //下面对传入的值进行判断
{
Console.WriteLine("班级号不合法...");
}
else
{
class1 = value; //为字段class1赋值
}
}
}
public string Gender //定义表示性别的自动属性
{
get;
set;
}
public void introduce() //定义介绍的introduce() 方法
{
Console.WriteLine("老师同学好!我叫"+name+", 我是"+Gender+"我所在班级是"+class1+"班");
}
}
}
//在主函数调用
internal class Program
{
static void Main(string[] args)
{
Student stu = new Student(); //创建Student对象
stu.Class1 = -2;
stu.Gender="男生"; //对class1属性赋值
stu.introduce(); //调用对象的方法
Console.ReadLine();
}
}
结果如下:
以上代码,定义了Student类,其中使用关键词private将字段name、class1,声明为私有,并对外界提供相应属性Name,Class1,进行用于封装name、class1字段。Gender属性为自动属性。
在主函数中创建Student对象,把属性Class1赋值-2,由于赋予属性Class的值小于0,判断赋值的内容不符合,因此会打印“班级号不合法…”的信息,class1字段就会被默认初始化。
3.5访问修饰符
在3.1中出现的关键词public都属于修饰符,用于限定外界对类和方法的访问权限,具体修饰符如下:
修饰符 | 内容 |
---|---|
public | 最高访问级别,访问不受限制 |
protected | 保护访问级别,受保护的成员可由自身及派生类访问 |
internal | 内部访问级别,只有子同一程序集中,内部类型或成员才可以访问 |
protected internal | 内部保护级别,访问仅于当前程序集,可由自身及派生类访问 |
private | 私有访问,最低访问级别,私有成员只有在声明它们的类和结构中才可访问 |