I would like to instantiate an object with a generic type in Dart.
So far, there is nothing very complicated. This is how I would normally do it:
MyClass <MyType> x = new MyClass <MyType> ();
However, there I have a somewhat special case. The "MyType" type I want to use is contained in a variable.
And there, I do not see how to do the instantiation.
I specify that it is for a Flutter project.
Could you help me please ?
This way you can create a generic class and customize it to your needing:
class GenericClass<T> {
T t;
T getModel() => t;
void setModel(T t) => this.t = t;
}
You can also define its type to extends your 'CustomModel':
class GenericClass<T extends CustomModel>{
...
}
For using just get instance from class like this:
GenericClass<int> intClass = new GenericClass();
I hope it was useful for you :)
There is no path without using something reflective like dart:mirrors to go from a String to a type. This is by design, to allow tree-shaking and optimizations to be more productive.
Related
For example, I know that I can add extension to class String like this:
val String.isValidEmail : Boolean
get() {
val expression = "^[\\w\\.-]+#([\\w\\-]+\\.)+[A-Z]{2,4}$"
val pattern = Pattern.compile(expression, Pattern.CASE_INSENSITIVE);
val matcher = pattern.matcher(this)
return matcher.matches()
}
Now I want to add a class as extension into another class, which I think the implementation will be like this:
class Networking {
....
}
class Networking.Email {
....
}
// MainActivity.kt
val email = Networking.Email()
But this gave me error for "Networking.Email". For the "Networking" part: Redeclaration: Networking. For the "Email" part: Expecting a top level declaration. Is this actually possible in Kotlin?
No, there are no such things as extension classes in Kotlin. See here:
Kotlin, similar to C# and Gosu, provides the ability to extend a class
with new functionality without having to inherit from the class or use
any type of design pattern such as Decorator. This is done via special
declarations called extensions. Kotlin supports extension functions
and extension properties.
I would like to build a case class DataObject.
case class DataObject(parameter: Double)
I want to be able to extend this if necessary with the functionality to call a function. For that I want to be able to extend it with a trait DataObjectFunctionable to make it functionable. This functionality should only be assignable to DataObject because it only makes sense there.
trait DataObjectFunctionable {
this: DataObject =>
def unimportantfunction(): Double = parameter + 1
protected val aFunction: AFunction
}
The exact implementation shall be defined later, thus I keep the Function abstract. Since the extra functionality shall only be a trait for DataObject and a DataObject with the functionality would be DataObjectFunctionable, I give DataObjectFunctionable as input type for the function.
trait AFunction {
def value(in: DataObjectFunctionable)
}
Now I am going to define my concrete Function.This is all good and well, until I want to excess the inputs parameters.
object MyFunction extends AFunction {
def value(in: DataObjectFunctionable) = in.parameter + 2
}
Now I am told that in.parameter cannot be resolved. Why is that? this: DataObject => makes sure that DataObject's members are also available inside DataObjectFunctionable (as seen with unimportantfunction). Why is it that though this is the case, I don't have parameter at my disposal in MyFunction? Is it just language design or am I doing something wrong?
What should I do instead? I found that
trait DataObjectFunctionable extends DataObject {
this: DataObject =>
def unimportantfunction(): Double = parameter + 1
protected val aFunction: AFunction
}
solves the issue, but is this really the way to go?
As far as I understand, trait DataObjectFunctionable extends DataObject means "the trait DataObjectFunctionable can only be extended by an DataObject or a subclass of it". However, as far as I understand this: DataObject => means the same... Maybe there is a misunderstanding here that led to my issue.
By the way, this is what I hoped for:
val myObject1 = new DataObject(parameter = 5) extends DataObjectFunctionable {
override protected val aFunction: AFunction = MyFunction
}
val myObject2 = new DataObject(parameter = 5)
myObject1.value // returns 5
myObject2.value // that should not be possible, since myObject2 does not get the functionality. I want this to throw a compiler error
Self-reference is akin to "private inheritance".
If you don't want the inherited parameters to be "private" to the trait, why don't you make it inherit from DataObject rather than self-reference it?
Alternatively, you can "export" the self-referenced parameter from the trait with something like def param = parameter.
Also, a word of caution: don't extend case classes, not even with traits. It is almost always a bad idea.
In Scala, is it possible to call a member method without having to call an instance of itself?
For instance, having this class:
class Model {
def action(value : String) = {
// Do action
}
}
this object implementation works:
object MyModel extends Model {
this action "doSomething"
}
But I would like to do something like this:
object MyModel extends Model {
action "doSomething"
}
As one does with Java property files, since it's a neat way to define the state of an object.
I managed to define an alias for this:
def declare = this
but it's the same issue of having to use a word in front of the call to the member method.
Is there an option to do this?
Yes, but you have to use parentheses:
object MyModel extends Model {
action("doSomething")
}
See this answer for example for more detail about when parentheses can or cannot be omitted.
As a side note, you could also alias this as follows:
object MyModel extends Model { declare =>
declare action "doSomething"
}
This is often useful if you want to refer to a class's this from inside of a nested class—it's a bit less verbose than writing Outer.this.x as you would in Java.
I'm trying to get a better understanding of Scala, and I can't seem to find a valid usecase for code like the following:
class C extends { def m() { /* ... */ } }
What is the rationale for allowing such constructs?
Thanks!
I guess the only rationale here is "avoid special cases if possible". You can extend any class, an anonymous class is a class, so you can extend an anonymous class.
That is not, in fact, an anonymous class! It's an early initializer and it runs as part of the constructor that goes before its superclass.
Quoting the excellent answer from another stackoverflow question:
abstract class X {
val name: String
val size = name.size
}
class Y extends {
val name = "class Y"
} with X
If the code were written instead as
class Z extends X {
val name = "class Z"
}
then a null pointer exception would occur when Z got initialized, because size is initialized before name in the normal ordering of initialization (superclass before class).
It's called Early definitions and they deal with super class initialization order problem.
I know that objects are treated pretty much like singletons in scala. However, I have been unable to find an elegant way to specify default behavior on initial instantiation. I can accomplish this by just putting code into the body of the object declaration but this seems overly hacky. Using an apply doesn't really work because it can be called multiple times and doesn't really make sense for this use case.
Any ideas on how to do this?
Classes and objects both run the code in their body upon instantiation, by design. Why is this "hacky"? It's how the language is supposed to work. If you like extra braces, you can always use them (and they'll keep local variables from being preserved and world-viewable).
object Initialized {
// Initalization block
{
val someStrings = List("A","Be","Sea")
someStrings.filter(_.contains('e')).foreach(s => println("Contains e: " + s))
}
def doSomething { println("I was initialized before you saw this.") }
}
scala> Initialized.doSomething
Contains e: Be
Contains e: Sea
I was initialized before you saw this.
scala> Initialized.someStrings
<console>:9: error: value someStrings is not a member of object Initialized
Initialized.someStrings
Rex has it right, I just wanted to point out a pattern I use a lot, that saves you from having to use vars, while avoiding namespace pollution by intermediate values.
object Foo {
val somethingFooNeeds = {
val intermediate = expensiveCalculation
val something = transform(intermediate)
something
}
}
If it makes you feel better, you can create some class with protected constructor and object will create singleton of this class:
sealed class MyClass protected (val a: String, b: Int) {
def doStuff = a + b
}
object MyObject extends MyClass("Hello", b = 1)
Also notice, that sealed stops other classes and objects to extend MyClass and protected will not allow creation of other MyClass instances.
But I personally don't see any problems with some code in the body of the object. You can also create some method like init and just call it:
object MyObject {
init()
def init() {
...
}
}
The body of object and class declarations IS the default constructor and any code placed in there will be executed upon first reference, so that is exactly the way to do it.