访问修饰符(是添加到类、结构或成员声明的关键字)
Public:公有的,是类型和类型成员的访问修饰符。对其访问没有限制。
Internal:内部的,是类型和类型成员的访问修饰符。同一个程序集中的所有类都可以访问
Private:私有的,是一个成员访问修饰符。只有在声明它们的类和结构中才可以访问。
Protected:受保护的,是一个成员访问修饰符。只能在它的类和它的派生类中访问。
protected internal:访问级别为 internal 或 protected。即,“同一个程序集中的所有类,以及所有程序集中的子类都可以访问
注意点: 一个成员或类型只能有一个访问修饰符,使用 protected internal组合时除外。 如果在成员声明中未指定访问修饰符,则使用默认的可访问性
声明修饰符
Partial:在整个同一程序集中定义分部类和结构。
Static: 声明属于类型本身而不是属于特定对象的成员。
Abstract:抽象类,只能是其他类的基类。类中的方法只声明不实现,方法的实现在他的派生类中完成。
Sealed:指定类不能被继承。
Virtual:用于修饰方法、属性、索引器或事件声明,并且允许在派生类中重写这些对象
Override:提供从基类继承的成员的新实现
New:作修饰符,隐藏从基类成员继承的成员,在不使用 new 修饰符的情况下隐藏成员是允许的,但会生成警告。作运算符,用于创建对象和调用构造函数。
Extern:用于声明在外部实现的方法。 extern 修饰符的常见用法是在使用 Interop 服务调入非托管代码时与 DllImport 特性一起使用。 在这种情况下,还必须将方法声明为 static
2. new不需要和virtual配套使用。在基类base中声明了方法method(),在子类derived中声明了同名的方法method()并用new修饰。那么当将子类的实例赋予基类的对象时即Base Bclass= new Derived();Bclass.Method()是调用了基类类的method()方法,而不是子类的。
3. override可以覆盖基类的方法,让基类的方法以子类的内容实现,而new不用来覆盖基类的方法,而是全新定义一个子类的方法,这个方法只属于子类,与基类的方法无关,只是名字上相同而已
下面,我以例子来说明他们之间的微妙区别:
public class GrandClass//基类
{
public GrandClass()
{
Console.WriteLine("In GrandClass.Constructor");
}
public virtual void Method()//用virtual才可以在子类中用override,而new不需要这样
{
Console.WriteLine("In GrandClass.Method()");
}
}
public class ParentClass:GrandClass//继承基类,看看override状态
{
public ParentClass()
{
Console.WriteLine("In ParentClass.Constructor");
}
public override void Method()//使用override,是说把基类的方法重新定义
{
Console.WriteLine("In ParentClass.Method() use override");
}
}
public class NewParentClass:GrandClass//继承基类,看看new状态
{
public NewParentClass()
{
Console.WriteLine("In NewParentClass.Constructor");
}
new public void Method()//使用new,不是说用到基类的方法,而是重新定义一个子类方法,只不过,方法名称与基类相同
{
Console.WriteLine("In NewParentClass.Method()");
}
}
下面的调用代码:
static void Main()
{
GrandClass Parent=(GrandClass)new ParentClass();//用override子类加框一个基类对象句柄
Parent.Method();
GrandClass NewParent=(GrandClass)new NewParentClass();//用new子类加框一个基类对象句柄
NewParent.Method();
NewParentClass NewParent1=new NewParentClass();//一个子类句柄
NewParent1.Method();
}
结果是这样的:
[1]In GrandClass.Constructor
[2]In ParentClass.Constructor
[3]In ParentClass.Method() use override
[4]In GrandClass.Constructor
[5]In NewParentClass.Constructor
[6]In GrandClass.Method()
[7]In GrandClass.Constructor
[8]In NewParentClass.Constructor
[9]In NewParentClass.Method()
结果前的序号是我自己加的.为了以下的分析:
[1],[2]两句是GrandClass Parent=(GrandClass)new ParentClass();的结果.(注意一下子类构建器与基类构建器的初始化顺序)
[3]是Parent.Method();结果.
[4],[5]两句是GrandClass NewParent=(GrandClass)new NewParentClass();的结果.
[6]是NewParent.Method();的结果.
[7],[8]两句是GrandClass NewParent1=(GrandClass)new NewParentClass();的结果.
[9]是NewParent1.Method();的结果.
这里我们可以看到,同样是用子类的对象构造一个基类句柄.结果却很明显,可以看到[3]和[6]的区别.[3]调用了子类的Method(),而[6]调用了基类的Method().
而这一例子的基础是建立在用子类对象加框成基类对象的,目的是实现用基类句柄调用子类方法,以实现重载的多态性.
如果想调用子类的new方法,用子类的句柄(绝对不能用基类句柄)来调用.结果[9]可以看出来.
用new是在为子类定义方法名时,实在没有办法定义方法名的情况才与基类的方法相同,但这个方法只在子类中起到作用,而不影响基类的方法.也就是说,new方法就是子类新定义的方法.用override是直正意义上的重载.
Public:公有的,是类型和类型成员的访问修饰符。对其访问没有限制。
Internal:内部的,是类型和类型成员的访问修饰符。同一个程序集中的所有类都可以访问
Private:私有的,是一个成员访问修饰符。只有在声明它们的类和结构中才可以访问。
Protected:受保护的,是一个成员访问修饰符。只能在它的类和它的派生类中访问。
protected internal:访问级别为 internal 或 protected。即,“同一个程序集中的所有类,以及所有程序集中的子类都可以访问
注意点: 一个成员或类型只能有一个访问修饰符,使用 protected internal组合时除外。 如果在成员声明中未指定访问修饰符,则使用默认的可访问性
声明修饰符
Partial:在整个同一程序集中定义分部类和结构。
Static: 声明属于类型本身而不是属于特定对象的成员。
Abstract:抽象类,只能是其他类的基类。类中的方法只声明不实现,方法的实现在他的派生类中完成。
Sealed:指定类不能被继承。
Virtual:用于修饰方法、属性、索引器或事件声明,并且允许在派生类中重写这些对象
Override:提供从基类继承的成员的新实现
New:作修饰符,隐藏从基类成员继承的成员,在不使用 new 修饰符的情况下隐藏成员是允许的,但会生成警告。作运算符,用于创建对象和调用构造函数。
Extern:用于声明在外部实现的方法。 extern 修饰符的常见用法是在使用 Interop 服务调入非托管代码时与 DllImport 特性一起使用。 在这种情况下,还必须将方法声明为 static
Virtual,override和new的区别
1. virtual和override配套使用。在基类base中声明了虚方法method()并用virtual修饰,在子类derived中重写方法method()并用override修饰。那么当将子类的实例赋予基类的对象(不需要强制转换)时即Base Bclass= new Derived();Bclass.Method()是调用了子类的method()方法,而不是基类的。2. new不需要和virtual配套使用。在基类base中声明了方法method(),在子类derived中声明了同名的方法method()并用new修饰。那么当将子类的实例赋予基类的对象时即Base Bclass= new Derived();Bclass.Method()是调用了基类类的method()方法,而不是子类的。
3. override可以覆盖基类的方法,让基类的方法以子类的内容实现,而new不用来覆盖基类的方法,而是全新定义一个子类的方法,这个方法只属于子类,与基类的方法无关,只是名字上相同而已
下面,我以例子来说明他们之间的微妙区别:
public class GrandClass//基类
{
public GrandClass()
{
Console.WriteLine("In GrandClass.Constructor");
}
public virtual void Method()//用virtual才可以在子类中用override,而new不需要这样
{
Console.WriteLine("In GrandClass.Method()");
}
}
public class ParentClass:GrandClass//继承基类,看看override状态
{
public ParentClass()
{
Console.WriteLine("In ParentClass.Constructor");
}
public override void Method()//使用override,是说把基类的方法重新定义
{
Console.WriteLine("In ParentClass.Method() use override");
}
}
public class NewParentClass:GrandClass//继承基类,看看new状态
{
public NewParentClass()
{
Console.WriteLine("In NewParentClass.Constructor");
}
new public void Method()//使用new,不是说用到基类的方法,而是重新定义一个子类方法,只不过,方法名称与基类相同
{
Console.WriteLine("In NewParentClass.Method()");
}
}
下面的调用代码:
static void Main()
{
GrandClass Parent=(GrandClass)new ParentClass();//用override子类加框一个基类对象句柄
Parent.Method();
GrandClass NewParent=(GrandClass)new NewParentClass();//用new子类加框一个基类对象句柄
NewParent.Method();
NewParentClass NewParent1=new NewParentClass();//一个子类句柄
NewParent1.Method();
}
结果是这样的:
[1]In GrandClass.Constructor
[2]In ParentClass.Constructor
[3]In ParentClass.Method() use override
[4]In GrandClass.Constructor
[5]In NewParentClass.Constructor
[6]In GrandClass.Method()
[7]In GrandClass.Constructor
[8]In NewParentClass.Constructor
[9]In NewParentClass.Method()
结果前的序号是我自己加的.为了以下的分析:
[1],[2]两句是GrandClass Parent=(GrandClass)new ParentClass();的结果.(注意一下子类构建器与基类构建器的初始化顺序)
[3]是Parent.Method();结果.
[4],[5]两句是GrandClass NewParent=(GrandClass)new NewParentClass();的结果.
[6]是NewParent.Method();的结果.
[7],[8]两句是GrandClass NewParent1=(GrandClass)new NewParentClass();的结果.
[9]是NewParent1.Method();的结果.
这里我们可以看到,同样是用子类的对象构造一个基类句柄.结果却很明显,可以看到[3]和[6]的区别.[3]调用了子类的Method(),而[6]调用了基类的Method().
而这一例子的基础是建立在用子类对象加框成基类对象的,目的是实现用基类句柄调用子类方法,以实现重载的多态性.
如果想调用子类的new方法,用子类的句柄(绝对不能用基类句柄)来调用.结果[9]可以看出来.
用new是在为子类定义方法名时,实在没有办法定义方法名的情况才与基类的方法相同,但这个方法只在子类中起到作用,而不影响基类的方法.也就是说,new方法就是子类新定义的方法.用override是直正意义上的重载.