每日一篇大数据每日一篇Scala程序员技术栈

Scala(四)-②-面相对象中级-包-包对象-访问控制权限

2018-11-14  本文已影响1人  sixleaves

① 包(package)

Why

包的三个主要作用是

How

Java中的包

Scala中的包
Scala中包的命名规则
命名规范

一般是小写字母+小圆点一般是, com.公司名.项目名.业务模块名

object TestTiger {

  def main(args: Array[String]): Unit = {

    val tiger1 = new com.sweetcs.bigdata.scala.day04.chapter07.packagedemo.scala.xh.Tiger
    val tiger2 = new com.sweetcs.bigdata.scala.day04.chapter07.packagedemo.scala.xm.Tiger

    println(tiger1 +"\t"+ tiger2)

  }
}

Details

graph TD
C(目录结构)
C --> |无需对应| D(源文件)
C --> |和目录结构对应| E(字节码文件)

第二种

package com.sweetcs
package scala
class Person{
  val name = "lisi"
  def play(message: String): Unit ={
  }
}
代码说明

第三种(最常用,方便在一个文件中的不同包中创建class和trait)

/**
  * @author sweetcs
  */
object AdvincePackageDemo {
  def main(args: Array[String]): Unit = {

  }
}

package com.sweetcs{
  package scala{
    class Person{
      val name = "lisi"
      def play(message: String): Unit ={
      }
    }

    object Student {

    }

  }
}

编译后可以对应查看到如下内容


package com.sweetcs{
  package scala{

    class User {

    }


    class Person{
      val name = "lisi"
      def play(message: String): Unit ={
      }
    }

    object Student {

    }
  }


  package scala2 {
    class User {

    }
  }
}
image.png
package com.sweetcs{
  package scala{

    class User {

    }


    class Person{
      val name = "lisi"
      def play(message: String): Unit ={
      }
    }

    object Student {

    }
  }


  package scala2 {
    class User {

    }

    object TestSubPackage {
      def main(args: Array[String]): Unit = {

        val user = new User // 不指定权限定类名使用最近原则
        println(user)

        val user2 = new com.sweetcs.scala.User  // 指定某个类要用权限定类名
        println(user2)

      }
    }
  }
}  
package com.sweetcs{
  package scala{

    class User {

      def sayHello(): Unit = {
        import com.sweetcs.scala.scala12.UserInScala12
        val userInScala= new UserInScala12
        userInScala.sayHello()
      }

    }

    package scala12 {

      class UserInScala12 {
        def sayHello(): Unit = {

        }
      }

    }
  }
}

②-包对象

Why

尽管我们可以在包中写classtraitobject但是没法写函数方法或者变量.因为JVM的限制,无法这样做.于是scala提出了包对象技术就是为了解决这个缺陷,我们可以将函数方法或者变量写在包对象中,相当于对包做了扩展,这样以后我们可以在包里调用这些写函数方法或者变量.

How

语法

package object 要扩展的包名 {
   
}
Demo
package com.sweetcs {

  package object packageObject {

    def sayHello(): Unit = {
      println("hello packageobject")
    }

  }

  package packageObject {

    class User {

      def callPackageObject(): Unit = {
        sayHello()
      }
    }

    object Test {
      def main(args: Array[String]): Unit = {
        val user = new User
        user.callPackageObject()
      }
    }

  }
}

What

包对象的运行原理,看反编译.如下图

包对象生成了两个对象package.classpackage$.class

在User类里,调用的是package$.MODULE$.sayHello().而这个MODULE$package$类的一个静态实例对象.

如下核心的反编译源码

具体的调用关系

Details

③-Scala的访问修权限和包可见性

Why

几乎现代的所有编程语言都有访问控制权限,Scala也有,大部分和java类似,旦细节少也有不同.Scale中有private、protected、public、默认、四种访问权限修饰符

How

规则和语法
private[排除的包] var 成员变量名 :成员变量类型 = 变量值
Demo

package com.sweetcs.packagedemo.scala.advincepackage

/**
  * @author sweetcs
  */
object ModifierDetailsDemo {

  def main(args: Array[String]): Unit = {

    val  c = new User()

    // public
    println(c.name)
    c.showInfo()

    // protected
    //  c.address 错误 无继承关系无法访问
    // c.protectedMethod 错误 无继承关系无法访问

    // private
    // c.privatedMethod 错误 私有方法无法访问

    c.packagePrivateMethod()
    println(c.phone)

  }


}

class User {
  var name : String = "jack"
  private var sal : Double = 9999.9
  protected var address :String = "beijing"
  private[advincepackage] var phone :String = "110"

  def showInfo(): Unit = {
    println(" name " + name + " sal= " + sal)
  }

  protected def protectedMethod(): Unit = {
    println("called protectedMethod")
  }

  private def privatedMethod(): Unit = {
    println("called privateMethod")
  }

  private[advincepackage] def packagePrivateMethod(): Unit = {
    println("called packagePrivateMethod")
  }

}
object User{
  def test(c : User): Unit = {
    //这里体现出在伴生对象中,可以访问c.sal
    println("test() name=" + c.name + " sal= " + c.sal)
  }
}

Details

④-Scale中包的引入

Why

包的引入技术对应打包技术,用来将在一个包内的类引入使用.

How

Scalae中的包引入分为以下几种

/**
  * @author sweetcs
  */
object ImportDetailDemo {
  def main(args: Array[String]): Unit = {

  }
}


class User {
  // 1.指定到一个类文件
  //  import scala.beans.BeanProperty

  // 2.指定到几个类文件
  import scala.beans.{BeanProperty,BeanDescription}
  @BeanProperty var name : String = ""
 
  // 3.指定到父包,批量引入类文件
  //  import scala.beans._
  
  // 4.给引入的类文件的起别名
  import java.util.{HashMap => JavaHashMap}
  var cache = new JavaHashMap()
  
  // 5.隐藏掉引入的类,引入剩余类(很少用,主要为了解决命名冲突,如果该类不用)
  import java.util.{ HashMap=>_, _} // 含义为 引入java.util包的所有类,但是忽略 HahsMap类.
  var set = new HashSet() 

}

class Dog {
  import scala.beans.BeanProperty
  @BeanProperty var name : String = ""
}
上一篇下一篇

猜你喜欢

热点阅读