score:1
agree with @mik378. but if you are in the process of migrating from the 2 args version to the 3 args version, you can:
trait base {
// mark this as deprecated
// no default implementation here because otherwise, a & b would need to
// be modified to add the 'override' keyword
@deprecated
def compute(arg1:type1, arg2:type2): returntype
// provide a default implementation for old implementations e.g. a / b
def compute(arg1:type1, arg2:type2, arg3:type3): returntype =
compute(arg1, arg2)
}
// convenience base class for new implementations e.g. c
abstract class newbase extends base {
override def compute(arg1: type1, arg2: type2): returntype =
throw new unsupportedoperationexception
}
class a extends base {
def compute(arg1:type1, arg2:type2): returntype = {
//detailed implementations
}
}
class b extends base {
def compute(arg1:type1, arg2:type2): returntype = {
//detailed implementations
}
}
// all new implementations extend 'newbase' instead of 'base'
class c extends newbase {
override def compute(arg1:type1, arg2:type2, arg3:type3): returntype = {
//detailed implementations
}
}
and now, you can just use the 3-args version for old & new objs,
val name = objs.map(_.compute(arg1, arg2, arg3))
score:1
you'll either need to define compute(arg1:type1, arg2:type2, arg3:type3)
in a
and b
and defined compute(arg1:type1, arg2:type2)
in c
or you can provide a default, no-op implementation in your trait
trait base {
def compute(arg1:type1, arg2:type2) {}
def compute(arg1:type1, arg2:type2, arg3:type3) {}
}
i'd also recommend defining the return type explicitly in base
edit
a full (simplified) working example using case classes:
trait base {
def compute(arg1: int, arg2: int): int = 0
def compute(arg1: int, arg2: int, arg3: int): int = 0
}
case class a() extends base {
override def compute(arg1: int, arg2: int): int = arg1 + arg2
}
case class b() extends base {
override def compute(arg1: int, arg2: int): int = arg1 - arg2
}
case class c() extends base {
override def compute(arg1: int, arg2: int, arg3: int): int = arg1 + arg2 - arg3
}
case class d(arg1: int, arg2: int, arg3: int, objs: seq[base]) {
val computed = objs map (_ match {
case x: c => x.compute(arg1, arg2, arg3)
case x: base => x.compute(arg1, arg2)
})
}
score:1
have you heard about interface segregation principle?
the interface-segregation principle (isp) states that no client should be forced to depend on methods it does not use.1 isp splits interfaces that are very large into smaller and more specific ones so that clients will only have to know about the methods that are of interest to them. such shrunken interfaces are also called role interfaces.
source: wikipedia
traits are in some ways similar to those named "interfaces".
basically, you have to split base
trait.
traits represent modules in scala and it's a good practice to keep them small so that we increase their ability to be combined and get larger abstractions.
you would end up with two traits: (i merely altered the naming to be clearer)
trait computation {
def compute(arg1:int, arg2:int): unit
}
trait specificcomputation {
def compute(arg1:int, arg2:int, arg3:int)
}
class a extends computation {
def compute(arg1:int, arg2:int) = {
//detailed implementations
}
}
class b extends computation {
def compute(arg1:int, arg2:int) = {
//detailed implementations
}
}
class c extends specificcomputation {
def compute(arg1:int, arg2:int, arg3:int) = {
//detailed implementations
}
}
if you want a class d
that should know about those two compute
method variants, you write:
class d extends specificcomputation with computation {
def compute(arg1:int, arg2:int) = {
//detailed implementations
}
def compute(arg1:int, arg2:int, arg3:int) = {
//detailed implementations
}
}
Source: stackoverflow.com
Related Query
- class needs to be abstract since method in trait is not defined error
- class needs to be abstract since value element in trait is not defined
- underscore "class needs to be abstract since method is not defined" error
- protected method that takes an abstract super class instance and the "access to protected method not permitted" error
- Scala: "class needs to be abstract, since method is not defined" error
- Type mismatch error when type is not defined in abstract class
- class needs to be abstract since its members are not instantiated
- Method is tail recursive when defined on object but not on class
- Error on scala class : recursive method printExpr needs result type
- why trait method needs asInstanceOf and class method don't
- Why is it not possible (in scala) to provide implementation for an abstract override method in the implementing base class
- AsyncTask.doInBackground - abstract method not implemented error in Android Scala project
- Class needs to be abstract error while using traits in scala
- Inheriting abstract types causing error saying that class is not an enclosing class
- Reflection does not see companion of subclass case class when defined in companion of extending trait
- Error in running Scala Program: Main method not found in class main, please define the main method
- Access a constant from the companion class inside a method defined in a trait
- Error : case class implementing parent's abstract method
- Scala abstract generic class with a generic method not compiling
- Why Scala reports error if does not specify this.type when using chain method in inherited class
- Getting an error in intellij referencing a scala method I'm not actually using in a class I have used
- Scala trait extending abstract class, how do I know whether an abstract method has been implemented or not
- Not able to call a method in Class ; Getting runtime error
- Json.reads on abstract class (Sealed trait is not supported: no known subclasses)
- Spark Scala Error - Error: Main method not found in class
- Difference between Abstract Class and Trait
- "Parameter type in structural refinement may not refer to an abstract type defined outside that refinement"
- If the Nothing type is at the bottom of the class hierarchy, why can I not call any conceivable method on it?
- Compiler error about class graph being not finitary due to a expansively recursive type parameter
- Difference between using sealed trait and sealed abstract class as a base class
More Query from same tag
- How to transform a decimal-point-separated string into a multi-dimensional hash?
- Using a trait name as a logger name
- Get type from class name in Scala
- Filtering a Scala List by type
- How can I change column types in Spark SQL's DataFrame?
- Scala Compile Error
- What goes into making a Proxy Server?
- How does RequestContext.reject work?
- How to calculate the log loss metric in scala/spark?
- getPersistentRDDs returns Map of cached RDDs and DataFrames in Spark 2.2.0, but in Spark 2.4.7 - it returns Map of cached RDDs only
- Implementation of ALS in Spark
- How to count record changes for a particular value of a column in a scala Dataframe
- How to reduce Dataset of tuple
- How can I call another task from my SBT task?
- "Yield" doesn't work in binding.scala
- how to use zip function spark java
- Scala : Akka - multiple event buses for actorsystem or having prioritized events?
- Can't find SttpBackends + "Error occurred in an application involving default arguments."
- How to test exceptions thrown inside map in Scala
- "fromString" method on case classes extending a sealed trait
- How to create generic method to update multiple columns in Slick?
- How to do a `getOrElseComplete` on `Promise`?
- How to join two Datasets using only Dataset API
- Scala: Can I declare a public field that will not generate getters and setters when compiled?
- Using pattern matching to swap two elements in scala
- What's the most efficient method of continually deleting files older than X hours on Windows?
- getting code coverage for java code with scala tests
- Save IndexedRowMatrix to file in scala spark
- pySpark: java.lang.UnsupportedOperationException: Unimplemented type: StringType
- CPS style for linked-list style function calls