Learning Flutter/getx package I came across the sample code like the following:
import 'package:get/get.dart';
class MyHomePageController extends GetxController {
final count = 0.obs;
}
The code 0.obs scares me. I mean how an integer can have a .obs attribute? what has the getx pacakge done to my code?
This is a feature of dart language called extension introduced in Dart 2.7, it is a way to add functionality to existing libraries.
You might use extension methods without even knowing it.
For example, when you use code completion in an IDE, it suggests extension methods alongside regular methods.
For example, consider the following code that parses a string into an integer:
int.parse('42')
It might be nice — shorter and easier to use with tools — to have that functionality be on String instead:
'42'.parseInt()
To enable that code, you can import a library that contains an extension of the String class:
import 'string_apis.dart';
// ···
print('42'.parseInt()); // Use an extension method.
Extensions can define not just methods, but also other members such as getter, setters, and operators. Also, extensions have names, which can be helpful if an API conflict arises. Here’s how you might implement the extension method parseInt(), using an extension (named NumberParsing) that operates on strings.
extension NumberParsing on String {
int parseInt() {
return int.parse(this);
}
// ···
}
SUMMARY
the get package use extensions behind the scene to call getter of RxInt.
Object so the attribute is not actually called upon primitive datatype
this is from the source code of the get package ... you can access it by pressing ctrl+ ".obs"
extension IntExtension on int {
/// Returns a `RxInt` with [this] `int` as initial value.
RxInt get obs => RxInt(this);
}
Related
In Swift, I am trying to create a generic class that can extend another class, while inheriting from it. I am able to do it in C++ as follows, but is there a way to do the same in Swift?
class Atom {};
template<typename Base, typename Extension>
class Extend: Base {
Extension _value;
};
int main() {
return 0;
}
One approach I have been trying to apply is Protocol Oriented Design, but it doesn't seem to be able to take a class and extend it. The best I reached is something like creating the extension manually, and declaring that it does extend Atom, but at that point, I would just create another class and add to it the respective property manually.
One way to do it is by generating the code for the subclass at compile or run time. check these answers of these questions:
How to generate code dynamically with annotations at build time in Java?, and Generating, compiling and using Java code at run time?.
You can add a custom generic method to the base class that would be overridden by each subclass (in the generated code) and it may return Object. It would be a working approach, if it's worth the hassle.
I'm using a third-party library for a new app that I'm making using Swift. The author of the class/library has made it final using the final keyword, probably to optimise and to prevent overriding its properties and methods.
Example:
final public class ExampleClass {
// Properties and Methods here
}
Is it possible for me extend the class and add some new properties and methods to it without overriding the defaults?
Like so:
extension ExampleClass {
// New Properties and Methods inside
}
An extension may not contain stored properties but you can add methods inside.
Extensions (like Objective-C categories) don't allow stored properties.
Methods and computed properties are fine though.
A common (but IMO hacky) workaround in Objective-C was to use associated objects to gain storage within categories. This also works in Swift if you import ObjectiveC.
This answer contains some details.
Yes, you can extend a final class.
That extension has to follow the usual rules for extensions, otherwise it's nothing special.
While you cannot create new stored properties in extensions you can add methods and computed properties.
Example computed property:
extension ExampleClass {
// computed properties do not have a setter, only get access
var asInt: Int? {
Int(aStringPropertyOnTheClass)
}
}
What are the implications of doing the following:
protocol A {
func f()
}
extension A {
final f() {}
}
I'm looking to understand what putting final in the extension over here does when compared to not putting it. I know what final does, I'm looking to understand overriding behaviour for classes implementing/not implementing f and their subclasses.
You can no longer mark extension funcs as final.
https://bugs.swift.org/browse/SR-1762
For Swift 2.0: Protocol Extensions
Methods, properties, or subscripts that you add to a class in an extension can also be marked as final within the extension’s definition.
Referring to this question of Inheritance, final keyword would not allow to override the (final) method defined in Extension, when it's Sub-classed.
For Swift 1.2:
This might be useful in context of Extensions Extensions can add new functionality to a type, but they cannot override existing functionality
Few things to look in context of Extensions, while decide on architecture of applications:
Protocol's cannot be extended to Extension.
It has go through a Class.
Existing functionality cannot be overridden (invalid redeclaration of)
On final keyword, this is my take it has no impact on Extensions methods as compared to classes(Inheritance). Please correct me if I'm wrong here.
Demo links:
Protocol A-->Class B-->Extension B
Protocol A-->Class B-->Extension B, then Class B --> Class C
This question has been asked (and probably answered) in the old Haxe forums on babble ... but it appears that that entire forum system no longer functions. Therefore, I'm asking here:
In Haxe, I need to declare an "Interface" to a class which includes a static function, "instance()." But when I do so:
You can't declare static fields in interfaces
So I remove the word "static" from public function instance() [...], and I get this:
Field instance needed by [...] is missing.
Apparently a "Catch-22." But there obviously must be some easy solution. What is it?
As you stated the language doesn't allow for static fields on interfaces. The choice is intentional. Another thing that doesn't exist is inheriting static fields.
There are several ways to structure your code to avoid such usage that in my point of view it doesn't give you many advantages. A factory pattern or DI approach (I suggest the minject library) seems the most obvious.
Given the comment below go for a typedef instead of an interface:
typedef GetInstance = Void -> Void;
You can pass that typedef around the same as an interface with the advantage that you can use both static and instance methods to satisfy that signature.
Check out the Singleton library. Any class that implements Singleton will automatically declare a static "instance" variable and corresponding getter function.
Note: as of this writing, the Haxelib version (1.0.0) is out of date. Download the Git version instead.
In an abstract class, I wish to define static methods, but I'm having problems.
In this simple example
abstract class Main {
static String get name;
bool use( Element el );
}
class Sub extends Main {
static String get name => 'testme';
bool use( Element el ) => (el is Element);
}
I receive the error:
function body expected for method 'get:name' static String get name;
Is there a typo in the declaration, or are static methods incompatible with abstract classes?
Dart doesn't inherit static methods to derived classes. So it makes no sense to create abstract static methods (without implementation).
If you want a static method in class Main you have to fully define it there and always call it like Main.name
== EDIT ==
I'm sure I read or heard some arguments from Gilad Bracha about it but can't find it now.
This behaviour is IMHO common mostly in statically typed languages (I don't know many dynamic languages). A static method is like a top level function where the class name just acts as a namespace. A static method has nothing to do with an instantiated object so inheritance is not applicable. In languages where static methods are 'inherited' this is just syntactic sugar. Dart likes to be more explicit here and to avoid confusion between instance methods and static methods (which actually are not methods but just functions because they don't act on an instance). This is not my primary domain, but hopefully may make some sense anyways ;-)
Looks like you are trying to 'override' a static method. I'm not sure what you are trying to achieve there. I'm not aware of any OO languages that support that (and not sure how they could).
A similar question in Java might help clarify Polymorphism and Static Methods
Note also that it is considered bad practice to refer to statics from an instance of the class in Java (and other OO languages). Interestingly I noticed Dart does not let you do this so is in effect removing this bad practice entirely.
So you couldn't even fool yourself into thinking it would behave polymorphically in Dart because you can't call the static from the instance.