⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 修饰符.txt

📁 C#实验报告 C#实验报告 C#实验报告 C#实验报告 C#实验报告 C#实验报告 C#实验报告
💻 TXT
📖 第 1 页 / 共 2 页
字号:
重写声明不能更改虚方法的可访问性。重写方法和虚方法必须具有相同的访问级修饰符。
不能使用下列修饰符修改重写方法:
new   static    virtual   abstract
重写属性声明必须指定与继承属性完全相同的访问修饰符、类型和名称,并且重写属性必须是虚拟的、抽象的或重写的。
有关访问基类成员的更多信息,请参见 7.5.8 基访问。
有关重写方法的更多信息,请参见 10.5.4 重写方法。
示例
请参见 virtual 关键字的示例。
从具有重写方法的派生类中,仍然可以通过使用 base 关键字来访问同名的重写基方法。例如,如果有虚方法 MyMethod() 和派生类上的重写方法,就可以通过下列调用从派生类访问此虚方法:
base.MyMethod()
将此方法与使用范围解析运算符 (::) 和基类名的 C++ 方法进行比较,例如:
My_Base_Class_Name::MyMethod()
示例
在该示例中,有一个基类 Square 和一个派生类 Cube。因为立方体的面积是六个正方形的面积之和,因此可以通过调用基类上的 Area() 方法来计算。
// cs_override_keyword.cs
// Calling overriden methods from the base class
using System;
class TestClass 
{
   public class Square 
   {
      public double x;

      // Constructor:
      public Square(double x) 
      {
         this.x = x;
      }

      public virtual double Area() 
      {
         return x*x; 
      }
   }

   class Cube: Square 
   {
      // Constructor:
      public Cube(double x): base(x) 
      {
      }

      // Calling the Area base method:
      public override double Area() 
      {
         return (6*(base.Area())); 
      }
   }

   public static void Main()
   {
      double x = 5.2;
      Square s = new Square(x);
      Square c = new Cube(x);
      Console.WriteLine("Area of Square = {0:F2}", s.Area());
      Console.WriteLine("Area of Cube = {0:F2}", c.Area());
   }
}
输出
Area of Square = 27.04
Area of Cube = 162.24
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
extern 修饰符

在方法声明中使用 extern 修饰符指示在外部实现方法。外部修饰符的常见用法是与 DllImport 属性一起使用。(有关更多信息,请参见 DllImportAttribute 类。)
将 abstract 和 extern 修饰符一起使用来修改同一成员是错误的。使用 extern 修饰符意味着方法在 C# 代码的外部实现,而使用 abstract 修饰符意味着在此类中未提供此方法的实现。
因为外部方法声明不提供实实现,所以没有方法体;此方法声明只是以一个分号结束,并且在签名后没有大括号 ({ })。例如:
public static extern int MyMethod(int x);
注意   extern 关键字在使用上比在 C++ 中有更多的限制。若要与 C++ 关键字比较,请参见 C++ Language Reference 中的使用 extern 指定链接。
有关外部方法的更多信息,请参见 10.5.7 外部方法。
有关属性的更多信息,请参见 17. 属性。
示例
在该示例中,程序接收来自用户的字符串并将该字符串显示在消息框中。程序使用从 User32.dll 库导入的 MessageBox 方法。
using System;
using System.Runtime.InteropServices;
class MyClass 
{
   [DllImport("User32.dll")]
   public static extern int MessageBox(int h, string m, string c, int type);

   public static int Main() 
   {
      string myString; 
      Console.Write("Enter your message: ");
      myString = Console.ReadLine();
      return MessageBox(0, myString, "My Message Box", 0);
   }
}
运行示例
Enter your message: Where do you want to go today?
输入以上文本后,屏幕上将弹出一个包含该文本的消息框。
示例
该示例使用两个文件 CM.cs 和 Cmdll.c 来说明 extern。C 文件是从 C# 程序中调用的外部 DLL。
文件:Cmdll.c
// cmdll.c
// compile with: /LD /MD
int __declspec(dllexport) MyMethod(int i)
{
   return i*10;
}
文件:CM.cs
// cm.cs
using System;
using System.Runtime.InteropServices;
public class MyClass 
{
   [DllImport("Cmdll.dll")]
   public static extern int MyMethod(int x);
   public static void Main() 
   {
      Console.WriteLine("MyMethod() returns {0}.", MyMethod(5));
   }
}
输出
MyMethod() returns 50.
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
static 修饰符

