一 单例类型 this.type

Scala中,对于任何类型的引用v,都可以调用v.type,然后会返回v或者null,有时候这种是有用的,假设一下场景:

比如某一个方法返回this,

class Person {
    private var name:String = null
    private var age:Int = 0
    def setName(name:String)={
        this.name=name
        //返回对象本身
       
this
    }
    def setAge(age:Int)={
        this.age=age
        //返回对象本身
       
this
    }
    override def toString()="name:"+name+" age:"+age
}

那么我们就可以完成链式调用,如:

object Test extends App {/*** 报错是因为返回的this代表的是父类自己而不是子类自己,而弗雷是没有setStudentNo方法的* 为解决该问题,可以将setName、setAge方法的返回值设置为:this.type*/println(new Person().setName("john").setAge(22).setStudentNo("2014"))
}

然而,如果你还有个子类:

/*当涉及到继承时,会存在一些问题*/
class Student extends Person{private var studentNo:String = nulldef setStudentNo(no:String) = {this.studentNo=nothis}override def toString() = super.toString()+" studetNo:"+studentNo
}

然后再来链式调用,就会有问题:

object Test extends App {/*** 报错是因为返回的this代表的是父类自己而不是子类自己,而弗雷是没有setStudentNo方法的* 为解决该问题,可以将setName、setAge方法的返回值设置为:this.type*/println(new Student().setName("john").setAge(22).setStudentNo("2014"))
}

解决办法:

