score:2
The thing you need to think about is why do you need your Action
to have the execute
method to begin with. Probably, you have something like this elsewhere in your code:
def executeAll(actions: Seq[Action], params: Parameters) =
actions.foreach { _.execute(params) }
Note, that here your actions
list can contain actions of different types. if some of them except the parameter of type A
, and some need it to be of type B
, it won't work, because your params
parameter cannot be both.
For this reason, you cannot override a method to take a different parameter type in a subclass (actually, you can, but the type has to be a super-class of the original type, not a subclass. They say that functions are contravariant in their parameter types for this reas, but I digress).
If your Action1
and Action2
can actually deal with their parameters generically, through the trait interface without requiring them to be of a particular type, then the solution is simple: just change the declarations of your overriding methods to be override def execute(params: Parameters)
.
If this is not the case, and Action1
can only deal with parameters of type A
, then (1) there is, probably (although, not necessarily) something wrong with your design, and (2) you have to go with parametrization solution, as the other answer suggests. But then you would have to change all the places, that deal with Action
as well:
def executeAll[T <: Parameters](actions: Seq[Action[T]], params: T) = ...
This declaration constraints the type of the params
argument to match what the actions in the list expect, so that Action1.execute
will not be called with B
by mistake.
Now, as you mentioned in the comment to the other answer, you can't mix actions of different type, because it does not make sense: they are essentially different classes. If you are not going to use the execute
method, and just want to pass the list of different actions around some piece of code, you can use the wildcard syntax:
val actions: List[Action[_] = List(Action1(...), Action2(...))
Once again, this list can serve as a generic container for actions of any type, but you cannot use it to apply the execute
method generically, because that would require the parameter to be of different types at the same time.
score:4
One way is to parametrize Action
.
trait Action[T <: Parameters] {
def execute(param: T)
}
Then
class Action1 extends Action[A] {
override def execute(param: A)
}
class Action2 extends Action[B] {
override def execute(param: B)
}
def run[T <: Parameters](t: Action[T], param: T) {
t.execute(param)
}
// You don't need new for a case class
run(new Action1, A("a", 1.0))
You have to modify run
a little bit here because you can't get what you're asking for by subclassing alone. Argument types are contravariant, meaning that something that a function A => T
is a superclass of a function Parameters => T
. This is because while any argument of type A
works for both A => T
and Parameters => T
, only some arguments of type Parameters
will work for A => T
while all of them will work for Parameters => T
.
Source: stackoverflow.com
Related Query
- Accept any case class which extends a trait as argument in scala
- Declaring a method to accept an unknown case class as argument to use it in pattern matching in Scala
- A Scala generic function which can accept any T.Value given T extends Enumeration?
- How to instantiate trait which extends class with constructor
- In scala is it possible for a trait to extend a class which needs parameters?
- How to check which parameters of case class have default value using scala reflection 2.10
- Define a trait to be extended by case class in scala
- Is it possible to update fields of any case class implementing a common trait
- Scala class cant override compare method from Java Interface which extends java.util.comparator
- An object extends its companion case class in Scala
- scala case class default argument
- How to implement a trait with a generic case class that creates a dataset in Scala
- default case class argument depending on other arguments scala
- Can scala accept any derivation of a tuple as an argument list?
- Scala accept only String or Int generic case class in List
- scala class extend a trait with generic which is a type of a field
- Scala Case Class with Different Argument Types
- Scala Case class copy member of parent trait when calling copy()
- How to bind a class that extends a Trait with a monadic type parameter using Scala Guice?
- Scala Generics with case class extending sealed trait
- Scala How can Trait override toString Case Class that is Derived Off
- scala function to operate on any case class
- Scala case class constructor with WrappedArray argument
- Return a case class that extends a trait
- Scala case class with multiple-type argument
- Merge two lists which contains case class objects scala
- Scala Expose a Case class nested in a trait
- How to use circe with generic case class that extends a sealed trait
- Scala choose which trait to implement from in case of conflicting signatures?
- Which is faster for comparing case class object in scala : a) equals(==) method or b) equating hash values
More Query from same tag
- Scala syntax - pass string to object
- IntelliJ IDEA unable to find credentials for Artifactory
- Unable to override bash startup script in sbt-native-packager
- Scala: recursive match case?
- Scala, why when I pass a lambda function as argument to another function i cannot execute it
- Converting Java code to Scala code
- define a scala variable scope
- How can I pass a complex external variable, say a map's value to an UDF from the driver program in Spark with Java?
- Spark DataFrame filtering: retain element belonging to a list
- flash not found in Products.scala
- scala get instance of runtime class
- Combining mongodb codec registries in scala
- List files scala emr hdfs (csv file missing)
- How can I resolve dependencies when cross-compiling in Scala with sbt?
- Merge info from one list to another Scala
- Pass type information at runtime
- Spark with BloomFilter of billions of records causes Kryo serialization failed: Buffer overflow.
- Why does the Scala worksheet evaluate the stream?
- Slick3 with SQLite - autocommit seems to not be working
- What is most efficient way to do immutable byte arrays in Scala?
- Partial function for trait implementation in Scala
- How to start Scala Play application on Bluemix?
- why paramGridBuilder scala error with CountVectorizer?
- Handling null values in Dataframe
- java.lang.ClassNotFoundException: org.apache.hadoop.hbase.HBaseConfiguration
- How to know if a is variables defined in scala on Zeppelin
- Removing SBT projects and removing Typesafe Stack
- How to construct an empty Iterable subclass, generically, and in Scala.js
- Binary search not working
- Weird compile error involving type parameters with a wildcard