标题:[.net基础]访问修饰符

一、前言

基础掌握不牢固啊,所以记录下来。

二、方法访问修饰符Internal

  (1)、创建工程ParentAndSon

  (2)、添加类ModelA

namespace ParentAndSon
{public class ModelA{internal void TestInternal(){}protected void TestProtected(){}protected internal void TestProtectedInternal(){}}
}

View Code

  (3)、添加测试类MainIn,注意命名空间和ModelA相同

namespace ParentAndSon
{public class MainIn{public static void Main(string[] arg){ModelA a = new ModelA();a.TestInternal();//a.TestProtected();
            a.TestProtectedInternal();}}
}

View Code

  可看出,只有protected修饰的无法访问,internal和protected internal修饰的方法均可访问。

  (4)、添加测试类InvokeModelA,注意命名空间和ModelA不同

namespace SomeNameSpace
{public class InvokeModelA{public InvokeModelA(){ModelA a = new ModelA();a.TestInternal();//a.TestProtected();
            a.TestProtectedInternal();}}
}

View Code

  可看出,只有protected修饰的无法访问,internal和protected internal修饰的方法均可访问。

  (5)、创建新工程TestParentAndSon,以下操作均在TestParentAndSon项目中。

  (6)、添加测试类Program,注意命名空间和ModelA不同

namespace TestParentAndSon
{class Program{static void Main(string[] args){ModelA a = new ModelA();//a.TestInternal();//a.TestProtected();//a.TestProtectedInternal();
        }}
}

View Code

  可看出,protected、internal和protected internal修饰的方法均不可访问。

  (7)、添加测试类TestA,注意命名空间和ModelA相同

namespace ParentAndSon
{public class TestA{public TestA(){ModelA a = new ModelA();//a.TestInternal();//a.TestProtected();//a.TestProtectedInternal();
        }}
}

View Code

  可看出,protected、internal和protected internal修饰的方法均不可访问。
  (8)、添加子类Son

