IT评测·应用市场-qidao123.com技术社区

标题: C#面向对象之访问限制,类基础,继续 [打印本页]

作者: 写过一篇    时间: 2024-12-4 07:12
标题: C#面向对象之访问限制,类基础,继续
1 访问限制

1.1 简介

C# 封装根据详细的必要,设置使用者的访问权限,并通过 访问修饰符 来实现。
一个 访问修饰符 定义了一个类成员的范围和可见性。C# 支持的访问修饰符如下所示:


2 类基础解说

2.1 类定义

类的定义是以关键字 class 开始,后跟类的名称。类的主体,包罗在一对花括号内。下面是类定义的一般形式:
  1. <access specifier> class  class_name
  2. {
  3.     // member variables
  4.     <access specifier> <data type> variable1;
  5.     <access specifier> <data type> variable2;
  6.     ...
  7.     <access specifier> <data type> variableN;
  8.     // member methods
  9.     <access specifier> <return type> method1(parameter_list)
  10.     {
  11.         // method body
  12.     }
  13.     <access specifier> <return type> method2(parameter_list)
  14.     {
  15.         // method body
  16.     }
  17.     ...
  18.     <access specifier> <return type> methodN(parameter_list)
  19.     {
  20.         // method body
  21.     }
  22. }
复制代码
注意:

2.2 构造函数

2.2.1 构造函数

类的 构造函数 是类的一个特别的成员函数,当创建类的新对象时执行。
构造函数的名称与类的名称完全类似,它没有任何返回范例。
默认的构造函数没有任何参数。但是如果必要一个带有参数的构造函数可以有参数,这种构造函数叫做参数化构造函数。可以在创建对象的同时给对象赋初始值
  1. using System;
  2. namespace LineApplication
  3. {
  4.    class Line
  5.    {
  6.       private double length;   // 线条的长度
  7.       public Line(double len)  // 参数化构造函数
  8.       {
  9.          Console.WriteLine("对象已创建,length = {0}", len);
  10.          length = len;
  11.       }
  12.       public void setLength( double len )
  13.       {
  14.          length = len;
  15.       }
  16.       public double getLength()
  17.       {
  18.          return length;
  19.       }
  20.       static void Main(string[] args)
  21.       {
  22.          Line line = new Line(10.0);
  23.          Console.WriteLine("线条的长度: {0}", line.getLength());
  24.          // 设置线条长度
  25.          line.setLength(6.0);
  26.          Console.WriteLine("线条的长度: {0}", line.getLength());
  27.          Console.ReadKey();
  28.       }
  29.    }
  30. }
复制代码
2.2.2 静态构造函数

在 C# 中存在一种叫做静态构造函数(static constructor)的特别构造函数,虽然它与实例构造函数不同,但依然被称为构造函数,且可以使用 static 修饰。静态构造函数用于初始化静态成员,并在类被加载时主动执行一次。
静态构造函数和静态方法或字段类似,属于类自己,而不属于类实例
静态构造函数的特点:

  1. using System;
  2. public class MyClass
  3. {
  4.     // 静态字段
  5.     public static int StaticValue;
  6.     // 静态构造函数
  7.     static MyClass()
  8.     {
  9.         Console.WriteLine("静态构造函数被调用");
  10.         StaticValue = 42; // 初始化静态字段
  11.     }
  12.     // 实例构造函数
  13.     public MyClass()
  14.     {
  15.         Console.WriteLine("实例构造函数被调用");
  16.     }
  17. }
  18. public class Program
  19. {
  20.     public static void Main()
  21.     {
  22.         Console.WriteLine("第一次创建对象");
  23.         MyClass obj1 = new MyClass();
  24.         Console.WriteLine("第二次创建对象");
  25.         MyClass obj2 = new MyClass();   
  26.         Console.WriteLine($"StaticValue = {MyClass.StaticValue}");
  27.     }
  28. }
  29. 结果:
  30. 第一次创建对象
  31. 静态构造函数被调用
  32. 实例构造函数被调用
  33. 第二次创建对象
  34. 实例构造函数被调用
  35. StaticValue = 42
复制代码
2.2.3 初始化次序

在 C# 中,静态初始化和继续的初始化遵照肯定的次序。对于有继续关系的类,在初始化时遵照以下规则:

