欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

scala java抽象理解_Scala - 抽象类型和隐式参数解析

发布时间:2024/10/8 编程问答 55 豆豆
生活随笔 收集整理的这篇文章主要介绍了 scala java抽象理解_Scala - 抽象类型和隐式参数解析 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

我正在使用Scala 2.10.4 .

请详细说明一下 - 实际的代码深深地嵌入了一个复杂的程序中,所以我不会解释这个问题,而是以时间的方式抽象出问题来讨论动物;-)

在scala我有两个特征 - 例如:

Animal ,和 HouseBase .

我没有权利改变Animal,但我继承了Dog,Rabbit,Fish等类 . 令人讨厌的是我不能改变每个子类,因为我没有拥有我使用的所有子类 .

我的动物都住在某个地方 - 他们的家必须从HouseBase继承 . 我可以改变HouseBase和它的子类(通过另一层抽象,如果必须的话) .

因此,Dog是Animal的子类,并且将存在于Kennel中,它是HouseBase的子类 .

一只兔子住在一个双雄,一条鱼住在坦克 .

请注意,这里没有强制执行1:1的关系 - 鱼也可以住在池塘里,我们也必须能够处理它 .

我希望的是 - 给定一个具体的动物(例如Fish),通过抽象类型Animal引用,并给定一个具体的返回类型(例如Tank),Scala将能够自动选择正确的隐含参数我在下面的设计 .

object AnimalSelectionProblem extends App {

def abstractFish : Animal = new Fish(true, 20.0)

def concreteFish : Fish = new Fish(false, 30.0)

def abstractDog : Animal = new Dog("tasty bone")

def concreteDog : Dog = new Dog("yummy bone")

def abstractRabbit : Animal = new Rabbit(5)

def concreteRabbit : Rabbit = new Rabbit(10)

import HouseImplicits._

val myTank1: Tank = HouseImplicits.create(abstractFish)

val myTank2: Tank = HouseImplicits.create(concreteFish)

val myKennel1: Kennel = HouseImplicits.create(abstractDog)

val myKennel2: Kennel = HouseImplicits.create(concreteDog) // This works

val myhutch1: Hutch = HouseImplicits.create(abstractRabbit)

val myhutch2: Hutch = HouseImplicits.create(concreteRabbit) // This works

}

但是有2个相关的问题 .

问题1 - 如果动物被引用为摘要,则隐式参数将仅查找采用抽象类型(Animal)而不是基础具体类型的函数 . 我怀疑解决方案可能是使用ClassTags,因为Scala似乎没有使用运行时信息?我实现了这个目标并且无可救药地失去了(我对Scala来说还是新手!) .

问题2 - 如果我的动物可以生活在多种类型的House中,那么会出现类似的问题,即使指定了具体的返回类型,编译器也会发现Fish的两个隐含对象不明确 . 我有点难过这里要做什么!

我可以用手动样板制作解决方案来匹配运行时的类型,但这不是很容易扩展 .

任何想法都感激不尽!其余代码如下 .

编辑 - 这些链接似乎证实了我所怀疑的 . 使用了编译时多态性,因此无法知道运行时类型:

所以,我想现在我的问题是,鉴于此,有没有办法修改我的示例以使用运行时调度?

Animals:

trait Animal {

}

class Dog(val boneName: String) extends Animal

class Rabbit(val length: Int) extends Animal

class Fish(val likesFrogs: Boolean, val optimumTemp: Double) extends Animal

Houses and Implicits:

sealed trait HouseBase

// Made up some arbitrary member variables

case class Kennel(posessions: Seq[String]) extends HouseBase

case class Hutch(length: Int) extends HouseBase

case class Tank(waterTemp: Double) extends HouseBase

case class Pond(containsFrog: Boolean) extends HouseBase

sealed trait HouseCreator[A <: animal hb housebase>

def create(animal: A): HB

}

object HouseImplicits {

implicit object BuildKennelForDog extends HouseCreator[Dog, Kennel] {

override def create(dog: Dog): Kennel = {

new Kennel(Seq(dog.boneName))

}

}

implicit object BuildTankForFish extends HouseCreator[Fish, Tank] {

override def create(fish: Fish): Tank = {

new Tank(fish.optimumTemp)

}

}

implicit object BuildPondForFish extends HouseCreator[Fish, Pond] {

override def create(fish: Fish): Pond = {

new Pond(fish.likesFrogs)

}

}

implicit object BuildHutchForRabbit extends HouseCreator[Rabbit, Hutch] {

override def create(rabbit: Rabbit): Hutch = {

new Hutch(rabbit.length*5)

}

}

def create[A <: animal h housebase a house: housecreator :>

val newHouse = house.create(animal)

newHouse

}

}

总结

以上是生活随笔为你收集整理的scala java抽象理解_Scala - 抽象类型和隐式参数解析的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。