scala的访问修饰符

  包、类或对象的成员可以用访问修饰符private和protected做标记,从而将成员的访问限制在代码确定的区域中。

一、Scala里的访问修饰符类型


1.私有成员
  用private关键字修饰,带有此标记的成员仅在包含了成员定义的类或对象内部可见,同样的规则还适用内部类。

class Outer{
    class Inner{
    private def f(){println("f")}
    class InnerMost{
        f() //OK
        }
    }
    (new Inner).f() //Error
}

  (new Inner).f( )访问不合法是应为f在Inner中被声明为private,而访问不在类Inner之内。但在InnerMost里访问f就没有问题,因为这个访问包含在Inner类之内。Java中允许这两种访问,因为它允许外部类方位器内部类的私有成员。

2.受保护成员
  在scala里,对保护成员的访问比java更严格一些。因为它只允许保护成员在定义了该成员的的类的子类中被访问。而在java中,用protected关键字修饰的成员,除了定义了该成员的类的子类可以访问,同一个包里的其他类也可以进行访问。

package p{
    class Super{
        protected def f() {println("f")}
        }
    class Sub extends Super{
        f()
    }
    class Other{
     (new Super).f()//Error
     }
    }

  上例中,Sub类对f的访问没有问题,因为f在Super中被声明为protected,而Sub是Super的子类。相反,Other对f的访问不被允许,因为other没有继承自Super。而后者在java里同样被认可,因为Other与Sub在同一包里。

3.公开成员

  Scala中,没有任何标记为private或protected的成员都是公开的,它没有显示的指定修饰符。这样的成员在任何地方都可以被访问。

二、与Java的不同之处


  1、如果不指定任何访问修饰符,Java默认为包内可见。Scala默认为public(public不再是关键字)。
  2、Java要么对当前包所有的类可见,要么对任何一个都不可见。Scala可以对可见性进行“细粒度”的控制。后面将做说明。
  3、Java的protected可见性包括了派生类和当前包的任何类。Scala只有本类内和派生类才可见,同一个包的其他类都不可见。而且,在类外只有派生类才能访问到protected成员,本类不行。
  4、Java的封装是在类一级。在实例方法里,可以访问当前类的任何私有字段和方法。这也是Scala的默认做法;不过,也可以限制为当前实例。

三、更细粒度的控制


  Scala中,访问修饰符可以通过使用限定词强调。格式为:

private[x] 或 protected[x]

  这里的x指代某个所属的包、类或单例对象。如果写成private[x],读作“这个成员除了对[…]中的类或[…]中的包中的类及它们的伴生对像可见外,对其它所有类都是private。这种技巧在横跨了若干包的大型项目中非常有用,它允许你定义一些在你项目的若干子包中可见但对于项目外部的客户却始终不可见的东西。

示例:

package bobsrocckets{
    package navigation{
        private[bobsrockets] class Navigator{
         protected[navigation] def useStarChart(){}
         class LegOfJourney{
             private[Navigator] val distance = 100
             }
            private[this] var speed = 200
            }
        }
        package launch{
        import navigation._
        object Vehicle{
        private[launch] val guide = new Navigator
        }
    }
}

  上述例子中,类Navigator被标记为private[bobsrockets]就是说这个类对包含在bobsrockets包里的所有的类和对象可见。比如说,从Vehicle对象里对Navigator的访问是被允许的,因为对象Vehicle包含在包launch中,而launch包在bobsrockets中,相反,所有在包bobsrockets之外的代码都不能访问类Navigator。

【注意】
(1) private限定词也可以是他直接所属的包,比如上例中的guide这种访问修饰符等价于java的包私有访问。

(2) 当某类里的成员用protected[x]修饰时,表示允许该类的所有子类及修饰符所属的包、类或对象X访问带有此标记的定义。例如,useStarChart方法能被Navigator所有子类及包含在navigation包里的所有代码访问。

(3) 当private[x]里面的x是this时,表示仅能在包含了定义的同一个对象中被访问,这种定义称为对象私有。如类Navigator里面的speed的定义。这意味着所有的访问必须不仅是在Navigator类里,而且还要是同一个Navigator实例内发生的。因此在Navigator内访问“speed”和“this.speed”是合法的。把成员标记为private[this],可以保证它不能被同一个类中的其它对象访问。

整理自scala编程。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值