开发者

Writing a method to return a java Class constrained to a certain type in Scala

开发者 https://www.devze.com 2023-03-22 22:17 出处:网络
For example, I have this: abstract class Vehicle class Car extends Vehicle And I want to write a method that returns a java Class, but constrained to only Classes of type Vehicle.

For example, I have this:

abstract class Vehicle

class Car extends Vehicle

And I want to write a method that returns a java Class, but constrained to only Classes of type Vehicle.

object CarDealer {
  def getVehicularClass: Class[Vehicle] = classOf[Car]
}

I am not able to开发者_Python百科 get the following different approaches to work:

  1. The way I would normally deal with this

    object CarDealer {
      def getVehicularClass[A <: Vehicle]: Class[A] = classOf[Car]
    }
    
    [error]  found   : java.lang.Class[Car](classOf[Car])
    [error]  required: Class[A]
    [error]   def getVehicularClass[A <: Vehicle]: Class[A] = classOf[Car]
    
  2. Using an abstract type

    type V <: Vehicle
    
  3. Using an implicit manifest (seems like it only constrains method arguments and not return values)

Can anyone help?

Thanks!


Vehicle is the supertype. You don't know that some subtype A of Vehicle is going to include Car, so you can't write it generically that way. What if someone asked for a Bus? The CarDealer can't help, but the type signature promises that it can make it work for any A <: Vehicle that you ask for.

If you don't care about preserving the real type of the vehicle, just write

object CarDealer {
  def getVehicularClass: Class[Vehicle] = classOf[Car]
}

Alternatively, if you want some interface obeyed, you specify in the interface what you want:

trait VehicleClass[A <: Vehicle] {
  def getVehicularClass: Class[A]
}

and then you have your object state which subclass of vehicle it is promising to return:

object CarDealer extends VehicleClass[Car] {
  def getVehicularClass = classOf[Car]
}

and now all promises are specified and lived up to.


The type Class[T] is invariant in type T. Thus even if A extends B, classOf[A] is not a subtype of classOf[B]. Therefore there's no exact solution to your problem...


This constrain is adequately expressed with existential types:

object CarDealer {
  def getVehicularClass: Class[_ <: Vehicle] = classOf[Car]
}

Of course, there might be other requirements that make an existential type inappropriate, but your problem is not particularly well stated.

0

精彩评论

暂无评论...
验证码 换一张
取 消