Scala中协变和逆变主要作用是用来解决参数化类型的泛化问题。由于参数化类型的参数(参数类型)是可变的,当两个参数化类型的参数是继承关系(可泛化),那被参数化的类型是否也可以泛化呢?在Java中这种情况下是不可泛化的,然而Scala提供了三个选择,即协变、逆变和非变,解决了参数化类型的泛化问题。

协变和逆变

在Scala语言中,协变和逆变到处可见。如List,Queue等属于协变协变和逆变的一种。

协变和逆变使用“+”,“-”差异标记。当我们定义一个协变类型List[+A]时,List[Child]可以是List[Parent]的子类型,当我们定义一个逆变类型List[-A]时,List[Child]可以是List[Parent]的父类型

+B是B的超集,叫协变

-A是A的子集,叫逆变

假设有参数化特质List,那么可以有三种定义。如下所示:

(1)  trait List [T]{}

非变。这种情况下,当类型S是类型A的子类型,则List [S]不可以认为是List [A]的子类型或父类型,这种情况和Java是一样的。

(2)  trait List [+T]{}

协变。如果Sextends A (S为子类型,A为父类型),则List [S]为子类型,List [A]为父类型S <: A => List [S] <: List [A]。

(3)  trait List [-T]{}

逆变。如果S extends A (S为子类型,A为父类型),则List [S]为父类型,List [A]为子类型,和协变互逆S <: A => Queue[S] >: Queue[A]。

那么,在Scala中如何定义协变逆变类呢,举例如下。

objectCovariantAndContravariantDemo {defmain(args: Array[String]): Unit = {//不变definv1: Invariant[Tiger] = newInvariant[Tiger]()//不可以赋值,编译器编译不通过definv2: Invariant[Cat] = inv1//协变defcov1: Covariant[Tiger] = newCovariant[Tiger]()//可以直接赋值defcov2: Covariant[Cat] = cov1//逆变defcont1: Contravariant[Cat] = newContravariant[Cat]()//可以直接赋值defcont2: Contravariant[Tiger] = cont1}/*** 定义一个不可变的类*/class Invariant[T] {}/*** 定义一个协变的类*/class Covariant[+T] {}/*** 定义一个逆变的类*/class Contravariant[-T] {}/*** 定义一个动物的类,具有行为(吃)*/class Animal {def eat() {println("Animal likeeat botany.")}}/*** 定义动物(猫)的类,具有行为(吃)*/class Cat extends Animal {override def eat() {println("Cat eatfish.")}}/*** 定义动物(老虎)的类,具有行为(吃)*/class Tiger extends Cat {override def eat() {println("Tiger eatmeat.")}}
}

上界和下界

类型的上界和下界,它们的含义如下。

1) U >: T

这是类型下界的定义,也就是U必须是类型T的父类(或本身,自己也可以认为是自己的父类)。

2) S <: T

这是类型上界的定义,也就是S必须是类型T的子类(或本身,自己也可以认为是自己的子类)

协变、逆变结合上下界

栗子

协变

逆变

trait c1[+T] {

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

trait c1[-T] {

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

object c2 extends c1[Int]

c2.method (3) // 3

c2.method (3.0) // 3.0

c2.method ("abc") // "abc"

object c2 extends c1[Int]

c2.method (3) // 3

c2.method (3.0) // 报错

c2.method "abc") // 报错

[Scala的协变和逆变]相关推荐

  1. Scala中协变(+)、逆变(-)、上界(:)、下界(:)简单介绍

