Pass constant to super constructor - scala

How can I pass a constant from a sub class to a super constructor? Something like:
class SubClass extends SuperClass(Const) {
val Const = ...
}

Constants are usually placed in companion objects, so you can do it as follows:
class SubClass extends SuperClass(SubClass.Const)
object SubClass {
val Const = ...
}

Related

How I can extend a class that use a mixin to another class that are using mixin in flutter?

I have a class that has a mixin generated through freezed.
I have another class that has a mixin generated through freezed.
I want to extend the second class, but I receive a type error because the mixin methods have differences.
Example:
class A with _$A {
const factory A.initial() = _Initial;
}
class B with _$B {
const factory B.final() = _Final;
}
I want:
class B extends A with _$B, _$A {
const factory B.final() = _Final;
}
and then I should be able to use:
B.initial()

Modify constructor arguments before passing it to superclass constructor in Scala

I have a superclass:
class Filter(val param: ComplexFilterParams){
def this(config: String) = this(parseStrConfig(config))
And I need to create a subclass that gets a String argument and then parses it in another way and creates ComplexFilterParams.
Something like that:
class NewFilter(str:String) extends Filter {
Is there a way to do it?
I got one solution. But I think it's ugly. I create companion object, define there a convert method and do next:
class NewFilter(str:String) extends Filter(NewFilter.convert(str)) {
You can go mush easier with another apply implementation in companion object like:
class NewFilter(val param: ComplexFilterParams) extends Filter(param){
//other implementations
}
object NewFilter {
def apply(str: String) = new NewFilter(convert(str))
def convert(str: String): ComplexFilterParams = ...
}
val filter = NewFilter("config string")

Scala: Extend base class that contains 'apply' method

I have a base class in the 'common' module that looks like this:
class BaseClass(args: Seq[String] = Seq()) extends Serializable {
private val argMap: Map[String, String] =
// <More code here...>
object BaseClass {
def apply(args: Seq[String] = Seq()): BaseClass = new BaseClass(args)
}
Now I want to extend this BaseClass in my 'module' so I am trying this...
class MyNewClass(args: Seq[String] = Seq()) extends com.xyz.BaseClass {
// Add additional code here
}
object MyNewClass extends com.xyz.BaseClass {
def apply(args: Seq[String] = Seq()): MyNewClass = new com.xyz.MyNewClass(args)
}
My understanding is, when I instantiate MyNewClass it will automatically instantiate & call the 'apply' method of the base class but that's not happening. What is a proper way to extend the BaseClass in a way that all its variables & methods can be accessed via the Child class?
My understanding is, when I instantiate MyNewClass it will automatically instantiate & call the 'apply' method of the base class...
Your understanding isn't quite on.
extends com.xyz.BaseClass means that this class inherits from the base class, not the singleton object.
And new com.xyz.MyNewClass(args) creates a new instance of the specified class, bypassing the apply() method in any companion object.
What is a proper way to extend the BaseClass in a way that all its variables & methods can be accessed via the Child class?
The current code does exactly that. MyNewClass, and its companion object, inherits all members from BaseClass. Nothing is inherited from the BaseClass companion object because you can't extend an object, and you don't inherit the access permissions from BasseClass so while a BaseClass instance can access private members of the BaseClass companion object, a MyNewClass instance cannot.

WIth Squeryl (using Lift), how can I make two model classes a subclass of the same class?

Using Lift with Squeryl, how can I make two classes a subclass of the same class?
My classes look like the following:
class SubClass1 extends Record[SubClass1] with KeyedRecord[SubClass1] with CreatedUpdated[SubClass1] {
val id = ...
val field1a = StringField(...)
...
}
class SubClass2 extends Record[SubClass2] with KeyedRecord[SubClass2] with CreatedUpdated[SubClass2] {
val id = ...
val field2a = StringField(...)
}
I want SubClass1 and SubClass2 each to be a child class of some other class, say MyParentClass. So I would think that I would have to do something like this:
abstract class MyParentClass extends Record[MyParentClass] with KeyedRecord[MyParentClass] with CreatedUpdated[MyParentClass] {}
and then
class SubClass1 extends MyParentClass {
val id = ...
val field1a = StringField(...)
...
}
class SubClass2 extends MyParentClass {
val id = ...
val field2a = StringField(...)
...
}
This gives me errors, such as the fields (StringField) etc. not conforming to the right type. Any suggestions on how to do this?
Thanks,
You abstract superclass can't define a concrete type parameter, since it needs to be overriden by the subclasses. Try:
abstract class MyParentClass[A <: MyParentClass]
extends Record[A] with KeyedRecord[A] with CreatedUpdated[A]
Then:
class SubClass extends MyParentClass[SubClass]

Scala abstract class method that returns a new corresponding class child object

I have the following class in my mind:
abstract class MyClass (data: MyData) {
def update(): MyClass = {
new MyClass(process())
}
def process(): MyData = {
...
}
}
However, abstract classes cannot be instantiated so the line new MyClass(process()) is an error. My question is - is there any way to tell the compiler that in case of each of the child classes of MyClass I want to create an object of exactly that child class? It seems an overkill to write this method awhole in all child classes. Playing with type parameters of the class or method I could not acheive that myself.
How about something like this? MyClass is parametrized with the concrete type. Of course, all concrete classes have to implement a method that actually returns a new instance of Self.
trait MyClass[+Self <: MyClass[Self]] {
def update(): Self = {
makeNew(process())
}
def process(): MyData = {
// ...
}
protected def makeNew(data: MyData): Self
}
class Concrete0 extends MyClass[Concrete0] {
protected def makeNew(data: MyData) = new Concrete0
}
class RefinedConcrete0 extends Concrete0 with MyClass[RefinedConcrete0] {
override protected def makeNew(data: MyData) = new RefinedConcrete0
}
Credit: IttayD’s second update to his answer to this question.
To completly avoid implementing almost identical method in all subclasses you would need to use reflection. I guess that would be your last resort if you have chosen Scala.
So here is how to minimize the repetitive code:
// additional parameter: a factory function
abstract class MyClass(data: MyData, makeNew: MyData => MyClass) {
def update(): MyClass = {
makeNew(process())
}
def process(): MyData = {
...
}
}
class Concrete(data: MyData) extends MyClass(data, new Concrete(_))
This way you repeat only the shortest fragment required to instantiate the subclass.