public / protected / private
类的成员的可访问性
(1表示可访问)
访问控制符 | 同类中 | 相同程序集的子类 | 相同程序集的子类 | 不同程序集的子类 | 不同程序集的非子类 |
---|---|---|---|---|---|
public | 1 | 1 | 1 | 1 | 1 |
protected internal | 1 | 1 | 1 | 1 | |
protected | 1 | 1 | 1 | ||
internal | 1 | 1 | |||
private | 1 |
【注意】
- 如果没有修饰符,默认为private。
- 构造方法通常用public,如果没有写默认为private。
- 子类不能访问基类中的private字段。
- 对于基类中的protected,子类不能访问基类的实例的protected字段,但通过实例化子类来访问该字段。
各元素能够使用的访问控制符
语法元素 | 默认的 | 允许使用的 |
---|---|---|
namespace | public | 不可修饰 |
class | private | 五种均可 |
struct | private | 不可使用protected |
interface【重点!易错!】 | public | 不可修饰! |
enum | public | 不可修饰 |
static
- static可用来修饰:字段、方法、属性、事件、操作符或构造函数。
- 常数或嵌套的类型隐含为static;
- 索引器不能是static的。
- 有static的:静态成员;没有static的:实例成员。
static的真正含义:
不属于某个实例的,而是属于整个类的,整个类的所有实例都是共享的。
简而言之,static就是“非实例的”。
static字段
静态字段不保存在某个对象实例的内存空间中,而是保存在一个类的内存区字段的公共存储单元。
什么时候用静态字段?
例如:人的总数,这个性质是属于所有“人”类的,而不是属于一个实例Anna的。而年龄、名字等,是属于一个具体的实例Anna的。
public class Person
{
int totalNum;
int age;
int name;
}
static void Main()
{
Person.totalNum++;
var Anna = new Person();
//...
}
static方法
只属于类的静态方法。
静态方法和实例方法的比较
- **内存所有:**实例方法是属于某个对象的方法,在这个对象创建时,对象的方法在内存中拥有自己专用的代码段;静态方法属于整个类,他在内存中的代码段将随着类的定义而分配和装载,不被任何一个对象专有。
- **处理限制:**静态方法不能操纵和处理属于某个对象的成员变量,而只能处理属于整个类的成员变量。即,static方法只能处理static字段或调用static方法。
- **访问限制:**static方法中,不能访问实例变量。在类方法中不能使用this或base。
- **调用方式:**调用static方法时,应该使用类名直接访问,不能用某一个具体的对象名。
例如:
Console.WriteLine(); int.Parse();是静态方法。
const
被const的修饰的是常量(constant)。
格式:
修饰符 const 类型 常量名 = 常量表达式
- 常量的作用相当于对常量的符号表示,必须在定义时显式地赋值,并且赋以常量表达式,不能用变量赋值。
- 除了在定义的地方,不能对常量进行赋值。在程序中保持不变。
- 隐含static,只能用类名来访问。但不能显式地用static修饰。
class Constants
{
public const int a = 1;
public const int b = a + 1;
}
readonly
特点:
- readonly字段可以是各种类型。(const只能是简单类型或字符串)
- readonly字段可以用变量或表达式赋值。
- readonly不能修饰局部变量(const可以)。
- 不隐含static性质。
- 不要求定义时初始化。