`

scala 学习四

阅读更多

4.   OOP

4.1.     class

4.1.1.  定义

例子1

class User {

var name = "anonymous"

var age:Int = _

val country = "china"

def email = name + "@mail"

}

使用:

val u = new User

// var定义的属性可读可写

u.name = "qh"; u.age = 30

println(u.name + ", " + u.age) // "qh, 30"

// val 定义的属性只读不可写

u.country = "usa" // 报错

println(u.country) // "china"

// def 定义的是方法, 每次调用时重新计算

u.email // "qh@mail"

 

例子2

// 定义

class Person(ln : String, fn : String, s : Person = null) {

  def lastName = ln;   // def定义后才是属性,lnfns不可见

  def firstName = fn;

  def spouse = s;

  def introduction() : String =

    return ("Hi, " + firstName + " " + lastName) +

    (if (spouse != null) " and spouse, " + spouse.firstName + " " + spouse.lastName + "."

     else ".");

}

// 调用

new Person("aa","bb", new Person("cc","dd")).introduction();

 

4.1.2.  构造方法

class c1(x:String) // 等同于:class c1(private var x:String)

val o1 = new c1("aaa")

o1.x // 报错,因为是private的,定义成 class c1(var x:String) 才能这样用

 

例子1

object construct1 {

class c1(name:String, age:Int) { // (1)直接在类定义处

    def this() { this("anonymous", 20) } // (2)this定义

        def m1() = {  printf("%s=%d\n", name, age) }

    }

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

new c1().m1()

new c1("qh", 30).m1()

}

}

编译:fsc construct1.scala

运行:java construct1

 

例子2:继承中的构造方法:

class c2(name:String, age:Int, female:Boolean=false)

    extends c1(name,age) {

    override def toString = { name + "," +  age + "," + female }

}

 

4.1.3.  override

不同于Java的使用 @Override,或者直接使用相同名字覆盖父类方法。

    override def toString = { name + "," +  age + "," + female }

如果是覆盖抽象方法,可以不用overriade关键字。

4.1.4.  object单例对象

如:

Java

Scala

public class User {

  private String name;

  private User(String name) { this.name=name; }

  public static User instance(String name) {

return new User(name)

  }

}

object User {    

  var name:String = _

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

  override def toString = "name: " + name

}

调用:

val u = User("qh") // "name: qh"

 

 

4.1.5.  静态方法

Scala没有静态方法,类似静态方法的函数定义在object中:

object Stringx {

    def left(s0:String, s:String) = ...

}

直接调用Stringx.left(s0, s),或者 Stringx left (s0, s)

 

定义在object中的implicit方法也能被直接调用:

例如:

--------- ImportSub.scala

object ImportSub {

  def fac(n: Int) = 1 to n reduceLeft (_ * _)

  implicitdef foo(n: Int) = new { def ! = fac(n) }

}

--------- ImportMain.scala

import ImportSub._

object ImportMain {

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

      println(5!) // 调用ImportSub中定义的implicit函数

  }

}

4.1.6.  case class(条件类)

例如:

case class Person(name:String, age:Int)   

特殊之处:

l  新建类实例不用new Person(..),直接用Person("qh",20)

l  自动定义好getXX方法,Person("qh",20).name // "qh"

l  提供默认的toString(), Person("qh",20) // "Person(qh,20)"

l  结合类继承可以通过模式匹配进行分解

例子1

abstract class Person

case class Man(power:Int) extends Person

case class Woman(beauty:Int, from:String) extends Person

 

val w1 = Woman(100,"china")

val w2 = w1.copy(from="usa") // Woman(100,"usa")

 

def f(t:Person) = t match {

case Man(x) => "man's power:" + x

case Woman(x,y) => y + " beauty:" + x

}

f(Man(100)) // man's power:100

f(Woman(90, "china")) // china beauty:90

 

注:基本类型直接可以用math case

 

例子2:可变的类状态

case class C1(var s: String, var ops: Int) { 

  def >>= (f: (String=>String)) = {

    s = f(s)  // s改变

    ops += 1  // ops改变

    this // 返回自身,可以连续调用

  } 

}  

val C1(res, ops) = C1("ab", 0) >>= (_ * 3) >>= (_ drop 3)

// res="ab"->"ababab"->"bab", ops=0-> 0+1+1->2

 

例子3:用case class代替tuple

val p = ("qh",20) // p._1 = "qh", p._2 = 20;好处是简洁,但无意义

case class person(name:String, age:Int)

val p = person("qh",20) // p.name = "qh", p.age = 20; 好处是有名字,自说明,可读性强

 

例子4:用case class来描述元数据

xml的版本:

<todo name = "housework">

<item priority = "high">Clean the hose</item>

<item priority = "medium">Wash the dishes</item>

<item priority = "medium">Buy more soap</item>

</todo>

Lisp的版本:

(todo "housework"

 (item (priority high) "Clean the house")

 (item (priority medium) "Wash the dishes")

 (item (priority medium) "Buy more soap"))

Scala的版本:

    case class item(priority:String, s:String)

    case class todo(name:String, items:List[item])

    todo (name="housework",

items=item("high","Clean the house")::

item("medium","Wash the dishes")::

item("medium","Buy more soap")::Nil)

 

4.1.7.  case object(条件单例对象)

比如定义一个标识类(而不是字符串):

case object Start

case object Stop

 

4.1.8.  枚举

Java中:

   enum fruits { apple, banana, cherry }

Scala中,则是:

sealed abstract class Fruits // sealed类似于javafinal

case object Apple extends Fruits

case object Banana extends Fruits

case object Cherry extends Fruits

也可以是 case class

 

4.1.9.  属性和Bean

例子1(直接定义和使用属性):

class c {

var name = "anonymous" // var定义的是r/w的属性

val age = 20  // val定义的是只r属性

}

 

val o = new c

o.name = "qh"

o.name // "qh"

o.age = 10 // 错误

o.age // 20

o.

 

例子2(定义get/set方法):

class c2 {

@reflect.BeanProperty var name = "anonymous"

}

val o2 = new c2

o2.name = "qh" // 也可以直接存取

o2.name // "qh"

o2.setName("james") // 增加了set/get方法

o2.getName() // "james"

4.1.10.      反射

Scala没有太特别的反射机制,使用java的即可,不过Scalamatch..case中可以匹配类型:

    case o:FooClass1 => ...

相关还有isInstanceOf[T], asInstanceOf[T]

 

1(利用javareflect):

"hello".getClass.getMethods.map(_.getName).toList.sortWith(_<_).mkString(", ")

 

例子2

classOf[String] // 相当于java中的String.class

"aaa".isInstanceOf[String] // true

"aaa".asInstanceOf[String]

4.2.     trait超级接口

注:trait  [treit] n.特征,特点,特性

JavaInterface类似,但可以定义实体方法,而非仅仅方法定义

trait可以看作有方法实现和字段的interface;代表一类事物的特性;

比如

Tom,可能是Engine Son两个trait的混合;

Sunny可能SalesSonFather三个trait的混合;

当在运行时往Son里面增加方法或者字段的时候,TomSunny都得到增加的特性。

4.2.1.  trait使用

trait Runnable {

  def run(): Unit;

}

 

只是用一个接口,就用extends:

class c1 extends Runnable {...}

 

2个接口(或一个继承一个接口),用with而不是implements如下:

class c1 extends c0 with Runnable {

    def run(): Unit = {...}

}

 

一个类可以组合多个trait

class c1 extends t1 with t2 with t3 {...}

 

4.2.2.  mixin

class Human

class Child

 

trait Dad {

    privatevar children:List[Child] = Nil

    def add(child:Child) = child :: children

}

 

class Man1(name:String) extends Human with Dad // 静态mixin

class Man2(name:String) extends Human // 先不具备Dad trait

 

val m1 = new Man1("qh")

m1.add(new Child)

     

val m2 = new Man2("小孩")

//    m2.add(new Child) // 报错   

val m2$ = new Man2("james") with Dad // 动态mixin

m2$.add(new Child)

 

 

4.3.     协变和逆变(co-|contra-)variance

4.3.1.  概念

使用“+”“-”差异标记

Function[A, B]Function[-A, +B]的区别图示:

Function[A,B]

Function[-A,+B]

 

trait Queue[T] {}

非变

trait Queue[+T] {}

协变

如果S extends A (S为子类型,A为父类型)

Queue[S]为子类型,Queue[A]为父类型

S <: A => Queue[S] <: Queue[A]            

trait Queue[-T] {}

逆变

如果S extends A (S为子类型,A为父类型)

Queue[S]为父类型,Queue[A]为子类型,和协变互逆

S <: A => Queue[S] >: Queue[A]

 

-AA的子集,叫逆变

+BB的超集,叫协变

 

4.3.2.  类型上下界

 

 

<%

foo[T <% Ordered[T]](...)

关系较弱:T能够隐式转换为Ordered[T]

<:

foo[T <: Ordered[T]](...)

关系较强:T必须是Ordered[T]的子类型,即T的类型范围小于Ordered[T]Ordered[T]为上界

>:

foo[T >: A](...)

关系较强:T必须是A的父类型,即Tde类型范围大于AA为下界

 

4.3.3.  协变、逆变结合上下界

例子1

trait c1[+T] {

def m[K >: T](x:K) = x }

trait c1[-T] {

def m[K <: T](x:K) = x }

object c2 extends c1[Int]

c2.m(3) // 3

c2.m(3.0) // 3.0

c2.m("abc") // "abc"

object c2 extends c1[Int]

c2.m(3) // 3

c2.m(3.0) // 报错

c2.m("abc") // 报错

 

 

 

例子2

// 非变

case class T1[T](e:T)

val v1:T1[java.lang.Integer] = new T1(100)

val v2:T1[java.lang.Integer] = v1

v2.e // 100

val v3:T1[java.lang.Number] = v1 // 报错

 

// 协变

case class T1[+T](e:T)

val v1:T1[java.lang.Integer] = new T1(100)

val v2:T1[java.lang.Integer] = v1

v2.e // 100

val v3:T1[java.lang.Number] = v1 // 合法

v3.e // 100

val v4:T1[java.lang.Integer] = v3 //非法

 

// 逆变

class T1[-T](e:T)

val v1:T1[java.lang.Number] = new T1(100)

val v2:T1[java.lang.Number] = v1

val v3:T1[java.lang.Integer] = v1 // 合法

val v4:T1[java.lang.Number] = v3 // 非法

分享到:
评论

相关推荐

    scala学习资料(带书签)

    这个压缩包“scala学习资料(带书签)”提供了一个全面的学习路径,从基础到高级,帮助你深入理解和掌握Scala语言。 **入门篇** 1. **基础语法**:Scala的基础包括变量声明、类型系统、控制结构(如if/else、循环)...

    Scala学习笔记(全)

    ### Scala学习笔记(全) #### 一、Scala概述与特点 Scala是一种多范式的编程语言,旨在集成面向对象编程和函数式编程的各种特性。它运行于Java平台(Java虚拟机JVM),并且能够完全兼容所有的Java程序。这使得Scala...

    scala 学习资料

    4. **Actor模型**:Scala集成了Akka库,提供了强大的并发和分布式计算支持。Actor模型允许并发执行而无需担心数据竞争,每个Actor都有自己的消息队列,通过异步消息传递进行通信。 5. **集合库**:Scala的集合库...

    scala学习笔记整理

    在"scala学习笔记整理"中,我们可以深入探讨以下关键知识点: 1. **基础语法**:Scala的基础语法与Java有相似之处,但也有很多独特的特点。例如,它支持变量的不可变性(immutability),使用`val`声明常量,`var`...

    scala学习-project.zip

    这个"scala学习-project.zip"压缩包很可能是为了帮助初学者或者开发者深入理解Scala语言而设计的一个实践项目。下面,我们将深入探讨Scala的一些核心概念和关键知识点。 1. **基础语法**:Scala的语法与Java有些...

    Scala学习之路(一)

    ### Scala学习之路(一)—— 开发环境搭建与首个程序 #### 一、Scala简介 Scala是一种多范式编程语言,旨在实现可扩展性,并融合了面向对象编程和函数式编程的最佳特性。作为一种与Java非常相似的语言,Scala能够...

    scala深入学习

    同时,由于Scala构建在Java平台上,了解Java对于Scala学习者来说是非常有帮助的,因为可以将Java的生态和已有的知识无缝迁移到Scala上。 深入学习Scala,除了阅读书籍和文档之外,还需要大量的实践。参与开源项目、...

    scala学习资料

    4. 集合库:Scala的集合库设计精良,包含各种高效的数据结构,如List、Set、Map等。这些集合不仅支持传统的OOP操作,还提供了丰富的函数式API,如map、filter、fold等,方便进行数据处理。 5. 特性与模式匹配:...

    spark+scala学习

    ### Spark+Scala 学习知识点概述 #### 一、Scala语言基础 **1. Scala语言简介** Scala是一种融合了面向对象编程与函数式编程特性的现代编程语言。它旨在简化编程,提供更简洁、强大的代码编写方式。Scala运行在...

    Scala-学习资料-mht.rar

    4. 并发编程:Scala提供了Actor模型,这是一种轻量级的并发机制,使得处理并发问题变得更加简单和高效。 5. Akka框架:Akka是用Scala编写的开源框架,用于构建高度可扩展、容错的应用程序,它充分利用了Scala的...

    Scala编程 pdf

    4. **函数式编程**:Scala鼓励使用不可变数据结构和高阶函数,函数是一等公民,可以赋值给变量,作为参数或返回值。λ表达式(匿名函数)和闭包也是重要的概念。 5. **类型推断**:Scala具有强大的类型推断能力,...

    scala sdk scala-2.12.3

    通过学习和使用Scala SDK,开发者可以利用其丰富的语言特性来构建复杂的软件系统,尤其是在大数据处理、Web应用、云计算等领域,Scala已经展现出了强大的生命力。例如Apache Spark,一个流行的分布式计算框架,就是...

    Akka Scala 学习高清原版pdf

    标题“Akka Scala 学习高清原版pdf”表明该文档是一个专注于Scala语言在Akka框架中应用的指南,而“描述”则指出文档内容涵盖Scala实现的Akka并发编程。标签“Akka scala 并发 actor”则进一步具体化了文档内容,即...

    scala学习资料,主题提取学习资料

    在"scala学习资料,主题提取学习资料"这个压缩包中,我们可以预见到包含了一系列帮助学习Scala编程以及主题提取技术的资源。 Scala的基础知识点包括: 1. **基本语法**:Scala的语法与Java有诸多相似之处,但更加...

    scala详细总结

    Scala 语言详细总结 Scala 是一门以 Java ...2. Scala 学习教程:Scala 学习教程提供了详细的学习资源,包括视频、文档和实践项目。 3. Scala 社区:Scala 社区是一个活跃的社区,提供了许多有用的资源和讨论论坛。

    基于Scala的Spark学习项目设计源码

    文件类型包括80个Scala源代码文件、4个XML配置文件、3个TXT文档、2个Markdown文档、2个Java源代码文件、1个GIT忽略文件、1个日志文件、1个JSON配置文件和1个Properties配置文件。该学习项目适合用于学习和实践Scala...

    Scala学习笔记

    ### Scala学习笔记关键知识点 #### 1. “均码”哲学与并发编程 - **“均码”哲学**: 指的是Scala设计时遵循的一种设计理念,即尽量保持语言的统一性和简洁性,使得不同的功能和特性能够以一种相似的方式进行处理。...

    scala讲解笔记 入门及进阶 PDF文档1-5

    Scala是一种强大的多范式编程语言,它融合了面向对象和函数式编程的特性,被广泛应用于大数据处理、分布式计算和高性能应用开发。...每个文档都配有实例和注释,便于理解和实践,是Scala学习者宝贵的资源。

Global site tag (gtag.js) - Google Analytics