寒假学习日报(三十九)——scala包的补充与新的知识学习

  今天学习的东西有很多,主要是赶进度,写了不少样例代码方便理解。现在先记录一部分,若有补充会在该博客后续补上。

  scala的包知识

昨天已经写了一些关于包的知识,但并不完整,今天上午将包这一板块学完了,现在重新进行梳理:

scala中父类与子类的操作和java相比还是有很多不同的,我个人认为跟scala的灵活性有关,java在创建时包名文件名什么的都要一致,而scala不需要,这给了充分自由的同时,也造成了访问时的指定问题,而且为了能够对类进行更细致的操作,scala还有“包对象”的概念

//scala支持在一个文件中创建多个包
package com.chapter01.packageabout { //包com.chapter01.packageabout

  class OutPack { //在com.chapter01.packageabout下创建类
    var name = "Outpackage"

    def play(message: String): Unit = {
      println(this.name + " " + message)
    }
  }

  class User {
    //若父包想访问子包的类,需要声明
    def sayHello: Unit = {
      //可以使用import引入
      import com.chapter01.packageabout.newpackagetry.Monster
      val monster = new Monster
      //也可以通过路径声明
      val monster2 = new com.chapter01.packageabout.newpackagetry.Monster2

    }
  }
  //包对象
  //每一个包都可以有一个包对象,注意对象名字要和包名一样
  //在包对象中可以定义变量,方法,这些变量方法也可以在包中使用
  package object newpackagetry{
    val who = "what"
    def sayHi(): Unit ={
      println("Hi!")
    }
  }
  package newpackagetry { //包com.chapter01.packageabout.newpackagetry

    class Pack { //在com.chapter01.packageabout.newpackagetry下创建类Pack
      var name = "package"

      def play(message: String): Unit = {
        println(this.name + " " + message)
      }
    }

    class User {

    }

    class Monster {

    }

    class Monster2 {

    }

    object packagetry { //在com.chapter01.packageabout.newpackagetry下创建object packagetry
      def main(args: Array[String]): Unit = {
        println("ok")
        //可以直接访问父包的类
        val op = new OutPack
        println("op=" + op)
        //若子包和父包存在同名类,就近原则
        val user = new User
        println("user=" + user)
        //若想访问同名父包类,声明路径
        val user2 = new com.chapter01.packageabout.User()
        //使用包对象中的变量和方法
        println("包对象中的who变量:" + who)
        print("包对象中的sayHi方法:")
        sayHi()
      }
    }

  }

}

 而和java相同,scala同样有public,protected,private这样的访问权限划分,而且在对protected的访问处理上,scala要更严苛一些,而且在设置访问权限的时候,也有了更多的方法。下面伴生类与伴生对象就是scala在去掉static之后诞生的。

package com.chapter01.packageabout

object visitabout {
  def main(args: Array[String]): Unit = {
    val c = new Clerk()
    c.showInfo()
    Clerk.test(c)
    val v1 = new vper()
    //增加权限后可以访问指定权限的私有属性
    println(v1.name)
  }
}

class Clerk {
  //默认是public权限,但注意scala中没有public关键字,且反编译时会发现实际上是private类型
  var name: String = "Jack"
  private var sal: Double = 8099.9
  //保护权限,同包无法使用,只能在子类中使用
  protected var age = 10

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

//当出现class Clerk和object Clerk时
//class Clerk为伴生类,object Clerk为伴生对象
//伴生类写非静态内容,伴生对象是静态内容
object Clerk{
  def test(c: Clerk): Unit ={
    //伴生对象中可以访问伴生类的私有属性
    println("test()name=" + c.name + " sal=" + c.sal)
  }
}

class vper {
  //增加包访问权限
  private[packageabout] val name = "vper"
}

 scala对包的引入有很多的手段

package com.chapter01.packageabout

import scala.beans.BeanProperty

class BeanAbout {
  //使用相对路径引入包
  @BeanProperty var age: Int = _
  //使用相对路径引入包2
  @scala.beans.BeanProperty var age2: Int = _
  //使用绝对路径引入包
  @_root_.scala.beans.BeanProperty var age3: Int = _
}
object inbean {
  def main(args: Array[String]): Unit = {

  }
}

我们都知道scala是用于spark进行数据处理的,效率就是关键,为了提高效率,减少包的索引是一个考量因素,因此scala对引入包的处理有了更多的手段:

package com.chapter01.packageabout

import scala.beans._
import scala.collection.mutable //表示将该包所有内容引入,等价于*

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

  }
}