class Person {private var name:String = nullprivate var age:Int = 0def setName(name:String):this.type = {this.name=name//返回对象本身this}def setAge(age:Int):this.type={this.age=age//返回对象本身this}override def toString()="name:"+name+" age:"+age
}

二 类型投影

问题描述,不同对象创建的内部类不是同一种类型:

import scala.collection.mutable.ArrayBuffer
class NetWork {class Member(val name:String){val contacts = new ArrayBuffer[Member]()}private val members = new ArrayBuffer[Member]def join(name:String) = {val m = new Member(name)members += mm}
}object Test extends App{val chatter = new NetWorkval myFace = new NetWork/*** 现在chatter.Member和 myFace.Member和是不同的类* 你不可以将其中一个member添加到另外一个member*/val fred = chatter.join("Fred")val banery = myFace.join("Banery")//这样是有问题的fred.contacts += banery
}

如果要解决这个问题,可以使用类型投影:

类型投影的目的是将外部类定义的方法中,他可以接收任意外部类对象的内部类。

也就是说newchatter.Member 和 new myFace.Member()虽然是属于不同的类,但是他们有着共同父类NetWork#Member,我们对之前的代码稍加改造:

class NetWork {class Member(val name:String){val contacts = new ArrayBuffer[NetWork#Member]()}private val members = new ArrayBuffer[NetWork.this.Member]def join(name:String) = {val m = new Member(name)members += mm}
}

三 类型别名

对于复杂的类型,你可以使用type关键字创建一个简单的别名,就像这样:

四 结构类型

结构类型利用反射机制为静态语言添加动态性,从而使得参数类型不受限于某个已命名的类型,比如:

class StructType {/*** 1 语法:def 函数名(变量名:{抽象函数},其他参数列表)* 2 {抽象函数}就表示结构体* 3 结构体还可以使用type关键字声明 type func = {抽象函数}* 4 在函数体内就可以调用=> 变量名.抽象函数()* 5 在调用主题函数的时候,需要使用new {抽象函数的实现}* 6 所以感觉上结构体也是一个特殊的类*/def appendLines(target:{def append(line:String):Any},lines:Iterable[String]): StringBuilder ={val sb = new StringBuilder()for (l <- lines){val s = target.append(l)sb.append(s).append("\n")}sb}
}object Test1 extends  App{val st = new StructTypeval animals = List("tiger","lions","hadoop")val sb = st.appendLines(new {def append(line:String):Any = {"<"+line.toUpperCase()+">"}},animals)sb.foreach(e => print(e))
}

<TIGER>

<LIONS>

<HADOOP>

另外结构体还可以使用type关键字声明:

class StructType {
type append_func = {def append(line:String):Any}def appendLines(target:append_func,lines:Iterable[String]): StringBuilder ={val sb = new StringBuilder()for (l <- lines){val s = target.append(l)sb.append(s).append("\n")}sb}
}object Test1 extends  App{val st = new StructTypeval animals = List("tiger","lions","hadoop")val sb = st.appendLines(new {def append(line:String):Any = {"<"+line.toUpperCase()+">"}},animals)sb.foreach(e => print(e))
}

五 复合类型

语法格式: T1 with T2with T3

其中T1,T2,T3是类型,要想成为该复合类型的实例,某一个值必须满足每一个类型要求才行,因此这样的类型也被称作为交集类型

你可以用复合类型来操纵那些必须提供多个特质的值,比如:

class A {def show(desc:String): Unit ={println(desc)}
}trait B {def toUpper(message:String):String
}/*** 现在这个类就是A和Serializable的复合类型* 注意:* with 必须是trait或者java的接口,不能是scala的类或者java类* 就算是抽象类也不行*/class ComplexType extends A with java.io.Serializable with B {override def toUpper(message: String): String = {message.toUpperCase()}
}

我们可以利用关键字type声明一个复合类型

class ComplexType {type Type = A with java.io.Serializable with Bdef func(t:Type): Unit ={t.show("I love you")}
}

六 中置类型

中置类型是一个带有两个类型参数的类型,以中置语法表示,类型名称写在两个类型参数之间,举例来说,你可以这样写:

String Map Int 而不是Map[String,Int]

case class InfixType[S,T](val name:S,val age:T) {}object InfixType extends App{//我么一般这么写:val infix1:InfixType[String,Int] = InfixType[String,Int]("Infix",28)//使用中置表达式写法val infix2:String InfixType Int = InfixType("Infix",28)
}

七 存在类型

存在类型的语法 [类型表达式] forsome {type T}

forSome使得我们能够使用更加复杂的关系,比如Map[T,S]

forSome {type T;type S <: T},而不仅限于类型通配符能表达的那些

class ExistsType {def func1[T](ele:Array[T] forSome {type T}):Unit = {ele.foreach(e => print(e+" "))}def func2(ele:Array[_]):Unit = {ele.foreach(e => print(e+" "))}//Map[_,_]相当于Map[T,U] forSome {type T;type U}def func3[T,S](dict:Map[T,S] forSome {type T;type S}): Unit ={for((k,v) <- dict){print(k,v)}}def func4(dict:Map[_,_]): Unit ={for((k,v) <- dict){print(k,v)}}
}

八  自身类型

我么知道,我们可以限制混入特质的时候,限定类型。

通过语法this:指定类型 => 然后指定所允许混入的类或者其子类才可以混入该trait

class BaseType
class ParentType
trait MyTrait {/*** 指定该trait只能被BaseType的子类可以混入* 不是BaseType的子类是不可以混入这个trait的*/this:BaseType =>
}class ConcreteType extends BaseType with MyTrait
/*所以这里会报错*/
class ImplementType extends  ParentType with MyTrait

九 抽象类型

抽象类型:是指在类或者特质中利用type关键字定义一个没有确定类型的标识,该标志在子类被确定,称这种类型为程序类型,比如:

abstract class Persons{//声明一个未被确定的类型type UndefinedTypedef show(x:UndefinedType)
}class Students extends Persons{//确定抽象类型type UndefinedType = Stringdef show(x:UndefinedType):Unit = {println("Student show => "+ x.toLowerCase())}
}class Teachers extends Persons{type UndefinedType = mutable.HashMap[String,String]def show(x:UndefinedType):Unit = {for ((k,v) <- x){println("Teacher show key => "+k+" value=>"+v)}}
}object AbstractType extends App {val message = "Welcome You, Guys"val map = mutable.HashMap(("Nicky", "Math"), ("Allice", "History"), ("Judy", "English"))val s = new Studentss.show(message)val t = new Teacherst.show(map)
}

上述代码的也可用泛型进行实现,如:

abstract class People[T]{def show(x:T)
}class Worker extends People[String]{def show(x:String):Unit = {println("Student show => "+ x.toLowerCase())}
}class Leader extends People[mutable.HashMap[String,String]]{def show(x:mutable.HashMap[String,String]):Unit = {for ((k,v) <- x){println("Teacher show key => "+k+" value=>"+v)}}
}

结论:

在实际应用中,如果类型是在实例化的时候给定的,推荐用类型参数进行类的定义;如果类型是在子类型中才被确定,则推荐使用抽象类型。

scala 高级类型相关推荐

  1. Scala08:Scala高级特性