namespace TestParentAndSon
{public class Son : ModelA{public Son(){//this.TestInternal();this.TestProtected();this.TestProtectedInternal();}}
}

View Code

  可看出,internal修饰的方法不可访问,而protected和protected internal修饰的方法可以访问。

总结:

  internal修饰符是针对同一程序集的,如果是同一程序集,则可以访问,否则不可访问。

  protected是针对子类的,不管是否位于同一个程序集。

  protected internal是把两者的优点集合到一起了,范围比两者任何一个都大。

三、继承override和new

1、测试public修饰方法

A、方法签名和父类相同

  (1)、新建工程ParentAndSon

  (2)、添加类MA

namespace ParentAndSon
{public class MA{public void InvokeShowProtected(){Console.WriteLine("MA-InvokeShowProtected");}public void InvokeShowProtectedInternal(){Console.WriteLine("MA-InvokeShowProtectedInternal");}}
}

View Code

  (3)、添加子类MAA,方法签名和MA完全一样

namespace ParentAndSon
{public class MAA : MA{public void InvokeShowProtected(){Console.WriteLine("MAA-InvokeShowProtected");}public void InvokeShowProtectedInternal(){Console.WriteLine("MAA-InvokeShowProtectedInternal");}}
}

View Code

  (4)、添加子类MAAA,方法签名和MAA完全一样

namespace ParentAndSon
{public class MAAA : MAA{public void InvokeShowProtected(){Console.WriteLine("MAAA-InvokeShowProtected");}public void InvokeShowProtectedInternal(){Console.WriteLine("MAAA-InvokeShowProtectedInternal");}}
}

View Code

  (5)、添加测试类Programe

namespace ParentAndSon
{public class Programe{public static void Main(string[] arg){Console.WriteLine("MA a = new MA();");MA a = new MA();a.InvokeShowProtected();a.InvokeShowProtectedInternal();Console.WriteLine();Console.WriteLine("MAA aa = new MAA();");MAA aa = new MAA();aa.InvokeShowProtected();aa.InvokeShowProtectedInternal();Console.WriteLine("MA b = (MA)aa;");MA b = (MA)aa;b.InvokeShowProtected();b.InvokeShowProtectedInternal();Console.WriteLine();Console.WriteLine("MAAA aaa = new MAAA();");MAAA aaa = new MAAA();aaa.InvokeShowProtected();aaa.InvokeShowProtectedInternal();Console.WriteLine("MAA bb = (MAA)aaa;");MAA bb = (MAA)aaa;bb.InvokeShowProtected();bb.InvokeShowProtectedInternal();Console.WriteLine();Console.WriteLine("MA na = new MAA();");MA na = new MAA();na.InvokeShowProtected();na.InvokeShowProtectedInternal();Console.WriteLine("MAA _na = (MAA)na;");MAA _na = (MAA)na;_na.InvokeShowProtected();_na.InvokeShowProtectedInternal();Console.WriteLine();Console.WriteLine("MAA naa = new MAAA();");MAA naa = new MAAA();naa.InvokeShowProtected();naa.InvokeShowProtectedInternal();Console.WriteLine("MAAA _naa = (MAAA)naa;");MAAA _naa = (MAAA)naa;_naa.InvokeShowProtected();_naa.InvokeShowProtectedInternal();Console.WriteLine();Console.ReadKey();}}
}

View Code

  (6)、执行结果

MA a = new MA();
MA-InvokeShowProtected
MA-InvokeShowProtectedInternalMAA aa = new MAA();
MAA-InvokeShowProtected
MAA-InvokeShowProtectedInternal
MA b = (MA)aa;
MA-InvokeShowProtected
MA-InvokeShowProtectedInternalMAAA aaa = new MAAA();
MAAA-InvokeShowProtected
MAAA-InvokeShowProtectedInternal
MAA bb = (MAA)aaa;
MAA-InvokeShowProtected
MAA-InvokeShowProtectedInternalMA na = new MAA();
MA-InvokeShowProtected
MA-InvokeShowProtectedInternal
MAA _na = (MAA)na;
MAA-InvokeShowProtected
MAA-InvokeShowProtectedInternalMAA naa = new MAAA();
MAA-InvokeShowProtected
MAA-InvokeShowProtectedInternal
MAAA _naa = (MAAA)naa;
MAAA-InvokeShowProtected
MAAA-InvokeShowProtectedInternal

View Code

B、方法修饰符改成new

步骤和上述一样,只是MAA:

namespace ParentAndSon
{public class MAA : MA{public new void InvokeShowProtected(){Console.WriteLine("MAA-InvokeShowProtected");}public new void InvokeShowProtectedInternal(){Console.WriteLine("MAA-InvokeShowProtectedInternal");}}
}

View Code

MAAA:

namespace ParentAndSon
{public class MAAA : MAA{public new void InvokeShowProtected(){Console.WriteLine("MAAA-InvokeShowProtected");}public new void InvokeShowProtectedInternal(){Console.WriteLine("MAAA-InvokeShowProtectedInternal");}}
}

View Code

执行结果和【A、方法签名和父类相同】一样。可见默认是new。

C、方法修饰符改成override

namespace ParentAndSon
{public class MAA : MA{public override void InvokeShowProtected(){Console.WriteLine("MAA-InvokeShowProtected");}public new void InvokeShowProtectedInternal(){Console.WriteLine("MAA-InvokeShowProtectedInternal");}}
}

View Code

编译出错:

Error    1    'ParentAndSon.MAA.InvokeShowProtected()': cannot override inherited member 'ParentAndSon.MA.InvokeShowProtected()' because it is not marked virtual, abstract, or override    D:\KiteSource\Temp\PageLoadAndOnload\ParentAndSon\MAA.cs    10    30    ParentAndSon

View Code

所以不能改成override。

2、测试public修饰方法(调用protected方法)

A、方法签名和父类相同

  (1)、新建工程ParentAndSon

  (2)、添加类MA

namespace ParentAndSon
{public class MA{protected virtual void ShowProtected(){Console.WriteLine("MA-ShowProtected");}protected internal virtual void ShowProtectedInternal(){Console.WriteLine("MA-ShowProtectedInternal");}public void InvokeShowProtected(){this.ShowProtected();}public void InvokeShowProtectedInternal(){this.ShowProtectedInternal();}}
}

View Code

  (3)、添加子类MAA,方法签名和MA完全一样

namespace ParentAndSon
{public class MAA : MA{protected virtual void ShowProtected(){Console.WriteLine("MAA-ShowProtected");}protected internal virtual void ShowProtectedInternal(){Console.WriteLine("MAA-ShowProtectedInternal");}public void InvokeShowProtected(){this.ShowProtected();}public void InvokeShowProtectedInternal(){this.ShowProtectedInternal();}}
}

View Code

  (4)、添加子类MAAA,方法签名和MAA完全一样

namespace ParentAndSon
{public class MAAA : MAA{protected virtual void ShowProtected(){Console.WriteLine("MAAA-ShowProtected");}protected internal virtual void ShowProtectedInternal(){Console.WriteLine("MAAA-ShowProtectedInternal");}public void InvokeShowProtected(){this.ShowProtected();}public void InvokeShowProtectedInternal(){this.ShowProtectedInternal();}}
}

View Code

  (5)、添加测试类Programe

namespace ParentAndSon
{public class Programe{public static void Main(string[] arg){Console.WriteLine("MA a = new MA();");MA a = new MA();a.InvokeShowProtected();a.InvokeShowProtectedInternal();Console.WriteLine();Console.WriteLine("MAA aa = new MAA();");MAA aa = new MAA();aa.InvokeShowProtected();aa.InvokeShowProtectedInternal();Console.WriteLine("MA b = (MA)aa;");MA b = (MA)aa;b.InvokeShowProtected();b.InvokeShowProtectedInternal();Console.WriteLine();Console.WriteLine("MAAA aaa = new MAAA();");MAAA aaa = new MAAA();aaa.InvokeShowProtected();aaa.InvokeShowProtectedInternal();Console.WriteLine("MAA bb = (MAA)aaa;");MAA bb = (MAA)aaa;bb.InvokeShowProtected();bb.InvokeShowProtectedInternal();Console.WriteLine();Console.WriteLine("MA na = new MAA();");MA na = new MAA();na.InvokeShowProtected();na.InvokeShowProtectedInternal();Console.WriteLine("MAA _na = (MAA)na;");MAA _na = (MAA)na;_na.InvokeShowProtected();_na.InvokeShowProtectedInternal();Console.WriteLine();Console.WriteLine("MAA naa = new MAAA();");MAA naa = new MAAA();naa.InvokeShowProtected();naa.InvokeShowProtectedInternal();Console.WriteLine("MAAA _naa = (MAAA)naa;");MAAA _naa = (MAAA)naa;_naa.InvokeShowProtected();_naa.InvokeShowProtectedInternal();Console.WriteLine();Console.ReadKey();}}
}

View Code

  (6)、执行结果

MAA-ShowProtectedInternal
MA b = (MA)aa;
MA-ShowProtected
MA-ShowProtectedInternalMAAA aaa = new MAAA();
MAAA-ShowProtected
MAAA-ShowProtectedInternal
MAA bb = (MAA)aaa;
MAA-ShowProtected
MAA-ShowProtectedInternalMA na = new MAA();
MA-ShowProtected
MA-ShowProtectedInternal
MAA _na = (MAA)na;
MAA-ShowProtected
MAA-ShowProtectedInternalMAA naa = new MAAA();
MAA-ShowProtected
MAA-ShowProtectedInternal
MAAA _naa = (MAAA)naa;
MAAA-ShowProtected
MAAA-ShowProtectedInternal

View Code

B、(public)方法修饰符改成new

步骤和上述一样,只是MAA:

namespace ParentAndSon
{public class MAA : MA{protected virtual void ShowProtected(){Console.WriteLine("MAA-ShowProtected");}protected internal virtual void ShowProtectedInternal(){Console.WriteLine("MAA-ShowProtectedInternal");}public new void InvokeShowProtected(){this.ShowProtected();}public new void InvokeShowProtectedInternal(){this.ShowProtectedInternal();}}
}

View Code

MAAA:

namespace ParentAndSon
{public class MAAA : MAA{protected virtual void ShowProtected(){Console.WriteLine("MAAA-ShowProtected");}protected internal virtual void ShowProtectedInternal(){Console.WriteLine("MAAA-ShowProtectedInternal");}public new void InvokeShowProtected(){this.ShowProtected();}public new void InvokeShowProtectedInternal(){this.ShowProtectedInternal();}}
}

View Code

执行结果和【A、方法签名和父类相同】执行结果一样。说明默认是new的。

C、(public)方法修饰符改成override

其他代码不变,只是MAA变了:

public override void InvokeShowProtected(){this.ShowProtected();}public override void InvokeShowProtectedInternal(){this.ShowProtectedInternal();}

View Code

编译不通过,提示:

Error    6    'ParentAndSon.MAA.InvokeShowProtectedInternal()': cannot override inherited member 'ParentAndSon.MA.InvokeShowProtectedInternal()' because it is not marked virtual, abstract, or override    D:\KiteSource\Temp\PageLoadAndOnload\ParentAndSon\MAA.cs    25    30    ParentAndSon

View Code

MAAA也是一样。

1和2说明,protected和protected internal和public修饰符在父类和子类方法覆盖上面,效果是一样的,经测试public virtual和public的表现也是一样的。

3、测试virtual方法

A、方法签名和父类相同

  (1)、新建工程ParentAndSon

  (2)、添加MA类

public class MA{public virtual void InvokeShowProtected(){Console.WriteLine("MA-InvokeShowProtected");}}

View Code

  (3)、添加子类MAA

public class MAA : MA{public virtual void InvokeShowProtected(){Console.WriteLine("MAA-InvokeShowProtected");}}

View Code

  (4)、添加子类MAAA

public class MAAA : MAA{public virtual void InvokeShowProtected(){Console.WriteLine("MAAA-InvokeShowProtected");}}

View Code

  (5)、测试程序

public static void Main(string[] arg){Console.WriteLine("MA a = new MA();");MA a = new MA();a.InvokeShowProtected();Console.WriteLine();Console.WriteLine("MAA aa = new MAA();");MAA aa = new MAA();aa.InvokeShowProtected();Console.WriteLine("MA b = (MA)aa;");MA b = (MA)aa;b.InvokeShowProtected();Console.WriteLine();Console.WriteLine("MAAA aaa = new MAAA();");MAAA aaa = new MAAA();aaa.InvokeShowProtected();Console.WriteLine("MAA bb = (MAA)aaa;");MAA bb = (MAA)aaa;bb.InvokeShowProtected();Console.WriteLine();Console.WriteLine("MA na = new MAA();");MA na = new MAA();na.InvokeShowProtected();Console.WriteLine("MAA _na = (MAA)na;");MAA _na = (MAA)na;_na.InvokeShowProtected();Console.WriteLine();Console.WriteLine("MAA naa = new MAAA();");MAA naa = new MAAA();naa.InvokeShowProtected();Console.WriteLine("MAAA _naa = (MAAA)naa;");MAAA _naa = (MAAA)naa;_naa.InvokeShowProtected();Console.WriteLine();Console.ReadKey();}

View Code

  (6)、执行结果

MA a = new MA();
MA-InvokeShowProtectedMAA aa = new MAA();
MAA-InvokeShowProtected
MA b = (MA)aa;
MA-InvokeShowProtectedMAAA aaa = new MAAA();
MAAA-InvokeShowProtected
MAA bb = (MAA)aaa;
MAA-InvokeShowProtectedMA na = new MAA();
MA-InvokeShowProtected
MAA _na = (MAA)na;
MAA-InvokeShowProtectedMAA naa = new MAAA();
MAA-InvokeShowProtected
MAAA _naa = (MAAA)naa;
MAAA-InvokeShowProtected

View Code

B、子类方法改用new

MA不变,MAA如下:

public class MAA : MA{public new void InvokeShowProtected(){Console.WriteLine("MAA-InvokeShowProtected");}}

View Code

MAAA如下:

public class MAAA : MAA{public new void InvokeShowProtected(){Console.WriteLine("MAAA-InvokeShowProtected");}}

View Code

测试程序不变,结果和【A、方法签名和父类相同】一样。

C、子类方法改用override

MA不变,MAA如下:

public class MAA : MA{public override void InvokeShowProtected(){Console.WriteLine("MAA-InvokeShowProtected");}}

View Code

MAAA如下:

public class MAAA : MAA{public override void InvokeShowProtected(){Console.WriteLine("MAAA-InvokeShowProtected");}}

View Code

测试程序不变,结果如下:

MA a = new MA();
MA-InvokeShowProtectedMAA aa = new MAA();
MAA-InvokeShowProtected
MA b = (MA)aa;
MAA-InvokeShowProtectedMAAA aaa = new MAAA();
MAAA-InvokeShowProtected
MAA bb = (MAA)aaa;
MAAA-InvokeShowProtectedMA na = new MAA();
MAA-InvokeShowProtected
MAA _na = (MAA)na;
MAA-InvokeShowProtectedMAA naa = new MAAA();
MAAA-InvokeShowProtected
MAAA _naa = (MAAA)naa;
MAAA-InvokeShowProtected

View Code

测试结果表明:

如果子类和父类方法签名一样,那么默认是new,也就是子类方法是另外一个新的方法,所以调用对象“表面”是哪个类型,就调用该类型的方法,而不管其“真实”类型是什么。但是需要注意如下写:

MA a = new MA();MAA aaaddd = (MAA)a;aaaddd.InvokeShowProtected();

View Code

会在运行时报类型转化错误。
而override则是完全覆盖父类方法,也就是无论“表面”是什么类型,都会执行其“真实”的方法。

参考:

C#中 protected internal 和 internal 的区别

访问修饰符(C# 编程指南)

4、注意点

当使用override覆盖父类方法时,要求方法签名和父类一模一样,只是改成override,访问修饰符要求完全一样,否则报错。比如

父类:

public class MA{protected virtual void InvokeShowProtected(){Console.WriteLine("MA-InvokeShowProtected");}}

View Code

子类:

public class MAA : MA{public override void InvokeShowProtected(){Console.WriteLine("MAA-InvokeShowProtected");}}

View Code

编译报错:

Error    2    'ParentAndSon.MAA.InvokeShowProtected()': cannot change access modifiers when overriding 'protected' inherited member 'ParentAndSon.MA.InvokeShowProtected()'    D:\KiteSource\Temp\PageLoadAndOnload\ParentAndSon\MAA.cs    10    30    ParentAndSon

View Code

但是new可以,因为new是一个完全新的方法,比如父类:

public class MA{protected virtual void InvokeShowProtected(){Console.WriteLine("MA-InvokeShowProtected");}}

View Code

子类:

public class MAA : MA{public new void InvokeShowProtected(){Console.WriteLine("MAA-InvokeShowProtected");}}

View Code

孙类:

public class MAAA : MAA{public new void InvokeShowProtected(){Console.WriteLine("MAAA-InvokeShowProtected");}}

View Code

可以正常调用。

参考:

为什么子类重写父类的方法的访问修饰符,不能低于父类的方法访问权限?

(2014-03-12 18:22)

转载于:https://www.cnblogs.com/fiteg/p/3596701.html

[.net基础]访问修饰符相关推荐

  1. java访问修饰符详解——学java,零基础不怕,不只要理论,更要实践+项目,a href=http://www.bjweixin.com太原维信科技提供 /a...

    java访问修饰符详解--学java,零基础不怕,不只要理论,更要实践+项目 <a href=http://www.bjweixin.com>太原维信科技提供 </a> pub ...

  2. 访问修饰符作用范围由大到小是_9个java基础小知识

    一.面向对象和面向过程的区别 1. 面向过程 : 面向过程性能比面向对象高.因为类调用时需要实例化,开销比较大,比较消耗资源,所以当性能是最重要的考虑因素时(例如单片机.嵌入式开发.Linux/Uni ...

  3. 语法基础(三. 类,属性,方法,方法重载,方法重写,构造方法,访问修饰符)

    语法基础(三. 类,属性,方法,方法重载,方法重写,构造方法,访问修饰符) (如有错误,欢迎指正,感谢!) 类 类是面向对象的程序设计中的概念,实现信息的封装 概念: 类就是拥有相等行为和相同的属性的 ...

  4. day03--java基础编程:面向对象,构造方法,代码块讲解,this super,static,final,访问修饰符,方法重写,向上/下造型,main方法,抽象类,接口,设计模式,异常,内部类

    1 Day06–面向对象1 1.1 面向对象 1.1.1 概念 推荐看的书:Thinking in java 概念:所谓的面向对象是一种编程思想,通过这种思想可以把生活中的复杂事情变得简单化,从原来的 ...

  5. 【Java基础】多态、equals、造型cast、访问修饰符(public、protected、default、private)、static、final

    1.面型对象–多态 多态的概念:多态性就是指同样的消息被类的不同的对象接收时导致的完全不同的行为的一种现象.这里的消息即对类成员函数的调用. 实现上面调用宠物叫,每种宠物有各自的叫声 public c ...

  6. java基础之访问修饰符

    java基础之访问修饰符: java中一共有四种访问修饰符号,用于控制方法和属性的访问权限(范围): 1.公开级别:public 对外公开 2.受保护级别:protected 对子类和同一个包中的类公 ...

  7. day03--java基础编程:面向对象,构造方法,代码块讲解,this super,static,final,访问修饰符,方法重写,向上_下造型,main方法,抽象类,接口,设计模式,异常,内部类

    1 Day06–面向对象1 1.1 面向对象 1.1.1 概念 推荐看的书:Thinking in java 概念:所谓的面向对象是一种编程思想,通过这种思想可以把生活中的复杂事情变得简单化,从原来的 ...

  8. Java基础:Java中四种访问修饰符

    一.背景. 这篇文章主要介绍了Java中四种访问修饰符详细教程,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下.放假在家里休息,闲来无事,想 ...

  9. .NET 基础 一步步 一幕幕 [注释、命名规则、访问修饰符、数据类型、常量、变量]...

    注释.命名规则.访问修饰符.数据类型.常量.变量 话说一个不会写注释的程序猿的不是一个好吃货,我们本篇就从注释开始说起好了. 在C#中有三种注释: 第一种:单行注释  以//开头,后面的就是注释内容 ...

最新文章

  1. 《术以载道——软件过程改进实践指南》—第1章1.1节对CMMI的基本认识
  2. DF以某一列的元素筛选其中属于某个集合的元素的所有行(2个版本函数)
  3. 【数据结构与算法】之深入解析“地下城游戏”的求解思路与算法示例
  4. 将下列数组中奇数和偶数分别存放于两个不同的两个数组
  5. (转)微信公众平台关于fakeid和openid的解析
  6. 鸿蒙系统更新法定年龄,超25000位开发者参赛,华为首届鸿蒙开发者创新大赛创意满满...
  7. 程序员谨防加班猝死之十大建议(转)
  8. 松下机器人找原点步骤_松下机器人操作规程
  9. 蒟蒻的noip2015滚粗记
  10. 图文并茂说明Linux启动流程
  11. 单片机成长之路(51基础篇) - 023 N76e003 系统时钟切换到外部时钟
  12. 创新Sound Blaster Tactic3D Alpha耳机驱动v1.0官方版
  13. 点云纹理映射 matlab,Spherical Texture Mapping Method for Large-scale Point Cloud Data
  14. ArcMap批量等分割线流程
  15. Python-Level1-day16:异常处理try-exceptraise语句,for迭代原理,深入手写创建迭代器;yield浅出使用生成器
  16. tkinter窗口美化功能介绍 第一章 内部美化功能
  17. E-R图与数据库模型学习心得
  18. 树莓派打造无线共享打印机
  19. 用java实现matlab的随机函数randsrc(m,n,[alphabet; prob])
  20. Ubuntu环境下制作Windows U盘启动工具

热门文章

  1. 修改mysql数据库名称
  2. c++ mfc 曲线图像的实现资料网址
  3. Linux---高级IO
  4. 【PHP学习】—get请求传递参数(五)
  5. 上了高中应该注意什么?
  6. 听说有人快收权限掉了
  7. 你见过最奇葩的人和事是什么?
  8. 厦门GDP超过万亿需要多少年时间?
  9. 一切想要发财的人,你都要善于看到隐形的东西
  10. 经销商生意平台化是趋势