java经典小知识

机构:郑州北大青鸟 时间:2015-11-30 点击:638

  任何用private 关键字声明的成员只对定义它的类型可见,包括它的实例。当应用于类型时,private 限制其可见性为包含它的package。

  // code-examples/BasicOOP/scoping/private-wont-compile.scala // WON'T COMPILE package scopeA { class PrivateClass1(private val privateField1: Int) { private val privateField2 = 1 def equalFields(other: PrivateClass1) = (privateField1 == other.privateField1) && (privateField2 == other.privateField2) && (nested == other.nested) class Nested { private val nestedField = 1 } private val nested = new Nested } class PrivateClass2 extends PrivateClass1(1) { val field1 = privateField1 // ERROR val field2 = privateField2 // ERROR val nField = new Nested()。nestedField // ERROR } class PrivateClass3 { val privateClass1 = new PrivateClass1(1) val privateField1 = privateClass1.privateField1 // ERROR val privateField2 = privateClass1.privateField2 // ERROR val privateNField = privateClass1.nested.nestedField // ERROR } private class PrivateClass4 class PrivateClass5 extends PrivateClass4 // ERROR protected class PrivateClass6 extends PrivateClass4 // ERROR private class PrivateClass7 extends PrivateClass4 } package scopeB { class PrivateClass4B extends scopeA.PrivateClass4 // ERROR } 编译这个文件会产生如下输出。

  14: error: not found: value privateField1 val field1 = privateField1 ^ 15: error: not found: value privateField2 val field2 = privateField2 ^ 16: error: value nestedField cannot be accessed in PrivateClass2.this.Nested val nField = new Nested()。nestedField ^ 20: error: value privateField1 cannot be accessed in scopeA.PrivateClass1 val privateField1 = privateClass1.privateField1 ^ 21: error: value privateField2 cannot be accessed in scopeA.PrivateClass1 val privateField2 = privateClass1.privateField2 ^ 22: error: value nested cannot be accessed in scopeA.PrivateClass1 val privateNField = privateClass1.nested.nestedField ^ 27: error: private class PrivateClass4 escapes its defining scope as part of type scopeA.PrivateClass4 class PrivateClass5 extends PrivateClass4 ^ 28: error: private class PrivateClass4 escapes its defining scope as part of type scopeA.PrivateClass4 protected class PrivateClass6 extends PrivateClass4 ^ 33: error: class PrivateClass4 cannot be accessed in package scopeA class PrivateClass4B extends scopeA.PrivateClass4 ^ 9 errors found 现在,PrivateClass2 不能访问它的父类PrivateClass1 的private 成员。正如错误消息指出的,它们对于子类来说完全不可见。它们也不能存取嵌套类的private 字段。

  正如protected 访问的例子一样,PrivateClass3 不能访问它使用的PrivateClass1 实例的private 成员。不过注意,equalFields 方法可以访问其它实例的private 成员。

  PrivateClass5 和PrivateClass6 的声明失败了,因为如果允许的话,它们等于允许PrivateClass4 “跳出它的定义域”。然而,PrivateClass7 的声明成功了,因为它同时被定义为了private。令人好奇的是,我们上一个例子中能够正确地定义一个继承自protected 类的public 类。

  最后,和protected 类型声明一样,private 类型不能在包含它的package 之外被继承。

  局部 Private 和Protected 可见性

  Scala 允许你用scoped private 和protected 可见性声明来更精细地调整可见性的范围。注意,在局部声明中使用proviate 或者protected 是可互换的,因为它们除了应用到继承的成员上的可见性之外,其它都是一样的。

  提示

  虽然在大多数情况下选择任何一个都能活动相同的效果,在代码中使用private 还是比protected 更常见一些。在Scala 的核心库里,这个比利大概是5:1。

  让我们从scoped private 和scoped protected 之间的唯一区别入手,来看看当成员有这些局部性声明的时候,它们在继承机制下是如何工作的。

  // code-examples/BasicOOP/scoping/scope-inheritance-wont-compile.scala // WON'T COMPILE package scopeA { class Class1 { private[scopeA] val scopeA_privateField = 1 protected[scopeA] val scopeA_protectedField = 2 private[Class1] val class1_privateField = 3 protected[Class1] val class1_protectedField = 4 private[this] val this_privateField = 5 protected[this] val this_protectedField = 6 } class Class2 extends Class1 { val field1 = scopeA_privateField val field2 = scopeA_protectedField val field3 = class1_privateField // ERROR val field4 = class1_protectedField val field5 = this_privateField // ERROR val field6 = this_protectedField } } package scopeB { class Class2B extends scopeA.Class1 { val field1 = scopeA_privateField // ERROR val field2 = scopeA_protectedField val field3 = class1_privateField // ERROR val field4 = class1_protectedField val field5 = this_privateField // ERROR val field6 = this_protectedField } } 编译这个文件会产生如下输出。

  17: error: not found: value class1_privateField val field3 = class1_privateField // ERROR ^ 19: error: not found: value this_privateField val field5 = this_privateField // ERROR ^ 26: error: not found: value scopeA_privateField val field1 = scopeA_privateField // ERROR ^ 28: error: not found: value class1_privateField val field3 = class1_privateField // ERROR ^ 30: error: not found: value this_privateField val field5 = this_privateField // ERROR ^ 5 errors found Class2 里的前两个错误说明,在同一个package 内的继承类,不能引用父类或者this 的scoped private 成员,但是它可以引用包含Class1 和Class2 的package (或者类型)的private 成员。

  相比之下,对于package 之外的继承类,它无法访问Class1 的任何一个scoped private 成员。

  然而,所有的scoped protected 成员对于两个继承类来说都是可以见的。

  我们会在后面剩下的例子和讨论中使用scoped private 声明,因为在Scala 库中,scoped private 比scoped protected 更加常见一些,前面的继承情况并不是其中一个因素。

  让我们从最严格的可见性开始,private[this],它也对类型成员起作用。

  // code-examples/BasicOOP/scoping/private-this-wont-compile.scala // WON'T COMPILE package scopeA { class PrivateClass1(private[this] val privateField1: Int) { private[this] val privateField2 = 1 def equalFields(other: PrivateClass1) = (privateField1 == other.privateField1) && // ERROR (privateField2 == other.privateField2) && (nested == other.nested) class Nested { private[this] val nestedField = 1 } private[this] val nested = new Nested } class PrivateClass2 extends PrivateClass1(1) { val field1 = privateField1 // ERROR val field2 = privateField2 // ERROR val nField = new Nested()。nestedField // ERROR } class PrivateClass3 { val privateClass1 = new PrivateClass1(1) val privateField1 = privateClass1.privateField1 // ERROR val privateField2 = privateClass1.privateField2 // ERROR val privateNField = privateClass1.nested.nestedField // ERROR } } 编译这个文件会产生如下输出。

  更多知识:郑州软件工程师培训学校

返回顶部