C# 中4个访问符和8个修饰符详解
4个访问修饰符(是添加到类、结构或成员声明的关键字)
Public:公有的,是类型和类型成员的访问修饰符。对其访问没有限制。
Internal:内部的,是类型和类型成员的访问修饰符。同一个程序集中的所有类都可以访问
Private:私有的,是一个成员访问修饰符。只有在声明它们的类和结构中才可以访问。
Protected::受保护的,是一个成员访问修饰符。只能在它的类和它的派生类中访问。
protected internal:访问级别为 internal 或 protected。即,“同一个程序集中的所有类,以及所有程序集中的子类都可以访问
注意点:
一个成员或类型只能有一个访问修饰符,使用 protected internal组合时除外。
如果在成员声明中未指定访问修饰符,则使用默认的可访问性
类型成员默认的可访问性
属于 |
默认的成员可访问性 |
该成员允许的声明的可访问性 |
enum |
public |
无 |
class |
private |
public protected internal private protected internal |
interface |
public |
无 |
struct |
private |
public internal private |
Internal 和protected internal 详解(即什么是同一个程序集)
示例1:(这里同一个程序集指同一个命名空间)
Class1:
using System;
using System.Collections.Generic;
using System.Text;
namespace Example05Lib
{
public class Class1
{
internal String strInternal = null;
public String strPublic;
internal protected String strInternalProtected = null;
}
}
Class2:
using System; using System.Collections.Generic; using System.text
namespace Example05Lib { class Class2 { private String tmpStr=new Class1().strInternal; private String tmpStr=new Class1().strInternalProtected; private String tmpStr=new Class1().strPublic; } }
1.1结果: Class2 类可以访问到 Class1 的 strInternal 成员,当然也可以访问到 strInternalProtected 成员,因为他们在同一个程序集里
Class3:
using System; using System.Collections.Generic; using System.text using Example05Lib
namespace Example05 { class Program { class Class3:Class1 { public Class3() { base.StrInternalProtected; base.strPublic; } } } }
1.2结果:Class3 类无法访问到 Class1 的 strInternal 成员,因为它们不在同一个程序集里。但却可以访问到 strInternalProtected成员,因为 Class3 是 Class1 的继承类。
using System; using System.Collections.Generic; using System.text using Example05Lib namespace Example05 { class Program { static void Main(string[] args) { String tmpStr=new Class1().strPublic; } } }
1.3结果:无法访问到 strInternalProtected 与strInternal 成员,因为它们既不在同一个程序集里也不存在继承关系
示例2(在这里同一个程序集是指同一个.cs文件,不同的.cs文件的命名空间省略)
2.1该示例包含两个文件:Assembly1.cs 和 Assembly2.cs。第一个文件包含内部基类 BaseClass。在第二个文件中,实例化BaseClass 的尝试将产生错误。
internal class BaseClass
{
public static int intM = 0;
}
class TestAccess
{
static void Main()
{
BaseClass myBase = new BaseClass(); // CS0122
}
}
2.2 使用与示例 1 中所用的文件相同的文件,并将 BaseClass 的可访问性级别更改为 public。还将成员 IntM 的可访问性级别更改为 internal。在此例中,您可以实例化类,但不能访问内部成员。
public class BaseClass
{
internal static int intM = 0;
}
public class TestAccess
{
static void Main()
{
BaseClass myBase = new BaseClass(); // Ok.
BaseClass.intM = 444; // CS0117
}
}
示例3
对于一些大型的项目,通常由很多个DLL文件组成,引用了这些DLL,就能访问DLL里面的类和类里面的方法。比如,你写了一个记录日志的DLL,任何项目只要引用此DLL就能实现记录日志的功能,这个DLL文件的程序就是一个程序集。
如果你记录日志的程序集是这么定义的
namespace LogerHelper
{
internal class aa
{
public void bb()
{
return "";
}
}
public class Write
{
public void WriteIn(string content)
{
class x = new aa();
x.bb();
}
}
}
当另一个项目引用了此DLL
它可以这么访问
LogerHelper.Write x = new LogerHelper.Write();
x.WriteIn("");
但不可以这么访问
LogerHelper.aa x = new LogerHelper.aa();
x.bb();
这就叫,只能在程序集中访问
8个声明修饰符
Partial:在整个同一程序集中定义分部类和结构,详解见问题1。
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(). 这说明,override可以覆盖基类的方法,让基类的方法以子类的内容实现,而new不用来覆盖基类的方法,而是全新定义一个子类的方法,这个方法只属于子类,与基类的方法无关,只是名字上相同而已. 而这一例子的基础是建立在用子类对象加框成基类对象的,目的是实现用基类句柄调用子类方法,以实现重载的多态性. 如果想调用子类的new方法,用子类的句柄(绝对不能用基类句柄)来调用.结果[9]可以看出来. 用new是在为子类定义方法名时,实在没有办法定义方法名的情况才与基类的方法相同,但这个方法只在子类中起到作用,而不影响基类的方法.也就是说,new方法就是子类新定义的方法.用override是直正意义上的重载.
注意:部分内容转载:http://blog.csdn.net/susan19890313/article/details/7575228
C# 中4个访问符和8个修饰符详解的更多相关文章
- java中的类修饰符、成员变量修饰符、方法修饰符。
类修饰符: public(访问控制符),将一个类声明为公共类,他可以被任何对象访问,一个程序的主类必须是公共类. abstract,将一个类声明为抽象类,没有实现的方法,需要子类提供方法实现. fin ...
- 第7.26节 Python中的@property装饰器定义属性访问方法getter、setter、deleter 详解
第7.26节 Python中的@property装饰器定义属性访问方法getter.setter.deleter 详解 一. 引言 Python中的装饰器在前面接触过,老猿还没有深入展开介绍装饰 ...
- Java 语言的类、属性、方法各有哪些修饰符?简述各修饰符的区别
1. 类的修饰符分为:可访问控制符和非访问控制符两种. 可访问控制符是:公共类修饰符 public 非访问控制符有:抽象类修饰符 abstract :最终类修饰符 final 1.公共类修饰符 pub ...
- Eclipse和MyEclipse工程描述符.classpath和.project和.mymetadata详解aaaaaa(转)
Eclipse和MyEclipse工程描述符.classpath和.project和.mymetadata详解(转) (2012-03-28 15:06:54) 转载▼ 标签: .mymetadata ...
- [转载]windows任务管理器中的工作设置内存,内存专用工作集,提交大小详解
windows任务管理器中的工作设置内存,内存专用工作集,提交大小详解 http://shashanzhao.com/archives/832.html 虽然是中文字,但是理解起来还是很困难,什么叫工 ...
- 对于形式参数只能用final修饰符,其它任何修饰符都会引起编译器错误
在Java中修饰符总共有一下几种: 1.访问控制修饰符 分别有:public private protected,缺省 2.其它修饰符 分别有:abstract,final,stati ...
- HTML中DOM核心知识有哪些(带实例超详解)
HTML中DOM核心知识有哪些(带实例超详解) 一.总结: 1.先取html元素,然后再对他进行操作,取的话可以getElementById等 2.操作的话,可以是innerHtml,value等等 ...
- vue--键盘修饰符以及自定义键盘修饰符
键盘修饰符以及自定义键盘修饰符 1.vue键盘修饰符[了解即可] 地址:https://cn.vuejs.org/v2/guide/events.html#%E6%8C%89%E9%94%AE%E4 ...
- MySQL中的主键,外键有什么作用详解
MySQL中的主键,外键有什么作用详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 学关系型数据库的同学,尤其在学习主键和外键时会产生一定的困惑.那么今天我们就把这个困惑连根拔起 ...
- (转)python中调用R语言通过rpy2 进行交互安装配置详解
python中调用R语言通过rpy2 进行交互安装配置详解(R_USER.R_HOME配置) 2018年11月08日 10:00:11 luqin_ 阅读数:753 python中调用R语言通过r ...
随机推荐
- Zipper
Zipper Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Su ...
- ExecuteReader(),ExecuteNonQuery(),ExecuteScalar(),ExecuteXmlReader()之间的区别
本文来自:http://www.cnblogs.com/zhouxiaxue/archive/2006/05/12/398266.html http://www.cnblogs.com/yaoxc/a ...
- WordPress中文汉字username不能注冊怎么办?
WordPress注冊用户是不支持中文的.可是近期在项目中须要用到中文注冊. 后来想到了简单的处理办法: 打开 wp-includes/formatting.php.找到 function sanit ...
- [tarjan] poj 1236 Network of Schools
主题链接: http://poj.org/problem?id=1236 Network of Schools Time Limit: 1000MS Memory Limit: 10000K To ...
- 【字母树+贪心】【HDU3460】【Ancient Printer】
题目大意: 一个打印机 只有 打印,删除,a-z.操作 给你一堆队名,如何才能操作次数最少输出全部 (字典树节点数-1)*2 输入,删除操作数 字符串数 printf操作数 最长字符串的长度 最后一个 ...
- 关于rem自适应的一点研究
参考地址:http://m.ctrip.com/html5/ https://www.amazon.cn/ rem是相对于html根元素的一个单位.rem是px的16倍,即1rem = 16px;除了 ...
- Sublime 学习记录(五) Sublime 其他插件(个人喜好)
(一) JSFormat 安装 :命令面板 pci 回车 JSFormat 回车 功能 : javascript的代码格式化插件 简介 : 很多网站的JS代码都进行了压缩,一行式的甚至混淆压缩,这让 ...
- uva 10366 Faucet Flow
题意: 给出l和r,然后从l坐标到r坐标每隔两个位置有一个档板,给出挡板的高度,然后想(-1, 1)中间加水,问什么时候会溢出. 分析: 两边先找到距离(-1,1)最近的最大值L和R.接着比较两个L和 ...
- 【Tomcat】项目自动部署的链接重置错误
在服务器中装好的tomcat7 ,(服务器是的window server 2008) 在tomcat bin目录运行的 service.bat install 安装服务.然后,设置服务项(服务项名称: ...
- iOS开发--系统通讯录的访问与添加联系人
公司项目有访问通讯录的需求,所以开始了探索之路.从开始的一无所知,到知识的渐渐清晰.这一切要感谢广大无私分享的 “coder”,注:我是尊称的语气! 苹果提供了访问系统通讯录的框架,以便开发者对系统通 ...