微信公众号已开通,搜索微信公众号:程序喵星人。点击关注^_^
6.面向对象编程基础
1.类的概念
1.什么是类?
类是一组具有相同数据结构和相同操作的对象的集合。类是对一系列具有相同性质的对象的抽象,是对对象共同特征的描述。
2.对象和类之间的关系?
对象可以是现实生活中的一个物理对象,还可以是某一类概念实体的实例。例如:一辆汽车、一个人、一本书、乃至一种语言、一个图形、一种管理方式,都可以最为一个对象。
类是一组具有相同数据结构和相同操作的对象的集合。类是对一系列具有相同性质的对象的抽象,是对对象共同特征的描述。比如每一辆汽车是一个对象的话,所有的汽车可以作为一个模板,我们就定义汽车这个类。
可以使用类的定义实例化对象,这表示创建该类的一个实例。
从类定义中产生对象,必须有建立实例的操作。
2.类的定义
1.类的定义包括类头和类体两部分,其中类体用一对大花括号{ }括起来,类体用于定义该类的成员。
语法形式:
{
[类成员声明]
}
类成员由两部分组成,一个是类体中以类成员声明形式引入的类成员,另一个则是直接从它的基类继承而来的成员。类成员声明主要包括:常数声明、字段声明、属性声明、事件声明、索引器声明、运算符声明、构造函数声明、析构函数声明、静态构造函数、类型声明等。
2.字段声明
语法形式
[属性集信息] [字段修饰符] 类型 变量声明列表;
其中:
a.变量声明列表--标识符或用逗号 “,” 分隔的多个标识符,并且变量标识符还可用赋值号 “=” 设定初始值。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; // 类的概念和定义 namespace Lesson_24_1 { class Program { static void Main(string[] args) { // 对象,实际就是根据类来定义的 Student stu = new Student(); // 给对象变量赋值 stu.strName = "张三"; stu.intNum = 100001; stu.intAge = 16; Console.WriteLine( "学生的姓名是:" + stu.strName ); Console.WriteLine( "学生的学号是:" + stu.intNum ); Console.WriteLine( "学生的年龄是:" + stu.intAge ); } } // 类头 public class Student // 一般来说 C# 中定义类的时候,它的首字母是大写 { // 类体 // 定义三个变量,分别用于存储:姓名,学号,年龄 public string strName; public int intNum; public int intAge; } }
3.构造函数
构造函数是类的一种特殊方法,每次创建类的实例都会调用它。
[访问修饰符] 类名()
{
// 构造函数的主体
}
参数化构造函数
[访问修饰符] 类名(参数列表)
{
// 构造函数的主体
}
// 构造函数:用以实例化对象,并且在内存中分配存储数据的区域。
4.this关键字
this仅限于在构造函数、类的方法和类的实例中使用。
在类的构造函数中出现的 this 作为一个值类型,它表示正在构造的对象本身的引用。
在类的方法中出现的 this 作为一个值类型,它表示对调用该方法的对象的引用。
在结构的构造函数中出现的 this 作为一个变量类型,它表示对正在构造的结构的引用。
在结构的方法中出现的 this 作为一个变量类型,它表示对调用该方法的结构的引用。
经常在构造函数或者类方法中,如果传入参数和类字段同名,一定需要在类字段前加上 this。
Student.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Lesson_25_1 { public class Student { public string strName; public int intNum; public int intAge; // 在创建一个类的时候,系统会自动给分配一个无参的构造函数 public Student() { } // 有参构造函数 public Student ( string p_strName, int p_intNum, int p_intAge ) { // this 表示的是访问的是这个对象本身的数据 this.strName = p_strName; this.intNum = p_intNum; this.intAge = p_intAge; } } }
Program.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; // 类的构造函数 和 this namespace Lesson_25_1 { class Program { static void Main(string[] args) { // 根据类的构造函数去实例化一个对象 Student stu = new Student(); // new 就是在内存中分配存储数据区域。 // 根据有参构造函数来实例化对象 Student stu2 = new Student( "张三", 10001, 16 ); Console.WriteLine( "学生的名字:" + stu2.strName ); Console.WriteLine( "学生的学号:" + stu2.intNum ); Console.WriteLine( "学生的年龄:" + stu2.intAge ); } } }
5.方法
定义:表示定义对象的行为。
声明:
[访问修饰符] [返回类型] <方法名>( [参数列表] )
{
// 方法主体
}
[访问修饰符] 可选,默认情况下为 private。
如果不需要任何返回值,[返回类型]使用void数据。
6.方法的调用
语法
对象名.方法名( [参数列表] )
实例 点号 类中的方法
Person.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Lesson_26_1 { class Person { // 无参方法 public string say() { string strResult = "这是一个说话的方法"; return strResult; } // 在方法定义的时候,我们把方法里的参数叫形参 public string doWork( string p_strJob ) { string str = "我的工作是:" + p_strJob; return str; } // 无返回值方法 public void doWrite() { Console.WriteLine( "这是 Person 里面的 doWrite 方法" ); } } }
OperatorMethod.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Lesson_26_1 { class OperatorMethod { private int _intNumOne; private int _intNumTwo; public OperatorMethod( int p_intNumOne, int p_intNumTwo ) { this._intNumOne = p_intNumOne; this._intNumTwo = p_intNumTwo; } public int Add() { return this._intNumOne + this._intNumTwo; } public int Div() { return this._intNumOne - this._intNumTwo; } } }
Program.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; // 方法 和 方法调用 namespace Lesson_26_1 { class Program { static void Main(string[] args) { Person p = new Person(); Console.WriteLine( p.say() ); // 方法在调用的时候传递的参数叫实参 Console.WriteLine( p.doWork( "程序员" ) ); p.doWrite(); OperatorMethod opm = new OperatorMethod( 10, 20 ); Console.WriteLine( opm.Add() ); Console.WriteLine( opm.Div() ); } } }
7.方法的参数
C#中方法的参数有 四 种类型:
值参数,不含任何修饰符。
引用型参数,以 ref 修饰符声明。
输出参数,以 out 修饰符声明。
数组型参数,以 params 修饰符声明。
Person.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Lesson_27_1 { class Person { // 参数:值传递 public void changeAge( int p_intAge ) { p_intAge = p_intAge + 10; } // 参数:ref 传递 public void changeAge( ref int p_intAge ) { p_intAge = p_intAge + 10; } // 参数:out 传递 public void modifyAge( out int p_intAge ) { p_intAge = 23; } // params 表示参数是可变的数组 public void showInfo( string p_str, params int[] args ) { foreach ( int arg in args ) { Console.WriteLine( "年龄是:" + arg ); } } } }
Program.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; // 方法的参数 namespace Lesson_27_1 { class Program { static void Main(string[] args) { int intAge = 16; Person p = new Person(); // 值参数传递 p.changeAge( intAge ); // 值参数传递。实际是克隆了一份值,所以在 changeAge 内改变值,不会影响到原有的intAge值 Console.WriteLine( "值传递调用后 intAge = " + intAge ); // 16 // ref引用参数传递 // 使用 Ref 的数据在使用前必须赋值 int intAge2 = 16; // 使用ref 必须赋值 p.changeAge( ref intAge2); // ref 引用传递。实际是直接使用(不克隆),所以在 changeAge 内改变值,会影响到 intAge2 值 Console.WriteLine("ref引用传递调用后 intAge2 = " + intAge2); // 26 // out引用参数传递 // 使用 out 的数据在使用前可以赋值,也可以不赋值 int intAge3 = 16; // 使用 out 可以赋值 int intAge4; // 使用 out 可以不赋值 p.modifyAge( out intAge3 ); // out 引用传递。实际是直接使用(不克隆),所以在 modifyAge 内改变值,会影响到 intAge3 值 Console.WriteLine("out 引用传递调用后 有赋值的 intAge3 = " + intAge3 ); // 23 p.modifyAge( out intAge4 ); // out 引用传递。实际是直接使用(不克隆),所以在 modifyAge 内改变值,会影响到 intAge4 值 Console.WriteLine("out 引用传递调用后 无赋值的 intAge4 = " + intAge4 ); // 23 // params int[] intArgs = { 12, 13, 14, 15, 16 }; p.showInfo( "", intArgs ); int[] intArgs2 = { 6, 8, 13 }; p.showInfo("", intArgs2); } } }
8.静态类和静态方法
类的数据成员可以分:
静态字段;
实例字段;
静态字段是和类相关联的,不依赖特定对象的存在。
实例对象是和对象相关联的,访问实例字段依赖于实例的存在。
含义与用法:
通常若一个方法声明中含有 static 修饰符,则表明这个方法是静态方法。同时说明它只对这个类中的静态成员操作,不可以直接访问实例字段。
若一个方法声明中不包含 static 修饰符,则该方法是一个实例方法。一个实例方法的执行与特定对象关联,所以需要一个对象存在。实例方法可以直接访问静态字段和实例字段。
Person.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Lesson_28_1 { // public 修饰符表示 这个类可以在 本命名空间和其他命名空间 中使用 public class Person { // static 表明是一个静态的字段,所谓的静态字段是长期驻留在内存中的。 public static string s_strCountry; // 方法加上 static 修饰符后,就是一个 静态方法。 public static void changeCountry() { Person.s_strCountry = "德国"; } // 实例字段 public string strName; public Person( string p_strName ) { this.strName = p_strName; } // 实例方法 public void showInfo() { Console.WriteLine( "name = " + this.strName ); Console.WriteLine( "country = " + s_strCountry ); // 实例方法中可以访问 静态字段 } // 静态方法 public static void showStaticInfo() { // Console.WriteLine( "static func name = " + this.strName ); // 静态方法中,无法访问 实例字段 Console.WriteLine( "static func country = " + s_strCountry ); } } }
OperatorMethod.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Lesson_28_1 { // 加上 static 后,这个类就是一个静态类,静态类不能实例化对象。 public static class OperatorMethod { // public int intResult; // 在静态类中不允许出现 实例字段 和 实例方法。 public static int s_intResult; // 静态字段 public static int Add( int a, int b ) // 静态方法 { s_intResult = a + b; return s_intResult; } } }
Program.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; // 静态类 和 静态方法 namespace Lesson_28_1 { class Program { static void Main(string[] args) { Person.s_strCountry = "中国"; // 不需要实例对象,直接使用 类 访问 静态字段; Console.WriteLine( Person.s_strCountry ); Person.changeCountry(); // 不需要实例对象,直接使用 类 访问 静态方法; Console.WriteLine( Person.s_strCountry ); Person p = new Person( "张三" ); // 创建一个实例对象 p.showInfo(); // 通过 实例对象 访问 实例方法 Person.showStaticInfo(); // 通过 类 方位 静态方法 } } }
9.方法的重载
方法重载,必须要求:
1.相同的方法名;
2.相同的返回值类型;
重载方法有两种方式:
1.指定不同个数的参数;
2.指定不同类型的参数;
方法重载跟 形参字段名字 无关;
比如:
a( int i );
a( int m );
两个方法是同一个,形参字段名(i 和 m)不会影响导致方法不一致。
10.命名空间的概念
语法:
namespace 命名空间的名称
{
// 该名称空间的所有的类都放在这里
}
命名空间:Lesson_29_1
Person.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; // 方法重载 和 命名空间 namespace Lesson_29_1 { // public 修饰符,表示类可以在 同一命名空间 和 其他命名空间 中使用。 // internal 修饰符,表示类只能在 同一命名空间 中使用。 public class Person { // 方法重载必须要求:方法的名字 和 返回类型 必须一致。 // 充话费的方法 public void chongHuaFei( string str, double d ) { Console.WriteLine( "给:" + str + "充了:" + d ); } // 方法重载--参数个数不同 public void chongHuaFei( string str ) { Console.WriteLine( "充话费" ); } // 方法重载--参数类型不同 public void chongHuaFei( double d ) { Console.WriteLine( "充了:" + d ); } } }
Program.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; // 方法重载 和 命名空间 // 命名空间主要用来区分类,比如:有两个 Person 类,分别在不同的命名空间中。 namespace Lesson_29_1 { class Program { static void Main(string[] args) { Person p = new Person(); p.chongHuaFei( 12 ); p.chongHuaFei( "张三" ); p.chongHuaFei( "李四", 23 ); } } }
命名空间:Test
Person.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Test { class Person { } }
Program.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Lesson_29_1; namespace Test { class Program { static void Main(string[] args) { // 在 Test 命名空间中,也有一个 Person 类 // 现在需要在 这里 使用 Lesson_29_1 命名空间中的 Person 类 // 步骤 // 1.在资源管理器中,选择 Test -> 引用 -> 右键,选择 “添加引用” -> 选择 "项目" -> "Lesson_29_1" // 2.如本例中,加入:using Lesson_29_1; // 3.使用: Lesson_29_1.Person p = new Lesson_29_1.Person(); Lesson_29_1.Person p = new Lesson_29_1.Person(); } } }