class User {

  import scala.beans.BeanProperty //需要时引入,作用域在{}内
  @BeanProperty var name: String = _

  def test(): Unit = {
    //选择器引入包的指定内容
    import scala.collection.mutable.{HashMap, HashSet}
    var map = new HashMap()
    var set = new HashSet()
  }

  def test2(): Unit = {
    //将java.util.HashMap重命名,这是临时生效的
    import java.util.{HashMap => JavaHashMap, List}
    import scala.collection.mutable._
    var map = new HashMap()
    var javamap = new JavaHashMap()
  }

  def test3(): Unit ={
    //还可以将不用的类隐藏掉,仍然以HashMap为例
    //第一个_指HashMap被隐藏,第二个_指引入java.util包下的其他内容
    import java.util.{HashMap => _, _}
    import scala.collection.mutable._
    //此时再声明HashMap不会使用java.util中的HashMap,idea中也不会给提示
    var map = new HashMap()
  }
}

以上是对scala包操作的一些总结。

下面说一些新的知识,这些知识我后续可能还会有一些补充,在半夜12点之前。若是过了12点,那新学的内容会在明日的日报中进行总结

继承:

package com.chapter01.extendsabout

object Extends01 {
  def main(args: Array[String]): Unit = {
    val sub = new Sub()
    sub.sayOK()
  }
}

//父类(基类)
class Base {
  var n1: Int = 1 //public n1(), public n1_$eq()
  protected var n2: Int = 2
  private var n3: Int = 3

  def test100(): Unit = { //默认public test100()
    println("base 100")
  }

  protected def test200(): Unit = { //反编译属于public类型,但只有子类可访问,同包不可访问
    println("base 200")
  }

  private def test300(): Unit = {
    println("base 300")
  }
}

//Sub继承
class Sub extends Base {
  def sayOK(): Unit = {
    this.n1 = 20 //访问本质仍然是this.n1_$eq()
    this.n2 = 40
    //n3无法访问,因为是私有类型
    println("范围:" + this.n1 + this.n2)
    test100()
    test200()
    //test300()同样无法访问,因为也是私有类型
  }
}

 重写:

package com.chapter01.extendsabout

object methodoverride01 {
  def main(args: Array[String]): Unit = {
    val empo = new OEmp
    empo.printName()
  }
}

class OPerson {
  var name: String = "John"
  def printName(): Unit ={
    println("OPerson printName()" + name)
  }
}

class OEmp extends OPerson {
  //重写的方法需要声明override
  override def printName(): Unit = {
    println("OEmp printName()" + name)
    //在子类中需要调用重写的父类方法时,使用super
    super.printName()
  }
}

 类与类之间的类型转换:

package com.chapter01.extendsabout

object TypeConvert {
  def main(args: Array[String]): Unit = {
    //classOf:可以得到类名
    println(classOf[String])
    val s = "king"
    println(s.getClass.getName) //使用反射机制

    //isInstanceOf asInstanceOf
    var o1 = new OPerson2
    var e1 = new OEmp2
    //将子类引用给父类(向上转型),这步是自动执行的,不需要声明isInstanceOf
    o1 = e1
    println(o1.isInstanceOf[OEmp2]) //true
    //将父类引用重新转成子类引用(多态),向下转型
    var e2 = o1.asInstanceOf[OEmp2]
    e2.sayHello()
  }
}
class OPerson2 {
  var name: String = "John"
  def printName(): Unit ={
    println("OPerson printName()" + name)
  }
  def sayHi(): Unit ={
    println("Hi")
  }
}

class OEmp2 extends OPerson2 {
  //重写的方法需要声明override
  override def printName(): Unit = {
    println("OEmp printName()" + name)
    //在子类中需要调用重写的父类方法时,使用super
    super.printName()
  }
  def sayHello(): Unit ={
    println("Hello")
  }
}

原文地址:https://www.cnblogs.com/20183711PYD/p/14409423.html