类型参数化

在scala中,类型参数化(类似于泛型)使用方括号实现,如:Foo[A],同时,我们称Foo为高阶类型。如果一个高阶类型有2个类型参数,则在声明变量类型时可以使用中缀形式来表达,此时也称该高阶类型为中缀类型,示例如下:

class Foo[A,B]

val x:Int Foo String = null     // Int FooString 等同于 Foo[Int,String]

与java相似,scala的类型参数化也使用类型擦除实现(类型擦除是很差劲的泛型机制,不过可能是由于java的原因,scala也这样做了),类型擦除的唯一例外就是数组,因为在scala中和java中,它们都被特殊处理,数组的元素类型与数组值保存在一起。在scala中,数组是“不变”的(这点与java不同),泛型默认是“不变”的。

协变、逆变与不变:

拿Queue为例,如果S是T的子类型,那么Queue[S]是Queue[T]的子类型,就称Queue是协变的;相反,如果Queue[T]是Queue[S]的子类型,那么Queue是逆变的;既不是协变又不是逆变的是不变的,不变的又叫严谨的。

在scala中,泛型默认是不变的。当定义类型时,你可以在类型参数前加上“+”使类型协变,如Queue[+A]。类似地,你可以在类型参数前加上“-”使类型逆变。在java中使用类型时可以通过使用extends和super来达到协变逆变的目的,它们都是“使用点变型”,java不支持“声明点变型”。而scala中同时提供了声明点变型(“+”和“-”,它们只能在类型定义时使用)和使用点变型(“<:”和“>:”,类似于java中的extends和super,在使用类型时声明)。不管是“声明点变型”还是“使用点变型”,都遵循PECS法则,详见java泛型。需要注意的是:变型并不会被继承,父类被声明为变型,子类若想保持仍需要再次声明。

继承中的协变逆变:

c++、java、scala都支持返回值协变,也就是说在继承层次中子类覆盖超类的方法时,可以指定返回值为更具体的类型。c#不支持返回值协变。

允许参数逆变的面向对象语言并不多——c++、java、scala和c#都会把它当成一个函数重载。

--------------------- 本文来自 苏门学士 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/oinvuki3375/article/details/77979758?utm_source=copy

最新文章

  1. jsp使用EL表达式回传boolean值出错的问题
  2. windows下登录lunix服务器
  3. python 学习笔记7(类/对象的属性;特性,__getattr__)
  4. Python 决策树的构造
  5. SQLAlchemy指南(tutorial)
  6. [转]使用 jQuery Mobile 与 HTML5 开发 Web App —— jQuery Mobile 事件详解
  7. Flex4 DataGrid ItemRenderer内嵌方式
  8. [Angular 2] Understanding Pure &amp; Impure pipe
  9. 转:linux运维工程师
  10. Regex类
  11. 关于Eclipse的编码配置和字体大小设置
  12. ajax 基础
  13. gpg XXX NO_PUBKEY XXX
  14. 使用sshkey的方式访问gitlab
  15. Python 爬取淘宝商品信息和相应价格
  16. CentOS Android Studio桌面图标的创建
  17. js 判断是否可以打开本地软件
  18. 2.19 C++友元函数和友元类
  19. Stanford机器学习笔记-9. 聚类(K-means算法)
  20. log4net保存到数据库系列二:独立配置文件中配置log4net

热门文章

  1. 设计模式-(10)观察者模式 (swift版)
  2. git pull ,git fetch ,git merge
  3. codeforces 688D D. Remainders Game(中国剩余定理)
  4. BZOJ_1307_玩具_单调栈+双指针
  5. AutoIT: 返回文件目录下所有的文件名,包括子文件
  6. SQL2008中Merge的用法(转)
  7. E20180128-hm
  8. bzoj 3456: 城市规划【NTT+多项式求逆】
  9. Reduction operations
  10. springboot(十)SpringBoot消息中间件RabbitMQ