注意:

  1. using System;
  2. public class BaseClass
  3. {
  4.     // 静态构造函数
  5.     static BaseClass()
  6.     {
  7.         Console.WriteLine("BaseClass: 静态构造函数");
  8.     }
  9.     // 实例构造函数
  10.     public BaseClass()
  11.     {
  12.         Console.WriteLine("BaseClass: 实例构造函数");
  13.     }
  14. }
  15. public class DerivedClass : BaseClass
  16. {
  17.     // 静态构造函数
  18.     static DerivedClass()
  19.     {
  20.         Console.WriteLine("DerivedClass: 静态构造函数");
  21.     }
  22.     // 实例构造函数
  23.     public DerivedClass()
  24.     {
  25.         Console.WriteLine("DerivedClass: 实例构造函数");
  26.     }
  27. }
  28. public class Program
  29. {
  30.     public static void Main()
  31.     {
  32.         Console.WriteLine("第一次创建 DerivedClass 对象");
  33.         DerivedClass obj1 = new DerivedClass();
  34.         Console.WriteLine("\n第二次创建 DerivedClass 对象");
  35.         DerivedClass obj2 = new DerivedClass();
  36.     }
  37. }
  38. 结果:
  39. 第一次创建 DerivedClass 对象
  40. BaseClass: 静态构造函数
  41. DerivedClass: 静态构造函数
  42. BaseClass: 实例构造函数
  43. DerivedClass: 实例构造函数
  44. 第二次创建 DerivedClass 对象
  45. BaseClass: 实例构造函数
  46. DerivedClass: 实例构造函数
复制代码
2.2.4 对象初始化器

在 new 关键字后使用大括号 {} 进行对象初始化。这种方式称为对象初始化器(object initializer),允许在创建对象时直接初始化其属性或字段。使用对象初始化器的语法简洁、方便,特别得当在构造函数之外进行属性的直接赋值。
对象初始化器的特点:

适用场景:

对象示例:
  1. public class Person
  2. {
  3.     public string Name { get; set; }
  4.     public int Age { get; set; }
  5. }
  6. public class Program
  7. {
  8.     public static void Main()
  9.     {
  10.         // 使用对象初始化器创建并初始化对象
  11.         Person person = new Person
  12.         {
  13.             Name = "Alice",
  14.             Age = 30
  15.         };
  16.         Console.WriteLine($"Name: {person.Name}, Age: {person.Age}");
  17.     }
  18. }
复制代码
集合示例:
  1. using System;
  2. using System.Collections.Generic;
  3. public class Person
  4. {
  5.     public string Name { get; set; }
  6.     public int Age { get; set; }
  7. }
  8. public class Program
  9. {
  10.     public static void Main()
  11.     {
  12.         List<Person> people = new List<Person>
  13.         {
  14.             new Person { Name = "Alice", Age = 30 },
  15.             new Person { Name = "Bob", Age = 25 },
  16.             new Person { Name = "Charlie", Age = 35 }
  17.         };
  18.         foreach (var person in people)
  19.         {
  20.             Console.WriteLine($"Name: {person.Name}, Age: {person.Age}");
  21.         }
  22.     }
  23. }
复制代码
2.3 析构函数

类的 析构函数 是类的一个特别的成员函数,当类的对象超出范围时执行。
析构函数的名称是在类的名称前加上一个波浪形(~)作为前缀,它不返回值,也不带任何参数。
析构函数用于在竣事程序(好比关闭文件、开释内存等)之前开释资源。析构函数不能继续或重载。
  1. using System;
  2. namespace LineApplication
  3. {
  4.    class Line
  5.    {
  6.       private double length;   // 线条的长度
  7.       public Line()  // 构造函数
  8.       {
  9.          Console.WriteLine("对象已创建");
  10.       }
  11.       ~Line() //析构函数
  12.       {
  13.          Console.WriteLine("对象已删除");
  14.       }
  15.       public void setLength( double len )
  16.       {
  17.          length = len;
  18.       }
  19.       public double getLength()
  20.       {
  21.          return length;
  22.       }
  23.       static void Main(string[] args)
  24.       {
  25.          Line line = new Line();
  26.          // 设置线条长度
  27.          line.setLength(6.0);
  28.          Console.WriteLine("线条的长度: {0}", line.getLength());         
  29.       }
  30.    }
  31. }
