Scala 学习 六 面向对象

一,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")
    }
}

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


共收录Twitter的14款开源软件,第1页Twitter的Emoji表情 TwemojiTwemoji是Twitter开源的其完整的Emoji表情图片。开发者可以去GitHub下载完整的表情库,并把这些表情加入到自己的应用或网页中。使用示例:var i = 0;twemoji.parse(  ’emoji, m\u276
Java和Scala中关于==的区别Java:==比较两个变量本身的值,即两个对象在内存中的首地址;equals比较字符串中所包含的内容是否相同。publicstaticvoidmain(String[]args){​ Strings1="abc"; Strings2=newString("abc");​ System.out.println(s1==s2)
本篇内容主要讲解“Scala怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Scala怎么使用”吧!语法scala...
这篇文章主要介绍“Scala是一种什么语言”,在日常操作中,相信很多人在Scala是一种什么语言问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,
这篇文章主要介绍“Scala Trait怎么使用”,在日常操作中,相信很多人在Scala Trait怎么使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,
这篇文章主要介绍“Scala类型检查与模式匹配怎么使用”,在日常操作中,相信很多人在Scala类型检查与模式匹配怎么使用问题上存在疑惑,小编查阅了各式资料,整理...
这篇文章主要介绍“scala中常用但不常见的符号有哪些”,在日常操作中,相信很多人在scala中常用但不常见的符号有哪些问题上存在疑惑,小编查阅了各式资料,整理...
本篇内容主要讲解“Scala基础知识有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Scala基础知识有哪些”...
本篇内容介绍了“scala基础知识点有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧...
本篇内容介绍了“Scala下划线怎么使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧...
本篇内容主要讲解“Scala提取器怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Scala提取器怎么使用”...
这篇文章主要讲解了“Scala基础语法有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Scala基础语法有...
本篇内容主要讲解“Scala方法与函数怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Scala方法与函数怎...
这篇文章主要讲解了“scala条件控制与循环怎么实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“scala条...
这篇文章主要介绍“scala函数怎么定义和调用”,在日常操作中,相信很多人在scala函数怎么定义和调用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操
这篇文章主要介绍“scala如何声明变量”,在日常操作中,相信很多人在scala如何声明变量问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对...
这篇文章主要讲解了“scala的Map和Tuple怎么使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“scala的Ma...
这篇文章主要介绍“scala的隐式参数有什么作用”,在日常操作中,相信很多人在scala的隐式参数有什么作用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的...
本篇内容主要讲解“Scala怎么进行文件写操作”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Scala怎么进行文件...
这篇文章主要讲解了“Scala怎么声明数组”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Scala怎么声明数组...