Scala 泛型实现应根据子类返回子类型

Scala 泛型实现应根据子类返回子类型,scala,generics,inheritance,polymorphism,return-type,Scala,Generics,Inheritance,Polymorphism,Return Type,在我的应用程序中,有很多资源是以相同的方式加载的,所以我想抽象这些方法 我创造了一种叫做资源的特质 现在,这种特质有三项任务要完成 它为任意数量的资源实现缓存。 它为可以加载该类型资源的所有加载程序实现一个映射。例如,对于可能包含PNGLoader、JPGLoader甚至GIFLoader的资源映像 实现通用/默认方法来检索给定路径上的资源 看起来是这样的: trait Resources { private val loaders: mutable.HashMap[String, Re

在我的应用程序中,有很多资源是以相同的方式加载的,所以我想抽象这些方法

我创造了一种叫做资源的特质

现在,这种特质有三项任务要完成

它为任意数量的资源实现缓存。 它为可以加载该类型资源的所有加载程序实现一个映射。例如,对于可能包含PNGLoader、JPGLoader甚至GIFLoader的资源映像 实现通用/默认方法来检索给定路径上的资源 看起来是这样的:

trait Resources
{
    private val loaders: mutable.HashMap[String, ResourceLoader] = new mutable.HashMap[String, ResourceLoader]
    private val cache: mutable.HashMap[String, Resource] = new mutable.HashMap[String, Resource]

    def get(path: String): Resource =
    {
        // Check cache... if fail, see if there is a loader registered
    }

    private def load(path: String): Resource =
    {
        // Check if there is a loader for the file, if so loader.load(path)
    }

    def registerLoader(...)
}

trait ResourceLoader
{
    def load(path: String): Resource
}

trait Resource
trait Resources[ResourceType <: Resources[ResourceType]]
{
      private val cache: mutable.HashMap[String, ResourceType] = new mutable.HashMap[String, ResourceType]
   def get(path: String): ResourceType = {...}
}

trait ResourceLoader[ResourceType <: ResourceLoader[ResourceType]]
{
    def load(path: String): ResourceType
}
现在想象一下:

class Image extends Resource

object Images extends Resources

object PNGLoader extends ResourceLoader
{
    Textures.register("png", this)

    override def load(path: String): Image =
    {
        // Do some magic
    }
}
现在,有一个问题。我已经尝试过这种方法,但问题是:

val img: Image = Images.get("images/test.png")
将导致类型不匹配,因为图像!=资源

所以我需要这样做

val img: Resource = Images.get("images/test.png")
或者手动铸造。两者都不是真正的选择

现在,我试着做这样的事情:

trait Resources
{
    private val loaders: mutable.HashMap[String, ResourceLoader] = new mutable.HashMap[String, ResourceLoader]
    private val cache: mutable.HashMap[String, Resource] = new mutable.HashMap[String, Resource]

    def get(path: String): Resource =
    {
        // Check cache... if fail, see if there is a loader registered
    }

    private def load(path: String): Resource =
    {
        // Check if there is a loader for the file, if so loader.load(path)
    }

    def registerLoader(...)
}

trait ResourceLoader
{
    def load(path: String): Resource
}

trait Resource
trait Resources[ResourceType <: Resources[ResourceType]]
{
      private val cache: mutable.HashMap[String, ResourceType] = new mutable.HashMap[String, ResourceType]
   def get(path: String): ResourceType = {...}
}

trait ResourceLoader[ResourceType <: ResourceLoader[ResourceType]]
{
    def load(path: String): ResourceType
}
但这当然不行,因为尽管类型的名称完全相同,但没有共享信息,所以ResourceLoader的ResourceType!=ResourceType资源,因此loader.loadpath无法工作

总结:我想为ImageLoader返回一个具体类型,它应该是图像,对于VideoLoader,它应该是视频,但有不同的类负责缓存,比如图像和视频,所以我可以:

val视频:视频=视频。获取。。。和val image:image=Images.get

所以应该有不同的缓存,以便我可以刷新所有的视频或所有的图像等

另外,我刚刚看到,我可能需要将private更改为protectedg

您确实可以使Resources和ResourceLoader通用,但上限可以更简单:A