首页 > 其他 > 详细

Scala 学习 (六) 面向对象

时间:2019-06-01 13:20:35      阅读:58      评论:0      收藏:0      [点我收藏+]

一,scala单例对象

二,scala类

  2.1 类定义,主构造器,赋值构造器

  2.2 访问权限

  2.3 伴生类,apply方法

三,特质

四,抽象类

五,继承

  5.1 final关键字

  5.2 type关键字

六,样例类,样例对象

七,匹配模式

  7.1 匹配字符串,类型,守卫

  7.2 匹配数组

  7.3 匹配集合

  7.4 匹配元组

  7.5 匹配样例类,样例对象

 

 

 

正文

一,scala单例对象 

  在 Scala 中,是没有 static 这个东西的,但是它也为我们提供了单例模式的实现方法,那就是使用关键字 object, object 对象不能带参数

  如下实例:

/** * 单例对象
*/

object ScalaSingleton {
  def saySomething(msg: String) = {
    println(msg)   } } object test {   def main(args: Array[String]): Unit
= {
    ScalaSingleton.saySomething("滚犊子....")
    println(ScalaSingleton)
    println(ScalaSingleton)     
// 输出结果:     // 滚犊子....     // cn.demo.ScalaSingleton$@28f67ac7     // cn.demo.ScalaSingleton$@28f67ac7   } }

二,scala类

  2.1 类定义,主构造器,赋值构造器

  定义类,和一些注意事项:

/*
*    在 Scala 中,类并不用声明为 public。
*    如果你没有定义构造器, 类会有一个默认的空参构造器
*    var 修饰的变量, 这个变量对外提供 getter setter 方法
*    val 修饰的变量, 对外提供了 getter 方法,没有 setter
**/

class Student {
    // _ 表示一个占位符, 编译器会根据你变量的具体类型赋予相应初始值
    // 注意: 使用_ 占位符是, 变量类型必须指定
    var name: String=_
    var age: Int=_
    //    错误代码, val 修饰的变量不能使用占位符
    //    val age: Int = _  因为val修饰的不变的变量
    val school: String = "beida"
}

object Test{
    var name="zhangsan"
    def main(args: Array[String]): Unit = {
        //    调用空参构造器,可以加() 也可以不
        var stu = new Student()

        //    类中使用 val 修饰的变量不能更改
        //    student.school = "nanda"
        stu.name = "laowang"
        println(s"student.name is ${stu.name}") // student.name is laowang
        println(s"test.name is ${Test.name}") // test.name is zhangsan
    }
}

  定义在类后面的为类主构造器, 一个类可以有多个辅助构造器

/*
*    Student1(val name: String, var age: Int)
*    定义个 2 个参数的主构造器
**/

class Student1 (val name: String, var age: Int) {
    var gender: String = _
    // 辅助构造器, 使用 def this   
    // 在辅助构造器中必须先调用类的主构造器
    def this(name: String, age:Int, gender: String){ 
        this(name, age)
        this.gender = gender
    }
}

object Test1{
    def main(args: Array[String]): Unit = {
        // 调用主构造器
        val s = new Student1("laoduan", 38)
        println(s"${s.name} ${s.age}")
        
        // 调用的是辅助构造器
        val s1 = new Student1("laoYang", 18, "male")
        println(s"${s1.gender}")
    }
}        

  2.2 访问权限

  构造器访问权限

  

/*
*    Student1(val name: String, var age: Int)
*    定义个 2 个参数的主构造器
*   private 加在主构造器前面标识这个主构造器是私有的, 外部不能访问这个构造器
*   这里的外部是值只有在本类才可以调用,即本类的辅助构造器才能调用。还有伴生类也可以访问
**/

class Student1 private (val name: String, var age: Int) {
    var gender: String = _
    // 辅助构造器, 使用 def this
    // 在辅助构造器中必须先调用类的主构造器
    def this(name: String, age:Int, gender: String){
        this(name, age) // 这里调用了主构造器
        this.gender = gender
    }
}

object Test1{
    def main(args: Array[String]): Unit = {
        // 调用主构造器,若主构造器加上private,这里调用会报错
        val s = new Student1("laoduan", 38)
        println(s"${s.name} ${s.age}")

        // 调用的是辅助构造器
        val s1 = new Student1("laoYang", 18, "male")
        println(s"${s1.gender}")
    }
}

  成员变量访问权限

/*
*    private 加在主构造器前面标识这个主构造器是私有的, 外部不能访问这个构造器
*    private var age
*    age 在这个类中是有 getter setter 方法的
*    但是前面如果加上了 private 修饰, 也就意味着, age 只能在这个类的内部以及其伴生类对象中可以访问修改
*    其他外部类不能访问
**/

class Student2 private (val name: String, private var age: Int){
    var gender: String = _

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

    // private[this]关键字标识该属性只能在类的内部访问, 伴生类不能访
    private [this] val province: String = "北京"

    def getAge = 18
}

//
// 类的伴生对象
object Student2{
    def main(args: Array[String]): Unit = {
        //伴生对象可以访问类的私有方法和属性
        var s2 = new Student2("老王", 18)
        s2.age = 19
        println(s"${s2.age}")
        // println(s"${s2.province}") 伴生类不能访问
    }
}

  类包的访问权限

/*
*    private[包名] class 放在类声明最前面, 是修饰类的访问权限, 也就是说类在某些包下不可见或不能访问
*    private[sheep] class 代表 student3 在 sheep 包下及其子包下可以见, 同级包中不能访问
*
* */

private [this] class Student3(val name: String, private var age: Int){
    var xx: Int = _
}

object Student3{
    def main(args: Array[String]): Unit = {
        var s3 = new Student3("wallace", 16)
        println(s"${s3.name}")
    }
}

  2.3 伴生类,apply方法

  在 Scala 中, 当单例对象与某个类共享同一个名称时,他被称作是这个类的伴生对象。必须在同一个源文件里定义类和它的伴生对象。类被称为是这个单例对象的伴生类。类和它的伴生对象可以互相访问其私有成员。

三,特质

  Scala Trait(特质) 相当于 Java 的接口,实际上它比接口还功能强大。与接口不同的是,它还可以定义属性和方法的实现。一般情况下 Scala 的类只能够继承单一父类,但是如果是 Trait(特质) 的话就可以继承多个,实现了多重继承。使用的关键字是trait .

trait TDemo2 {
    // 特质属性
    var className: String = "牛B班"
    
    // 特质无实现方法
    def teacherSay(name: String)
    
    // 特质有实现方法
    def doSomeThing()={
        print("aaaa")
    }

}

四,抽象类

  在scala中,使用abstract修饰的类为抽象类,在抽象类中可以定义属性,未实现的方法和已实现的方法。

  如下实例:

abstract class AbsDemo1 {
    // 抽象类属性
    var className: String = "牛B班"

    // 抽象类未实现方法
    def teacherSay(name: String)

    // 抽象类已实现方法
    def doSomeThing()={
        print("aaaa")
    }
}

五,继承

  继承是面向对象的概念,用于代码的可重用性,被扩展的类称为超类或父类,扩展的类称为派生类或子类。Scala可以通过使用extends关键字来实现继承获其他类获特质。

  父类:

abstract class Animal {
    // 定义一个name属性
    val name: String = "animal"
    // 没有任何实现的方法
    def sleep()
    // 带有实现的方法
    def eat(f: String)={
        println("$f")
    }
}

  子类:

class Dog extends Animal {
    /*
    * with 后面只能是特质
    * 父类已经实现了的功能, 子类必须使用 override 关键字重写
    * 父类没有实现的方法,子类必须实现
    * */
    override val name: String = "Dog"

    override def sleep(): Unit = {
        println("躺着睡。。。。")
    }
}

  5.1 final关键字

  被 final 修饰的类不能被继承;
  被 final 修饰的属性不能重写;
  被 final 修饰的方法不能被重写

  5.2 type关键字

  Scala 里的类型,除了在定义 class,trait,object 时会产生类型,还可以通过 type 关键字来声明类型。

  type 相当于声明一个类型别名:

  父类:

trait StudentTrait {

    type T

    def learn(s: T) = {
        println(s)
    }

}

  子类:

object Student1 extends StudentTrait{
    override type T = String

    def main(args: Array[String]): Unit = {
        Student1.learn("String")
    }
}

object Student2 extends StudentTrait {
    override type T = Int

    def main(args: Array[String]): Unit = {
        Student2.learn(100)
    }
}

六,样例类,样例对象

/*
* 样例类,使用 case 关键字 修饰的类, 其重要的特征就是支持模式匹配
* 样例类默认是实现了序列化接口的
* */
case class Message(msgContent: String)
/*
* 样例 object, 不能封装数据, 其重要特征就是支持模式匹配
**/
case object CheckHeartBeat
object TestCaseClass  extends App{
    // 可以使用 new 关键字创建实例, 也可以不使用
    val msg = Message( "hello")
    println (msg .msgContent)
}

七,匹配模式

  7.1 匹配字符串,类型,守卫

val arr = Array ( "YoshizawaAkiho", "YuiHatano", "AoiSola")
val i = Random.nextInt( arr .length)
println ( i )
val name = arr ( i )
println ( name )
name h match {
    case " "YoshizawaAkiho" => println (" " 吉泽老师 ...")
    case " "YuiHatano" => {
        println (" " 波多老师 ...")
    }
    case _ => println (" " 真不知道你们在说什么 ...")
}

println ( "----------- 骚气的分割线 -----------")
//定义一个数组

val arr :Array[Any] = Array ( "hello123", 1, 2.0, CaseDemo02, 2L)
//取出一个元素
val elem = arr (3)

elem h match {
    case x: Int => println (t "Int " " + x)
    case y: Double if(y >= 0) => println ("Double " "+ y) // if 守卫
    case z: String => println (g "String " " + z)
    case w: Long => println (g "long " " + w)
    case CaseDemo02 => {
        println ("case o demo 2")
        //throw new Exception("not match exception")
    }
    case _ => { // 其他任意情况
        println ( "no")
        println ( "default")
    }
}

  7.2 匹配数组

val arr = Array (1, 1, 7, 0, 2,3)
arr h match {
    case Array (0, 2, x, y) => println (x + " " " " + y)
    case Array (2, 1, 7, y) => println (y "only 0 0 " " + y)
    case Array (1, 1, 7, _*) => println (0 "0 ...") // _* 任意多个
    case _ => println (g "something else")
}

  7.3 匹配集合

val lst = List(0, 3, 4)
println(lst.head)
println(lst.tail)
lst match {
    case 0 :: Nil => println ("only 0")
    case x :: y :: Nil => println (s"x $x y $y" ")
    case 0 :: a => println (s"value: $a")
    case _ => println ("something else")
}

  7.4 匹配元组

val tup = (1, 3, 7)
tup match {
    case (3, x, y) => println (s"hello 123 $x,$y")
    case (z, x, y) => println (s"$z,$x,$y")
    case (_, w, 5) => println (w)
    case _ => println("else")
}

  7.5 匹配样例类,样例对象

//样例类,模式匹配,封装数据(多例),不用 new 即可创建实例
case class SubmitTask(id: String, name: String)
case class HeartBeat(time: Long)
//样例对象,模式匹配(单例)
case object CheckTimeOutTask
val arr = Array (CheckTimeOutTask, new HeartBeat(123), HeartBeat (88888), new HeartBeat(666), SubmitTask ("0001","task-0001"))
val i = Random.nextInt( arr .length)
val element = arr ( i )
println( element )
element match {
    case SubmitTask (id, name) => {
        println (s"$id,$name")
    }
    case HeartBeat (time) => {
        println (time)
    }
    case CheckTimeOutTask => {
        println ("check")
    }
}

Scala 学习 (六) 面向对象

原文:https://www.cnblogs.com/tashanzhishi/p/10959226.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!