Understanding Dart private class [duplicate] - dart

This question already has an answer here:
Dart: should the instance variables be private or public in a private class?
(1 answer)
Closed 4 years ago.
In Flutter we commonly have something like this:
class MyStatefulWidget extends StatefulWidget {
#override
_MyState createState() => _MyState();
}
class _MyState extends State<MyStatefulWidget> {
void doSomething() => print('hi');
#override
Widget build(BuildContext context) {
return Container();
}
}
So _MyState is declared with a _, which makes it library private.
So how come the Flutter render engine can use _MySate if it's sopposed to be private?
It's funny because I can access doSomething() from other files, but if I make it _doSomething(), I can't access it anymore...So how come I can access a public method from a private class, but I can't access a private method from a private class?

While _MyState is private, StatefulWidget and State are not.
The framework doesn't manipulate _MyState, it manipulates these lower layer that he has access to, with a well-defined prototype.
This basically sums up into:
StatefulWidget widget;
State foo = widget.createState();
foo.initState();
final newWidget = foo.build(this);
...

Related

Why is recommended to use final variables in widget as public?

The standard that I see in repos is
class A extends StatelessWidget {
final String title;
...
What would be the reason to use
class A extends StatelessWidget {
final String _title;
...
On using public variable, you don't see error while assigning values to the named optional parameters like:
class AnyClass extends StatelessWidget {
final String title;
AnyClass({this.title}); // no error
}
But if you use private variable, like:
class AnyClass extends StatelessWidget {
final String _title;
AnyClass({this._title}); // Error: named optional parameters can't start with an underscore
}
Reason for the error:
Named/optional arguments with constructor shorthand leaks impl details, see more

Is it possible to create a dartdoc on a Flutter Application?

If I try to creat an Doc with dartdoc on an Flutter Application I get
[error] Invalid override. The type of 'AddLinkPage.createState' ('() → AddLinkPageState') isn't a subtype of 'StatefulWidget.createState' ('() → State')
and
[error] Classes can only extend other classes.
class AddLinkPage extends StatefulWidget {
AddLinkPage({Key key,}):super(key: key);
#override
AddLinkPageState createState() {
return AddLinkPageState();
}
}
class AddLinkPageState extends State<AddLinkPage>{
...
If I change my code to
class AddLinkPage extends StatefulWidget {
AddLinkPage({Key key,}):super(key: key);
#override
createState() {
return AddLinkPageState();
}
}
class AddLinkPageState extends State<AddLinkPage>{
...
I avoid the first error but the second still there and the generation of the dartdoc failed.
Is the dartdoc only for packes, plugin, module without application or do I something wrong?

is there a way to find the scope of an object?

I am developing a flutter plugin that instantiate objects in the dart code mapping other objects at the native side. I want to preserve memory by deleting objects at native code once their scope ends at the dart code.
If you are fine with the flutter framework managing your resources you could just wrap them within a State Object.
https://docs.flutter.io/flutter/widgets/State-class.html
The framework calls dispose() once the referring Stateful widget is permanently removed from the widget tree.
(1) Simple to implement - no control
class ResourceManager extends StatefulWidget {
#override
State<StatefulWidget> createState() => ResourceManagerState();
}
class ResourceManagerState extends State<ResourceManager>{
Resource referenceToResource;
#override
void initState() {
// create/open your unmanaged resource here
super.initState();
}
#override
void dispose() {
// close/destroy your resource here
super.dispose();
}
#override
Widget build(BuildContext context) {
return SomeWidgetThatUsesTheResource();
}
}
Things do get more complicated if you need to have more control over the resource. The garbage collector does not release the resource exactly when the Widget goes out of scope but only sometime later (or maybe only when the application is terminated)
Alternatively you could manage your resource using the didChangeDependencies and deactivate methods of the State object. I'd expect these to be called more reliably and closer in time to the actual scope change of the resource:
(2) still simple - slightly more control
class ResourceManager extends StatefulWidget {
#override
State<StatefulWidget> createState() => ResourceManagerState();
}
class ResourceManagerState extends State<ResourceManager>{
Resource referenceToResource;
#override
void didChangeDependencies() {
if(referenceToResource = null) {
// open/create resource here
}
super.didChangeDependencies();
}
#override
void deactivate() {
// close/destroy your resource here
super.deactivate();
}
#override
Widget build(BuildContext context) {
return SomeWidgetThatUsesTheResource();
}
}
(3) requires some work - even more control
If you need to reliably manage a limited number of resources you might have a look at the pool plugin for Flutter:
https://pub.dartlang.org/packages/pool

What does the Object<type> syntax mean in Dart?

In the following code example, from the flutter docs:
class RandomWords extends StatefulWidget {
#override
createState() => RandomWordsState();
}
class RandomWordsState extends State<RandomWords> {
#override
Widget build(BuildContext context) {
final wordPair = WordPair.random();
return Text(wordPair.asPascalCase);
}
}
What exactly does the State<RandomWords> syntax mean?
I understand that you can specify the type for the objects contained in a collection, like lists, using this syntax - List <String>
But I cannot understand the motive behind State<RandomWords>.
Moreover, how can you reference RandomWordsState in RandomWords declaration and also reference RandomWords in RandomWordsState declaration? Shouldn't that cause a circular reference error or something?
I come from dynamically typed languages like python, and this looks a little odd to me, can someone please point me to the right place?
<RandomWords> is a generic type parameter passed to the State class.
The State class looks like
abstract class State<T extends StatefulWidget> extends Diagnosticable {
and RandomWords will be passed to the T type parameter which has a constraint that T needs to be a subclass of StatefulWidget.
State also has a field and getter where the type parameter is used
T get widget => _widget;
T _widget;
This results in a property of the type of the widget
which provides proper autocompletion and type checks in its subclass RandomWordsState
Assume you have
class RandomWords extends StatefulWidget {
RandomWords({this.fixed});
final WordPair fixed;
#override
createState() => RandomWordsState();
}
class RandomWordsState extends State<RandomWords> {
#override
Widget build(BuildContext context) {
// vvvv here we can access `fixed` in a strongly typed manner
final wordPair = widget.fixed ?? WordPair.random();
return Text(wordPair.asPascalCase);
}
}
See also https://www.dartlang.org/guides/language/language-tour#generics

#override of Dart code

I noticed PetitParserDart has a lot of #override in the code, but I don't know how do they be checked?
I tried IDEA dart-plugin for #override, but it has no effect at all. How can we use #override with Dart?
From #override doc :
An annotation used to mark an instance member (method, field, getter or setter) as overriding an inherited class member. Tools can use this annotation to provide a warning if there is no overridden member.
So, it depends on the tool you use.
In the current Dart Editor(r24275), there's no warning for the following code but it should (it looks like a bug).
import 'package:meta/meta.dart';
class A {
m1() {}
}
class B extends A {
#override m1() {} // no warning because A has a m1()
#override m2() {} // tools should display a warning because A has no m2()
}
The #override annotation is an example of metadata. You can use Mirrors to check for these in code. Here is a simple example that checks if the m1() method in the child class has the #override annotation:
import 'package:meta/meta.dart';
import 'dart:mirrors';
class A {
m1() {}
}
class B extends A {
#override m1() {}
}
void main() {
ClassMirror classMirror = reflectClass(B);
MethodMirror methodMirror = classMirror.methods[const Symbol('m1')];
InstanceMirror instanceMirror = methodMirror.metadata.first;
print(instanceMirror.reflectee); // Instance of '_Override#0x2fa0dc31'
}
it's 2021 . the override it's optional
Use the #override annotation judiciously and only for methods where the superclass is not under the programmer's control, the superclass is in a different library or package, and it is not considered stable. In any case, the use of #override is optional. from dart api https://api.dart.dev/stable/2.10.5/dart-core/override-constant.html
example
Class A {
void say (){
print ('Say something 1') ;
}
}
Class B extends A {
#override
void adds() { // when i don't type the same name of super class function show an
// warning not an error say 'The method doesn't override an inherited
// method.' because it's not same name but when type the same name must be
// overriding
print ('Say something 2 ')
}
Update : the main use of #override is when try to reach abstract method inside abstract class in sub class that inherited to the abstract super class . must use #override to access the abstract method .

Resources