    对于一个带类型参数的类型,比如 List[T],如果对A及其子类型B,满足 List[B]也符合List[A]的子类型,那么就称为covariance(协变) , 如果 List[A]是 List[B ...

  2. spark笔记之Scala中的协变、逆变、非变

    1.1. 协变.逆变.非变介绍 协变和逆变主要是用来解决参数化类型的泛化问题.Scala的协变与逆变是非常有特色的,完全解决了Java中泛型的一大缺憾:举例来说,Java中,如果有 A是 B的子类,但 ...

  3. Scala教程之:深入理解协变和逆变

    文章目录 函数的参数和返回值 可变类型的变异 在之前的文章中我们简单的介绍过scala中的协变和逆变,我们使用+ 来表示协变类型:使用-表示逆变类型:非转化类型不需要添加标记. 假如我们定义一个cla ...

  4. Scala入门到精通——第二十一节 类型参数(三)-协变与逆变

    本节主要内容 协变 逆变 类型通匹符 1. 协变 协变定义形式如:trait List[+T] {} .当类型S是类型A的子类型时,则List[S]也可以认为是List[A}的子类型,即List[S] ...

  5. scala 协变和逆变_Scala方差:协变,不变和逆变

    scala 协变和逆变 In this post, we are going to discuss about Scala Variance and it's use cases. 在本文中,我们将讨 ...

  6. 7.scala初识 柯里化、隐式参数、隐式转换、视图边界、上界、下界、协变、逆变

    1.前言: 学过java我们都知道,java中的继承是对类的增强,java中的代理.装饰是对对象方法的增强.而在scala中,隐式转换和隐式参数是Scala中两个非常强大的功能,隐式的对类的方法进行增 ...

  7. 不变(Invariant), 协变(Covarinat), 逆变(Contravariant) : 一个程序猿进化的故事

    阿袁工作的第1天: 不变(Invariant), 协变(Covarinat), 逆变(Contravariant)的初次约 阿袁,早!开始工作吧. 阿袁在笔记上写下今天工作清单: 实现一个scala类 ...

  8. 上界与下界-- 视图界定--协变与逆变

    1.上界与下界:Upper bound,lower bound                  作用:规定泛型的取值范围                  Int x                 ...

  9. C# 4.0中的协变和逆变(一)

    在刚刚落下帷幕的PDC上,我们得到了很多振奋的消息,包括C# 4.0及VS2010等等.Anders Liu 已经 将C# 4.0 新特性白皮书翻译了 出来,那里面有非常详细的介绍. C#的发展是很快 ...

  10. .NET可变性解析(协变和逆变)

    [一]何为可变性 可变性是.NET4.0中的一个新特性,可变性可分为 : 协变性.逆变性.不可变性. 那么在.NET4.0之前是否有可变性? 答案是肯定的,我们可以通过下面的几个实例来简单的了解一下. ...

最新文章

  1. Shiro第一个程序:官方快速入门程序Qucickstart详解教程
  2. 【无标题】ubuntu20.04 开机引导后黑屏 光标闪现 无法进入图形桌面的解决方案_Denis.Zzzzzzzz?的博客-CSDN博客_ubuntu20黑屏光标闪烁
  3. BIM机器人来袭、你害怕了吗
  4. 2016年湖南省第十二届大学生计算机程序设计竞赛
  5. EOS全球行南京站:降低用户及开发者门槛仍是2019 EOS关键词
  6. Excel 2016新增函数之IFS
  7. Python高级——GIL全局解释器锁问题
  8. 雅思阅读真经总纲_你们要的刘洪波《雅思阅读真经总纲》高清PDF扫描版来了!!...
  9. VB判断指定名字的进程是否存在函数
  10. FastDFS特性及问题思考
  11. sql 去除数据表中一列中字符串后边的空格...
  12. C++初学必练基础题【第四期】
  13. mysql 超级管理员权限_取得超级管理员权限
  14. 一个简单的新闻发布系统
  15. 为什么公司宁愿花 15k 重招一个新人,也不愿加薪 5k 留住老程序员?
  16. Layer 开启与关闭加载层
  17. wirehark数据分析与取证attack.pcap
  18. 搭建个人博客【搭建Hexo+Fluid博客并部署到GitHub/云服务器(阿里云/腾讯云)】
  19. 腾讯微信客服电话号码是多少呢/腾讯微信人工服务热线
  20. [渝粤教育] 西北工业大学 理论力学 参考 资料

热门文章

  1. 【SEED Labs 2.0】ICMP Redirect Attack Lab
  2. Wireshark基础知识(一)
  3. 2.9Unicode 文本标准化
  4. ANSYS 有限元分析 修改与编辑
  5. scrapy数据存入mysql_Scrapy爬虫实例教程(二)---数据存入MySQL
  6. vue之设置背景图片自适应屏幕
  7. linux系统被×××后处理经历
  8. linux下查看eml类型文件
  9. 【一文搞懂】FD_SET的使用
  10. 某试卷由26道题c语言,c语言模拟试题