复制代码
2.4 类的静态成员

我们可以使用 static 关键字把类成员定义为静态的。当我们声明一个类成员为静态时,意味着无论有多少个类的对象被创建,只会有一个该静态成员的副本。
关键字 static 意味着类中只有一个该成员的实例。静态变量用于定义常量,因为它们的值可以通过直接调用类而不必要创建类的实例来获取。静态变量可在成员函数或类的定义外部进行初始化。也可以在类的定义内部初始化静态变量。
也可以把一个成员函数声明为 static。如许的函数只能访问静态变量。静态函数在对象被创建之前就已经存在。
  1. using System;
  2. namespace StaticVarApplication
  3. {
  4.     class StaticVar
  5.     {
  6.        public static int num;
  7.         public void count()
  8.         {
  9.             num++;
  10.         }
  11.         public static int getNum()
  12.         {
  13.             return num;
  14.         }
  15.     }
  16.     class StaticTester
  17.     {
  18.         static void Main(string[] args)
  19.         {
  20.             StaticVar s = new StaticVar();
  21.             s.count();
  22.             s.count();
  23.             s.count();                  
  24.             Console.WriteLine("变量 num: {0}", StaticVar.getNum());
  25.             Console.ReadKey();
  26.         }
  27.     }
  28. }
复制代码
2.5 匿名对象

2.5.1 定义

在 C# 中,匿名对象(anonymous type)是一种没有明确定义类名称的对象,通常在不必要为对象创建完备的类定义时使用。匿名对象的典范场景是暂时存储数据,特别是在查询结果和暂时数据封装时使用。
匿名对象的特点:

使用场景:

注意:

2.5.2 匿名对象的创建

匿名对象使用 new 关键字创建,属性名和属性值直接在大括号 {} 中指定。因为匿名对象没有类名,以是只能通过属性名访问其数据成员。
示例
  1. var person = new { Name = "Alice", Age = 30 };
  2. Console.WriteLine($"Name: {person.Name}, Age: {person.Age}");
复制代码
在上面的代码中,person 是一个匿名对象,包罗两个属性 Name 和 Age。使用 var 关键字声明匿名对象的变量范例,因为匿名范例没有显式的范例名称。
LINQ 查询示例
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. public class Program
  5. {
  6.     public static void Main()
  7.     {
  8.         List<Person> people = new List<Person>
  9.         {
  10.             new Person { Name = "Alice", Age = 30 },
  11.             new Person { Name = "Bob", Age = 25 },
  12.             new Person { Name = "Charlie", Age = 35 }
  13.         };
  14.         // 使用 LINQ 查询生成匿名对象列表
  15.         var selectedPeople = from p in people
  16.                              where p.Age > 28
  17.                              select new { p.Name, p.Age };
  18.         foreach (var person in selectedPeople)
  19.         {
  20.             Console.WriteLine($"Name: {person.Name}, Age: {person.Age}");
  21.         }
  22.     }
  23. }
  24. public class Person
  25. {
  26.     public string Name { get; set; }
  27.     public int Age { get; set; }
  28. }
复制代码
3 继续

继续是面向对象程序设计中最重要的概念之一。继续允许我们根据一个类来定义另一个类,这使得创建和维护应用程序变得更轻易。
继续的思想实现了 属于(IS-A) 关系
3.1 基类和派生类

一个类可以继续自另一个类,被称为基类(父类)和派生类(子类)。
C# 不支持类的多重继续,但支持接口的多重继续,一个类可以实现多个接口。
概括来说:一个类可以继续多个接口,但只能继续自一个类。
派生类会继续基类的成员(字段、方法、属性等),除非它们被明确地标志为私有(private)。
派生类可以通过关键字base来调用基类的构造函数和方法。
  1. class BaseClass
  2. {
  3.     public void SomeMethod()
  4.     {
  5.         // Method implementation
  6.     }
  7. }
  8. class DerivedClass : BaseClass
  9. {
  10.     public void AnotherMethod()
  11.     {
  12.         // Accessing base class method
  13.         base.SomeMethod();      
  14.         // Method implementation
  15.     }
  16. }
