大数据学习26:Scala泛型及隐式转换

本文深入解析Scala中的泛型应用,包括泛型类、泛型函数、上界与下界、视图界定、协变和逆变的概念及使用场景。同时,详细阐述了隐式转换、隐式参数和隐式类的原理与实践,帮助读者掌握Scala高级特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

(一)泛型

	1.泛型类:定义类的时候,可以带有一个泛型的参数

For Example:

object GenericClass {
  def main(args: Array[String]): Unit = {
    //定义一个Int 类型

    var v1 = new GenericClass[Int]
    v1.set(1)
    println(v1.get())

    var v2 = new GenericClass[String]
    v2.set("Hello Scala")
    println(v2.get())

  }
}
class  GenericClassInt{
  //定义一个整数的变量
  private var content:Int = 10

  //定义get和set
  def set(value:Int) = {content = value}
  def get():Int = {content}
}

class  GenericClassString{
  //定义一个整数的变量
  private var content:String = ""

  //定义get和set
  def set(value:String) = {content = value}
  def get():String = {content}
}

class GenericClass[T]{
  //定义一个整数的变量
  private var content:T = _

  //定义get和set
  def set(value:T) = {content = value}
  def get():T = {content}
}
	2.泛型函数:定义函数的时候,接收一个泛型参数
		举例:
				(1)定义函数:创建一个Int类型的数组
					   def mkIntArray(elem:Int*)= Array[Int](elem:_*)
					   mkIntArray(1,2,3)
				 (2)定义函数:创建一个String类型的数组
				 			def mkStringArray(elem:String*)= Array[String ](elem:_*)
				 			mkStringArray("Tomn","MArry")
				 (3)定义一个泛型函数
				 			 def mkTArray[T:ClassTag](elem:T*)= Array[T](elem:_*)
				 			 mkTArray("Hello Tag")

	3.上界和下界upper bound lower bound
	
						作用:是规定泛型的取值范围
						
	4.视图界定:View bound:扩展了上界和下界
						除了可以接收上界和下界规定的类型外,还可以接收能够通过隐式转换过去的类型用%表示
						 def addTwoString [T<%String](x:T,y:T)= {print(x+"***"+y)}
						(1)可以接收String和String的子类
						(2)可以接收能够转换成String的其他数据

						调用 addTwoString(1,2)
						error :No implicit view available from Int => String

						一定定义转换的规则(通过隐式函数来实现):多了一个关键字implicit
						  implicit def int2String(n:Int):String = {n.toString}

						调用:
									 addTwoString(1,2)
						执行过程:(1)首先调用int2String,把int 转成String
											(2)调用addString,拼加字符串

											
	5.协变和逆变
		概念:
			(1)协变:表示在类型参数的前面加上 +
			(2)逆变:表示在类型参数的前面加上 -
			
		总结:Scala的协变:泛型变量的值可以是本身类型或者其子类的类型
				   Scala的逆变:泛型变量的值可以是本身类型或者其父类的类型
//Scala的协变:泛型变量的值可以是本身类型或者其子类的类型

object DemoClass {
  def main(args: Array[String]): Unit = {
    //定义一个鸟吃东西的对象

    var c1:EatSomthing[Bird] = new EatSomthing[Bird](new Bird)
   // var c2 :EatSomthing[Animal] = new EatSomthing[Animal](new Animal)

    //问题:能否把c1付给c2
    //原因:尽管Bird 是Animal的子类,但是EatSomeThing不是EatSomething[Animal]的子类
    var c2:EatSomthing[Animal] = c1
  }
}


class Animal
class Bird extends Animal
class Sparrow extends Bird

class EatSomthing[+T](t:T)
//Scala的逆变:泛型变量的值可以是本身类型或者其父类的类型
object DemoClass2 {
  def main(args: Array[String]): Unit = {
    //定义一个鸟吃东西的对象

    var c1 :EatSomthing2[Bird2] = new EatSomthing2[Bird2](new Bird2)

    //定义一个麻雀吃东西的对象
    var c2 :EatSomthing2[Sparrow2] = c1


  }
}
class Animal2
class Bird2 extends Animal2
class Sparrow2 extends Bird2

class EatSomthing2[-T](t:T)

(二)隐式转换

/**
  * 定义一个隐式转换
  *
  * */

object ImplicitConversion {
//定义一个隐式转换函数,把Fruit纂成Monkey
  implicit def fruit2Monkey(f:Fruit):Monkey = {new Monkey(f)}

  def main(args: Array[String]): Unit = {
    //定义一个水果对象
    var f:Fruit = new Fruit("Banana")

    //问题是:能否调用下面函数
    //如果可以把水果转成monkey就可以调用
    f.say()


  }
}

//定义一个隐式转换函数
class Fruit(name:String){
  //得到水果的名字
  def getFruitName():String = name
}

//猴子
class Monkey(f:Fruit){
  def say() = {println("Monkey Like "+f.getFruitName())}
}

隐式参数
概念:使用implicit 申明函数的参数叫隐式函数,我们也可以使用隐式参数实现隐式的转换
在这里插入图片描述
在这里插入图片描述

隐式类

目的是:增强类的扩展性

object ImplicitClassDemo {

  //定义一个隐式类,来增加1这个对象的功能
  implicit class Calc(x:Int){
    def add(y:Int):Int = x+y
  }

  def main(args: Array[String]): Unit = {
        //执行两个函数的求和
    println("两个函数的和是:"+1.add(2))//实际上调用Calc.add方法

  }

}

隐式类的执行过程:
1.当1.add(2),Scala的编译器不会立即报错,在当前域中查找,有没有implict修饰的,同时可以将Int作为参数的构造器。并且具有add方法的类。通过查找,找到了Calc
2.利用隐式类Calc来执行add方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值