使用 static 修饰符声明属于类型本身而不是属于特定对象的静态成员。static 修饰符可用于字段、方法、属性、运算符、事件和构造函数,但不能用于索引器、析构函数或类型。
备注
常数或者类型声明隐式地是静态成员。 
不能通过实例引用静态成员。然而,可以通过类型名称引用它。例如,请考虑以下类: 
public class MyBaseC 
{
   public struct MyStruct {
      public static int x = 100;
   }
}
若要引用静态成员 x,请使用完全限定名(除非可从相同范围访问): 
MyBaseC.MyStruct.x
尽管类的实例包含该类所有实例字段的单独副本,但每个静态字段只有一个副本。 
不可以使用 this 引用静态方法或属性访问器。 
注意   static 关键字在使用上比在 C++ 中有更多限制。若要与 C++ 关键字进行比较,请参见 C++ Language Reference 中的 static。
为了说明实例成员,请看一个表示公司雇员的类。假设该类包含一种对雇员计数的方法和一个存储雇员数的字段。该方法和字段都不属于任何实例雇员,而是属于公司类。因此,应该将它们声明为此类的静态成员。
有关构造函数的更多信息,请参见 10.10 实例构造函数。
示例
该示例读取新雇员的名称和 ID,逐个增加雇员计数器并显示新雇员的有关信息以及新的雇员数。为简单起见,该程序从键盘读取当前的雇员数。在实际的应用中,应从文件读取此信息。
// cs_static_keyword.cs
// Static members
using System;
public class Employee 
{
   public string id;
   public string name;

   public Employee () 
   {
   }

   public Employee (string name, string id) 
   {
      this.name = name;
      this.id = id;
   } 

   public static int employeeCounter;

   public static int AddEmployee() 
   {
      return ++employeeCounter;
   }
}

class MainClass: Employee 
{
   public static void Main() 
   {
      Console.Write("Enter the employee's name: ");
      string name = Console.ReadLine();
      Console.Write("Enter the employee's ID: ");      
      string id = Console.ReadLine();
      // Create the employee object:
      Employee e = new Employee (name, id);
      Console.Write("Enter the current number of employees: ");
      string n = Console.ReadLine();
      Employee.employeeCounter = Int32.Parse(n);
      Employee.AddEmployee();
      // Display the new information:
      Console.WriteLine("Name: {0}", e.name);
      Console.WriteLine("ID:   {0}", e.id);
      Console.WriteLine("New Number of Employees: {0}",
                         Employee.employeeCounter);
   }
}
输入
Tara Strahan
AF643G
15
示例输出
Enter the employee's name: Tara Strahan
Enter the employee's ID: AF643G
Enter the current number of employees: 15
Name: Tara Strahan
ID:   AF643G
New Number of Employees: 16
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
virtual  修饰符 

virtual 关键字用于修改方法或属性的声明,在这种情况下,方法或属性被称作虚拟成员。虚拟成员的实现可由派生类中的重写成员更改。

调用虚方法时,将为重写成员检查该对象的运行时类型。将调用大部分派生类中的该重写成员,如果没有派生类重写该成员,则它可能是原始成员。(有关运行时类型和大部分派生实现的更多信息,请参见 10.5.3 虚拟方法。)

默认情况下,方法是非虚拟的。不能重写非虚方法。

不能将 virtual 修饰符与以下修饰符一起使用:

static   abstract   override

除了声明和调用语法不同外,虚拟属性的行为与抽象方法一样。 

在静态属性上使用 virtual 修饰符是错误的。 
通过包括使用 override 修饰符的属性声明,可在派生类中重写虚拟继承属性。 
有关虚方法的更多信息,请参见 10.5.3 虚拟方法。

示例
在该示例中,Dimensions 类包含 x 和 y 两个坐标和 Area() 虚方法。不同的形状类,如 Circle、Cylinder 和 Sphere 继承 Dimensions 类,并为每个图形计算表面积。每个派生类都有各自的 Area() 重写实现。根据与此方法关联的对象,通过调用正确的 Area() 实现,该程序为每个图形计算并显示正确的面积。

// cs_virtual_keyword.cs
// Virtual and override
using System;
class TestClass 
{
   public class Dimensions 
   {
      public const double pi = Math.PI;
      protected double x, y;
      public Dimensions() 
      {
      }
      public Dimensions (double x, double y) 
      {
         this.x = x;
         this.y = y;
      }

      public virtual double Area() 
      {
         return x*y;
      }
   }

   public class Circle: Dimensions 
   {
      public Circle(double r): base(r, 0) 
      {
      }

      public override double Area() 
      { 
         return pi * x * x; 
      }
   }

   class Sphere: Dimensions 
   {
      public Sphere(double r): base(r, 0) 
      {
      }

      public override double Area()
      {
         return 4 * pi * x * x; 
      }
   }

   class Cylinder: Dimensions 
   {
      public Cylinder(double r, double h): base(r, h) 
      {
      }

      public override double Area() 
      {
         return 2*pi*x*x + 2*pi*x*y; 
      }
   }

   public static void Main()  
   {
      double r = 3.0, h = 5.0;
      Dimensions c = new Circle(r);
      Dimensions s = new Sphere(r);
      Dimensions l = new Cylinder(r, h);
      // Display results:
      Console.WriteLine("Area of Circle   = {0:F2}", c.Area());
      Console.WriteLine("Area of Sphere   = {0:F2}", s.Area());
      Console.WriteLine("Area of Cylinder = {0:F2}", l.Area());
   }
}
输出
Area of Circle   = 28.27
Area of Sphere   = 113.10
Area of Cylinder = 150.80
在前面的示例中,注意继承的类 Circle、Sphere 和 Cylinder 都使用了初始化基类的构造函数,例如:

public Cylinder(double r, double h): base(r, h) {}
这类似于 C++ 的初始化列表。

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -