构造函数

Posted cjm123

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了构造函数相关的知识,希望对你有一定的参考价值。

构造函数可以标记为 publicprivateprotectedinternal 或 protectedinternal。这些访问修饰符定义类的用户构造该类的方式。有关更多信息,请参见访问修饰符

使用 static 关键字可以将构造函数声明为静态构造函数。在访问任何静态字段之前,都将自动调用静态构造函数,它们通常用于初始化静态类成员。有关更多信息,请参见静态构造函数

 

 

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吧

 

  • public:完全开放,谁都能访问。
  • private:完全封闭,只有类自身可以访问。
  • internal:只对相同程序集,或使用InternalVisibleToAttribute标记的程序集开放。 当前程序集可见 internal 内部成员只有在同一程序集中的文件内才是可访问的
  • protected:只对子类开放。
  • protected和internal修饰同一个成员,这使得类中的一个成员可以拥有5种不同的访问权限

 

pubic、private和protected级别的含义是清晰而纯粹的,而internal的开放程度则是像是一个“灰色地带”。

 

 

class A{
     internal A()
    {}
}

这段代码是表示这个构造方法只能在同一个程序文件中被访问。

 

http://www.cnblogs.com/JeffreyZhao/archive/2009/08/26/internal-member-is-bad-smell.html

 







































以上是关于构造函数的主要内容,如果未能解决你的问题,请参考以下文章

Android 逆向ART 脱壳 ( DexClassLoader 脱壳 | DexClassLoader 构造函数 | 参考 Dalvik 的 DexClassLoader 类加载流程 )(代码片段

防止 Proguard 删除片段的空构造函数

无法解析片段中的 ViewModelProvider 构造?

为啥要避免片段中的非默认构造函数?

片段真的需要一个空的构造函数吗?

这个嵌套类构造函数片段可以应用于泛型类吗?