zoukankan      html  css  js  c++  java
  • Scala 入门笔记

    [T <: A] UpperBound 上界:T的上界是A类型,即T的父类是A类型

    abstract class Animal {
    def name: String
    }

    abstract class Pet extends Animal {}

    class Cat extends Pet {
    override def name: String = "Cat"
    }

    class Dog extends Pet {
    override def name: String = "Dog"
    }

    class Lion extends Animal {
    override def name: String = "Lion"
    }

    class UpperBoundDemo2[P <: Pet](p: P) {
    def pet: P = p
    }

    object UpperBoundDemo2 {
    def main(args: Array[String]): Unit = {
    val dogContainer = new UpperBoundDemo2[Dog](new Dog)
    val catContainer = new UpperBoundDemo2[Cat](new Cat)

    println(dogContainer.pet.name)

    // 这行编译会报错,因为UpperBoundDemo2 要求 P 必须是 Pet的子类,而Lion是继承于Animal的
    val lionContainer = new UpperBoundDemo2[Lion](new Lion)
    }
    }

      

    [B >: A] LowerBound 下界:B类是的子类是A

    trait Node[+B] {
      // 因为函数的参数是逆变,返回是协变,所以此处需要用到下界,来传入B的父类U,满足逆变
      def prepend[U >: B](elem: U): Node[U]
    }
    
    case class ListNode[+B](h: B, t: Node[B]) extends Node[B] {
      override def prepend[U >: B](elem: U): Node[U] = ListNode(elem, this)
      def head: B = h
      def tail: Node[B] = t
    }
    
    case class Nil[+B]() extends Node[B] {
      override def prepend[U >: B](elem: U): Node[U] = ListNode(elem, this)
    }
    
    object LowerBoundClass extends App {
      trait Bird
      case class AffricanSwallow() extends Bird
      case class EuropeanSwallow() extends Bird
    
      val affricanSwallowList =  ListNode[AffricanSwallow](AffricanSwallow(), Nil())
      val birdList: Node[Bird] = affricanSwallowList
    
      birdList.prepend(new EuropeanSwallow)
    
    
    }
    

      

    [B <% A] ViewBound 表示B类型需要转换成A类型,需要一个隐式转换函数

    [B : A] ContextBound 需要一个隐式转换的值

      [-A] 逆变, 作为参数类型,如果A是T的子类,那么C[T]是C[A]的子类

      

    abstract class Printer[-A] {
      def print(value: A): Unit
    }
    
    class AnimalPrinter extends Printer[AnimalC] {
      override def print(value: AnimalC): Unit = {
        println("This Animal's name is: " + value.name)
      }
    }
    
    class CatPrinter extends Printer[CatC] {
      override def print(value: CatC): Unit = {
        println("This Cat's name is: " + value.name)
      }
    }
    
    object ContravarianceTest extends App {
      val myCat: CatC = CatC("Tom")
    
      def printMyCat(printer: Printer[CatC]): Unit = {
        printer.print(myCat)
      }
    
      val catPrinter: Printer[CatC] = new CatPrinter
      val animalPrinter: Printer[AnimalC] = new AnimalPrinter
    
      // Printer[AnimalC] 可以替换 Printer[CatC] 而反过来不可以
      printMyCat(catPrinter)
      printMyCat(animalPrinter)
    }
    

      

      [+B] 协变,作为返回类型,如果B是T的子类,那么C[B]是C[T]的子类

    如下面例子,cat、dog都是Animal的子类,Scala标准库中有 sealed abstract class List[+A],所以List[cat], list[dog]都可以替换

    List[Animal]的位置,因为cat、dog都是Animal的子类

    abstract class AnimalC {
      def name: String
    }
    
    case class CatC(name: String) extends AnimalC
    case class DogC(name: String) extends AnimalC
    
    class CovarianceTest {
    
    }
    
    object CovarianceTest extends App {
      def printAnimalName(animals: List[AnimalC]): Unit = {
        animals.foreach(animal => println(animal.name))
      }
    
      val cats: List[CatC] = List(CatC("Tom"), CatC("Jack"))
      val dogs: List[DogC] = List(DogC("Nill"), DogC("Jim"))
    
      printAnimalName(cats)
      printAnimalName(dogs)
    }
    

      

  • 相关阅读:
    NTP on FreeBSD 12.1
    Set proxy server on FreeBSD 12.1
    win32 disk imager使用后u盘容量恢复
    How to install Google Chrome Browser on Kali Linux
    Set NTP Service and timezone on Kali Linux
    Set static IP address and DNS on FreeBSD
    github博客标题显示不了可能是标题包含 特殊符号比如 : (冒号)
    server certificate verification failed. CAfile: none CRLfile: none
    删除文件和目录(彻底的)
    如何在Curl中使用Socks5代理
  • 原文地址:https://www.cnblogs.com/sunnystone85/p/11371417.html
Copyright © 2011-2022 走看看