5 访问修饰符 抽象类 抽象成员 密封类 静态类 扩展方法 命名约定
访问修饰符
- 所有声明在类中的成员都是可见的,无论他们的访问性如何。
- 继承的成员对派生的成员可以是可见的,也可以是不可见的。
- 下面是5个访问级别的名称。
- public
- private
- protected
- internal
- protected internal
- 必须对每个成员指定访问级别,如果不指定,它的隐式访问级别为 private
- 成员不能比它的类有更高的访问性
public int Member;
private int Member2; // 只能自己访问
protected int Member3; // 允许派生类访问
internal int Member4; // 相同程序集
protected internal int Member5; // 相同程序集且继承
修饰符 | 含义 |
---|---|
private | 只在类的内部可以访问 |
internal | 对该程序集内所有类可访问 |
protected | 对所有继承该类的类可访问 |
prctected internal | 对所有继承该类 或 在该类程序集内声明的类可访问 |
public | 对任何类可访问 |
抽象成员
抽象成员是指设计为被覆写的函数成员
- 必须是一个函数成员,也就是说 字段和常量不能为抽象成员
- 必须使用 abstract 修饰符标记
- 不能实现代码块。
abstract public void PrintStr(string str);
abstract public int MyProperty
{
get;
set;
}
抽象成员只能在抽象类中声明,一共有4个类型的成员可以声明为抽象
- 方法
- 属性
- 事件
- 索引
类似虚成员,派生类中抽象成员的实现必须指定override修饰符
虚成员 | 抽象成员 | |
---|---|---|
关键字 | virtual | abstract |
实现体 | 有实现体 | 没有实现体,被分号取代 |
在派生类中被覆写 | 能被覆写,使用override | 必须覆写,使用override |
成员类型 | 方法 属性 事件 索引器 |
方法 属性 事件 索引器 |
抽象类
抽象类的作用是被继承,只能作为基类
- 不能创建抽象类的实例
- 抽象类使用abstract修饰符声明
abstract class MyClass
{
...
}
- 抽象类可以包含抽象成员或普通的非抽象成员
- 抽象类可以派生另一个抽象类
- 任何派生自抽象类的类必须使用overrider关键字实现该类的所有抽象成员,除非派生类自己也是抽象类
abstract class AbClass
{
public void IdentifyBase()
{
Console.WriteLine("I am AbClass"); // 普通方法
}
abstract public void IdentfyDerived(); // 抽象方法
}
class DerivedClass:AbClass
{
override public void IdentifyDerived(); // 抽象方法的实现
{Console.WriteLine("I am DerivedClass");}
}
class Program
{
static void Main()
{
// AbClass a = new AbClass(); // 抽象类不能实例化
DerivedClass b = new DerivedClass(); // 实例化
b.IdentifyBase();
b.IdentifyDerived();
}
}
字段和常量不能声明abstract
abstract class MyBase // 抽象类
{
public int SideLength = 10; // 数据成员
const int TriangleSideCount = 3; // 数据成员
abstract public void PrintStuff(string s); // 抽象方法
abstract public int MyInt { get;set; } // 抽象属性
public int PerimeterLength() // 非抽象方法
{
return SideLength;
}
}
密封类
抽象类补不能实例化,只能作为基类,而密封类正好相反。
- 密封类只能被用作独立的类,无法作为基类
- 密封类使用 sealed 修饰符标注
sealed class MyClass
{
...
}
静态类
静态类中所有的成员都是静态的。
静态类用于存放不受实例数据影响的数据和函数。静态类的一个常见的用途可能是创建一个包含一组数学方法和值的数学库
- 类本身标记为static
- 类的所有成员必须是静态的
- 类可以有一个静态构造函数,但不能有实例构造函数,不能创建改类的实例
- 静态类是隐示密封的,也就是不能继承静态类
static public class MyMath
{
public static float PI = 3.14F;
public static bool IsOdd(int x)
{
return x % 2 == 1;
}
}
扩展方法
class MyData
{
private double D1;
private double D2;
private double D3;
// 构造方法
public MyData(double d1, double d2, double d3)
{
D1 = d1;
D2 = d2;
D3 = d3;
}
public double Sum()
{
return D1 + D2 + D3;
}
}
static class ExtendMyData
{
public static double Average(MyData md)
{
return md.Sum()/2;
}
}
优化:使用实例调用 Average
需要在参数声明中添加this关键字,必须是公有的静态类
static class ExtendMyData
{
public static double Average(this MyData md)
{
return md.Sum()/2;
}
}
MyData myData = new MyData(1, 2, 3);
myData.Average();
扩展方法的重要要求如下:
- 声明扩展方法的类必须声明为static
- 扩展方法本身必须是static
- 扩展方法必须包含关键字this作为第一个参数类型,后面紧跟它所扩展的类的名称
namespace _01_扩展方法
{
internal class Program
{
public static void Main(string[] args)
{
MyData data = new MyData(12);
// 调用
double r = data.res();
Console.WriteLine(r);
Console.ReadKey();
}
}
// 扩展方法
static class Extenddata
{
public static double res(this MyData data)
{
return data.Sum();
}
}
public class MyData
{
private double D1;
public MyData(double d1)
{
D1 = d1;
}
public double Sum()
{
return D1;
}
}
}
命名约定
风格名称 | 描述 | 推荐使用 | 示例 |
---|---|---|---|
Pascal大小写 | 首字符大写 | 类 方法 命名控件 属性 和 公共字段 | CardDeck |
Camel大小写 | 每个单词首字符大写 第一个除外 | 用于局部变量的名称和方法声明的形参声明 | totalCycleCount |
下划线加Camel大小写 | 下划线开头 每个单词首字符大写 第一个除外 | 用于私有和受保护的字段 | _cycleCount |
吾虽浪迹,却未迷失本心