zoukankan      html  css  js  c++  java
  • private 和 protected 构造函数的选择

    实现单例模式的时候经常要把构造函数标记为private 和protected以防止外部直接通过new操作符 构造一个新的实例

    众所周知 private 和protected的主要区别就是 后者允许子类调用被标记为protected的方法

    另外一个常识: 使用new操作符构造一个子类的过程中 .net会先构造一个父类出来 ,如此递归 直到object对象

    那么也就是说 标记为protected的时候 实际上还是可以通过继承的方式间接的构造父类对象

    代码如下: (new ClassB的同时也间接的new ClassA了)

    public class ClassA
    {
    protected ClassA()
    {
    }
    }

    public class ClassB : ClassA
    {
    public ClassB()
    {
    }
    }

    private则没有这个问题, 但是! 标记为private以后实际上也就意味着没有类型可以继承private了

    当然你可以编写如下代码: (但是编辑器会告诉你 'ClassA.ClassA()' is inaccessible due to its protection level)

    public class ClassA
    {
    private ClassA()
    {
    }
    }

    public class ClassB : ClassA
    {
    public ClassB()
    {
    }
    }

    原因就是构造ClassB的时候没法调用ClassA的构造函数

    从开发角度讲,如果一个类设计的时候就不想被继承或者不能被继承,那么应该标记为Sealed , 以防止别人不小心继承了这个类,那么这里的ClassA应该被标记为密封的

    那么如果是为了单例模式  private是一个比较好的选择,  密封类并protected也是一个可以使用的实现

    有的时候屏蔽构造函数并不是想使用单例模式 ,而且想通过这种方式规范调用方的行为

    代码如下:

    public class ClassA
    {
    protected ClassA()
    {
    }

    public ClassA Create()
    {
    //这里可以做特殊操作 例如给ClassA的属性赋初始值,或者写点日志什么的,反正你爱干嘛干嘛
    return new ClassA();
    }
    }

    那么这个时候我个人还是建议 使用protected的构造函数,因为这样不会剥夺被继承的能力

    在我 "某项目要调用现有的100多个DLL " 这个项目中  目前就需要用到这样的能力,通过Create这样创建出来的ClassA 实际上是ClassA的一个子类, 其中做了一个特别的处理

     .net中的 System.Net.WebRequest.Create 方法 就是这样的一个例子

    PS: private构造函数的问题就是间接剥夺了被继承的可能,如果这样 建议把类型标记为密封的

    PS: 如果不想剥夺被继承的能力,那么就使用protected吧

  • 相关阅读:
    四种常见系统架构介绍
    NC-UAP客户化开发-数据建模
    NC-UAP客户化开发-4.NC数据库持久化技术
    NC-UAP客户化开发-NC基础技术
    NC-UAP客户化开发-开发环境搭建
    Docker: 使用socket 代理
    Disk:磁盘管理之LVM和系统磁盘扩容
    Grafana & Graphite & Collectd:监控系统
    ELK:收集k8s容器日志最佳实践
    Virus:病毒查杀
  • 原文地址:https://www.cnblogs.com/PurpleTide/p/1954211.html
Copyright © 2011-2022 走看看