python机器学习爬虫Scala学习

Scala类的主辅构造器,单例对象,伴生对象,工厂模式

2020-09-16  本文已影响0人  xiaogp

摘要:scala构造器this关键字伴生对象单例对象工厂模式

类的主构造器

class Student1(var name: String, var age: Int) {
  def getOne: String = "name" + ":" + name + " " + "age" + ":" + age
}
class Student2(var name: String = "gp", var age: Int = 13) {
  def getOne: String = "name" + ":" + name + " " + "age" + ":" + age
}
class Student2(private var name: String = "gp", private var age: Int = 13) {
  def getOne: String = "name" + ":" + name + " " + "age" + ":" + age
}

类的辅构造器


辅构造器的基本写法,调用this关键字

class Student3 {
  var name: String = _
  var age: Int = _

  // this辅助构造器
  def this(name: String, age: Int) {
    // 辅助构造函数必须调用主构造函数或者通过this()之间相互调用
    this()
    this.name = name
    this.age = age
  }

  def getOne: String = "name" + ":" + name + " " + "age" + ":" + age
}

申明成员变量初始值为空,并且申明为private

class Student4 {
  private var name: String = _
  private var age: Int = _

  def this(name: String, age: Int) {
    this() // 调用主构造器,主构造器无参
    this.name = name
    this.age = age
  }

  def getOne: String = "name" + ":" + name + " " + "age" + ":" + age
}

有多个辅构造器,每个辅构造器必须调用已有辅构造器或者主构造器

class Student5 {
  private var name: String = _
  private var age: Int = _

  def this(name: String) {
    this()
    this.name = name
  }

  //  def this(name: String, age: Int) {
  //    this(name)  // 调用第一个辅构造器
  //    this.age = age
  //  }

  def this(name: String, age: Int) {
    this() // 调用主构造器
    this.name = name
    this.age = age
  }

  def getOne: String = "name" + ":" + name + " " + "age" + ":" + age
}

使用辅构造器配合主构造器一起设定入参,辅构造器支持Array传参,实际上将Array转化格式传给主构造器

class Student6(var name: String, var age: Int) {
  def this(param: Array[Any]) {
    this(param(0).asInstanceOf[String], param(1).asInstanceOf[Int])
  }

  def getOne: String = "name" + ":" + name + " " + "age" + ":" + age
}

判断类相等

需要重写equals方法,使用isInstanceOf判断对象类型,如果类型一致比较成员变量是否相等

class Student8(var name: String, var age: Int) {
  override
  def equals(obj: Any): Boolean = {
    if (!obj.isInstanceOf[Student8]) {
      false
    } else {
      this.name == obj.asInstanceOf[Student8].name
      true
    }
  }
}

单例对象

Scala中单例对象使用object关键字(类使用class关键字),单例对象不带参数,而类可以。单例对象是延迟创建的,当它第一次被使用时创建
创建一个单例对象

object ObjectTest {
  println("创建一个单例对象")
  private var num: Int = 1

  def getNum(): Unit = {
    num += 1
    println(num)
  }
}

单例可以在程序的任何其他地方被引用,在其他脚本import路径导入调用

import ObjectTest.getNum

object ObjectTest2 {
  def main(args: Array[String]): Unit = {
    getNum()
    getNum()
    getNum()
  }
}

输出2,3,4,可见只创建一个对象实例,公用的一个num

创建一个单例对象
2
3
4

一个实际案例使用object构造MySQL工具类对象单例,对象内部实现方法传参构造单例MySQL连接池对象

import org.apache.commons.dbcp.BasicDataSource
import java.util.Properties

object MysqlUtils {
  private var mysqlConns: BasicDataSource = null
  def getConnPool(prop: Properties) = {
    this.synchronized {
      if (null == mysqlConns) {
        mysqlConns = new BasicDataSource()
        mysqlConns.setDriverClassName(prop.getProperty("jdbc.driver"))
        mysqlConns.setUrl(prop.getProperty("jdbc.url"))
        mysqlConns.setUsername(prop.getProperty("jdbc.user"))
        mysqlConns.setPassword(prop.getProperty("jdbc.passwd"))
        mysqlConns.setMaxActive(4)
        mysqlConns.setMaxIdle(4)
        mysqlConns.setMinIdle(2)
        mysqlConns.setInitialSize(4)
        mysqlConns.setMaxWait(10000)
        mysqlConns.setTestWhileIdle(true)
        mysqlConns.setValidationQuery("select 1")
        mysqlConns.setValidationQueryTimeout(10000)
        mysqlConns.setTimeBetweenEvictionRunsMillis(10000)
      }
      mysqlConns
    }
  }
}

伴生对象

当一个单例对象和某个类共享一个名称时,这个单例对象称为 伴生对象。 同理,这个类被称为是这个单例对象的伴生类。类和它的伴生对象必须定义在同一个源文件中。类和它的伴生对象可以互相访问其私有成员。
一个例子在伴生类中调用伴生对象的私有变量,在其他脚本依旧需要new一个对象。

class PairTest {
  private var name: String = _
  private var age: Int = _

  def this(name: String, age: Int) {
    this()
    this.name = name
    this.age = age
  }

  // 在class中访问object中的私有变量
  def getOne(): Unit = {println("name" + " " + name + " " + "age" + " " + age + " " + "degree" + " " + PairTest.degree + " " + "city" + " " + PairTest.city)}

}

object PairTest {
  private val degree: String = "本科"
  private val city: String = "苏州"

  def main(args: Array[String]): Unit = {
    val pairTest: PairTest = new PairTest("gp", 12)
    pairTest.getOne()
  }
}
name gp age 123 degree 本科 city 苏州

工厂模式

通常将伴生对象作为工厂使用,在伴生对象中使用工厂模式,创建单例对象,在其他脚本getInstance不需要new

import java.util.Properties

class PairTest {
  private var name: String = _
  private var age: Int = _

  private def this(name: String, age: Int) {
    this()
    this.name = name
    this.age = age
  }

  def getOne(): Unit = {
    println("name" + " " + name + " " + "age" + " " + age)
  }

}

object PairTest {
  private var instance: PairTest = _

  def getInstance(prop: Properties): PairTest = {
    if (instance == null) {
      this.synchronized {
        if (instance == null) {
          instance = new PairTest(prop.getProperty("name"), Integer.parseInt(prop.getProperty("age")))
        }
      }
    }
    instance
  }

  def main(args: Array[String]): Unit = {
    val prop: Properties = new Properties() {{
      setProperty("name", "gp")
      setProperty("age", "12")
    }}
    PairTest.getInstance(prop).getOne()  // name gp age 12
  }
}
上一篇下一篇

猜你喜欢

热点阅读