    一.Scala高级特性 接下来我们学习一下Scala中的高级特性 模式匹配 隐式转换 1.模式匹配 先看一下模式匹配 模式匹配是Scala中非常有特色,非常强大的一种功能. 模式匹配,其实类似于Jav ...

  2. Scala入门到精通—— 第二节Scala基本类型及操作、程序控制结构

    本节主要内容 Scala基本类型 基本类型操作 Scala程序控制结构 Scala基本类型 Scala中的基本数据类型如下图: (来源:Programming in scala) 从上表中可以看出,S ...

  3. th:text为null报错_为vue3.0的学习TS解读高级类型

    知识点摘要 本节课主要关键词为: 自动类型推断 / 类型断言 / 类型别名(type) / 映射类型(Pick/Record等...) / 条件类型(extends) / 类型推断(infer) 自动 ...

  4. 类型全部为string_TypeScript 高级类型总结(含代码案例)

    // 每日前端夜话 第458篇// 正文共:2600 字// 预计阅读时间:10 分钟 TypeScript 是一种类型化的语言,允许你指定变量.函数参数.返回的值和对象属性的类型. 以下是 Type ...

  5. boolean类型_10、typescript的高级类型

    所谓高级类型,是typescript为了保证语言的灵活性,所使用的一下语言特性.这些特性有助于我们应对复杂多变的开发场景. 交叉类型 将多个类型合并成一个类型,新的类型将具有所有类型的特性,所以交叉类 ...

  6. as button onitemclicklistener为null_为vue3.0的学习TS解读高级类型

    知识点摘要 本节课主要关键词为: 自动类型推断 / 类型断言 / 类型别名(type) / 映射类型(Pick/Record等...) / 条件类型(extends) / 类型推断(infer) 自动 ...

  7. TypeScript 高级类型及用法

    一.高级类型 交叉类型(&) 交叉类型是将多个类型合并为一个类型.这让我们可以把现有的多种类型叠加到一起成为一种类型,它包含了所需的所有类型的特性. 语法:T & U 其返回类型既要符 ...

  8. Scala之类型参数化:Type Parameterization

    Scala之类型参数化:Type Parameterization 本文原文出处: http://blog.csdn.net/bluishglc/article/details/52584401 严禁 ...

  9. 5.TypeScript入门之TS高级类型(class类)

    上一章节:4.TypeScript入门之TS常用类型(3) Ⅳ.TypeScript高级类型 概述 TS中的高级类型有很多,重点学习以下高级类型: class类 类型兼容性 交叉类型 泛型和 keyo ...

最新文章

  1. python的软件叫什么-Python 是什么软件?
  2. 数学建模学习笔记——分类模型
  3. Android(java)学习笔记158:多线程断点下载的原理(JavaSE实现)
  4. WinPcap笔记(2):获取设备列表
  5. v-viewer图片打不开一直在刷新_网速很慢甚至打不开?广告弹窗太多了?有效提升网络质量的方法。...
  6. iPhone平台下的游戏开发
  7. SequenceFile文件的读取
  8. c# html正则,c# 使用正则解析html
  9. html转pdf乱码问题,java html 转 pdf 中文乱码
  10. 黑客的google运用技巧
  11. 字蛛font-spider报错 web font not found
  12. Mumble安装部署教程
  13. EAX、ECX、EDX、EBX
  14. 软件测试可以分为哪几个类型?
  15. 大学物理复习笔记——量子物理
  16. Source Insight使用教程(一):导入工程
  17. 数据结构与算法——给定整数A1,A2,....An,....(可能有负数),求该数据序列的最大子序列的和
  18. 宝塔linux面板命令大全
  19. 一个(基于xfs协议)身份证扫描仪的理解
  20. 写于数学建模美赛准备期间

热门文章

  1. java在捕获异常并弹窗_Java捕获异常的问题
  2. c语言自己编译自己,TCC研究(一): Tiny C Compiler最小的C语言编译器,自己编译自己...
  3. 浏览器的cookie和服务器存储的session有什么关联,下面妙文为你解答
  4. java web环境配置_JAVA Web开发环境配置
  5. 【django】三、常用的模板标签和过滤器
  6. 数据分析与挖掘建模实战002:数据获取
  7. 升级php5.4 mysql5.5_在CentOS上把PHP从5.4升级到5.5
  8. MySQL 5.7 主从复制配置
  9. Java 算法 友好数
  10. webwork在freemarker中使用iterator