复制代码
3.2 基类初始化

派生类继续了基类的成员变量和成员方法。因此父类对象应在子类对象创建之前被创建。可以在成员初始化列表中进行父类的初始化。
含有父类的初始化语法:public SonClass(string str) : base(s)
  1. using System;
  2. namespace RectangleApplication
  3. {
  4.    class Rectangle
  5.    {
  6.       // 成员变量
  7.       protected double length;
  8.       protected double width;
  9.       public Rectangle(double l, double w)
  10.       {
  11.          length = l;
  12.          width = w;
  13.       }
  14.       public double GetArea()
  15.       {
  16.          return length * width;
  17.       }
  18.       public void Display()
  19.       {
  20.          Console.WriteLine("长度: {0}", length);
  21.          Console.WriteLine("宽度: {0}", width);
  22.          Console.WriteLine("面积: {0}", GetArea());
  23.       }
  24.    }//end class Rectangle  
  25.    class Tabletop : Rectangle
  26.    {
  27.       private double cost;
  28.       public Tabletop(double l, double w) : base(l, w)
  29.       { }
  30.       public double GetCost()
  31.       {
  32.          double cost;
  33.          cost = GetArea() * 70;
  34.          return cost;
  35.       }
  36.       public void Display()
  37.       {
  38.          base.Display();
  39.          Console.WriteLine("成本: {0}", GetCost());
  40.       }
  41.    }
  42.    class ExecuteRectangle
  43.    {
  44.       static void Main(string[] args)
  45.       {
  46.          Tabletop t = new Tabletop(4.5, 7.5);
  47.          t.Display();
  48.          Console.ReadLine();
  49.       }
  50.    }
  51. }
复制代码
3.3 Partial类

3.3.1 定义

partial 关键字用于将一个类、结构或方法的定义拆分到多个文件中。通过这种方式,多个开发者可以同时在不同文件中对同一个类进行扩展,而不必要归并代码到一个文件中。partial 提供了灵活性和可维护性,尤其得当复杂项目和主动生成代码的场景,可以减少派生类
partial的用途:

使用规则:

3.3.2 partial 类

假设你有一个类 Person,可以将其定义拆分到两个文件中。
文件 1: Person.Part1.cs
  1. namespace MyApplication
  2. {
  3.     public partial class Person
  4.     {
  5.         public string FirstName { get; set; }
  6.         public string LastName { get; set; }
  7.     }
  8. }
复制代码
文件 2: Person.Part2.cs
  1. namespace MyApplication
  2. {
  3.     public partial class Person
  4.     {
  5.         public string GetFullName()
  6.         {
  7.             return $"{FirstName} {LastName}";
  8.         }
  9.     }
  10. }
复制代码
使用代码:
  1. using MyApplication;
  2. class Program
  3. {
  4.     static void Main()
  5.     {
  6.         Person person = new Person
  7.         {
  8.             FirstName = "John",
  9.             LastName = "Doe"
  10.         };
  11.         Console.WriteLine(person.GetFullName());
  12.     }
  13. }
  14. 输出:
  15. John Doe
复制代码
3.3.3 partial 方法

除了类和结构,C# 还支持 partial 方法,允许方法声明和实现分开。
文件 1: PartialMethodExample.Part1.cs
  1. public partial class PartialMethodExample
  2. {
  3.     partial void OnAction(); // 声明部分方法
  4.     public void TriggerAction()
  5.     {
  6.         OnAction(); // 调用部分方法
  7.     }
  8. }
复制代码
文件 2: PartialMethodExample.Part2.cs
  1. public partial class PartialMethodExample
  2. {
  3.     partial void OnAction() // 实现部分方法
  4.     {
  5.         Console.WriteLine("Partial method executed.");
  6.     }
  7. }
复制代码
使用代码:
  1. class Program
  2. {
  3.     static void Main()
  4.     {
  5.         PartialMethodExample example = new PartialMethodExample();
  6.         example.TriggerAction();
  7.     }
  8. }
  9. 输出:
  10. Partial method executed.
复制代码
注意:


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 IT评测·应用市场-qidao123.com技术社区 (https://dis.qidao123.com/) Powered by Discuz! X3.4