I have a class that extends another. The parent class is not intended to be used directly by the API rather it implements basic methods that are helpers for child classes.
When I use the child class in a program I can see all method from said class but also the one from the parent class that are not intended to be called directly, they exist to be called by the methods of the child class.
I tried to make parents method private. This would work I believe as long as parent and child are declared in the same library. But I have an issue with the "library" notion. I understand part/part of are somewhat depreciated, and I want the parent class to be in a specific file. I can't figure a way to do it with import/export.
Is there a way to either hide a public method from the parent class from all child classes usage or to make a private method from the parent class callable from all child classes ?
Best regards ;
Exemple:
myLib.dart
export mainClass.dart;
mainClass.dar
import baseClass.dart;
class MainClass extends BaseClass {
publicFunc() => ... //Can't call _hiddenFunc, can call wantToHideFunc()
}
In a second file (for code reusability purposes)
class MainClass extends BaseClass {
_hiddenFunc() => ...
wantToHideFunc() => ...
}
Using myLib public API
import myLib.dart
main() {
class = Class();
class.publicFunc(); //Intended
class.wantToHideFunc() //Wants to avoid...
}
Dart does not have protected access like Java or C#.
You can't hide a public member, you can't access a private member from a different library, and there is no third option.
It sounds like you want members of the superclass which can be invoked only from subclasses, not from outside of the object. That's what's called protected in, e.g., Java, and Dart does not have anything similar to that.
The only level of privacy in Dart is library-private, which is chosen by starting the name with a _.
The reason that Dart has this design is that it was originally a very dynamic language. You can preform "dynamic invocations" on a value with static type dynamic, say dynVal.foo(42) and it will call the method of that name.
To make a name unreachable, it needed to be safe from dynamic invocation as well. Because of that, Dart privacy does not care where the code doing the invocation is, it only cares whether you know the name - and library private names are considered different names depending on which library they're from.
Using part is not discouraged for situations where it actually serves a purpose. If you can put the part into a library of its own, that's better because it allows it to have its own privacy and imports, but if you need the classes to share privacy, using part files to split up a large file is perfectly reasonable. It's a tool, there is nothing wrong with using it when it's the right tool for the job. A library is often a better tool for modularity, but not always.
Now, there is a hack you can use:
// Declare the base and provide extensions for "protected" members:
abstract class Base {
int get _someHiddenStuff => 42;
int get somePublicStuff => 37;
}
extension ProtectedBase on Base {
int get someHiddenStuff => _someHiddenStuff;
}
Then import that in another library and do:
import "base.dart";
export "base.dart" hide ProtectedBase;
class SubClass extends Base {
int doSomething => someHiddenStuff + somePublicStuff;
}
Then anyone importing "subclass.dart" will also get a version of Base, but they won't get the ProtectedBase extensions. Hiding the extensions from your package's public API will allow yourself to use it, but prevent your package's users from seeing the helper extensions.
(This is likely highly over-engineered, but it's an option. It's the evolution of the hack of having static/top-level helper functions that you don't export.)
Related
Set the case there are multiple libraries of a package which need access to a commonly used class which is in its own library. This class gets exported and contains private fields which should only be accessible internally by libraries of the package. Because the part of directive is discouraged I am avoiding it. So this is the challenge: How can I access private fields of a public class from another library of the same package without using part of?
This is what a came up with:
class PublicClass {
Object _shouldNotBePublic;
}
class InternalClass extends PublicClass {
Object get publicInternally => _shouldNotBePublic;
}
And it partially solves the problem.
But now there is an exported function
void someFunction(PublicClass param) {
param._shouldNotBePublic;
}
which takes an argument of PublicClass and it needs to access the private _shouldNotBePublic field. That is exactly what C++ friend does. Are there any good solutions for Dart that don't involve part of?
Edit: The workaround I use for the time being is a simple not exported function in the same library like PublicClass:
Object getShouldNotBePublic(PublicClass obj) {
return obj._shouldNotBePublic
}
I am trying out the new Dart FFI in making wrappers for libsodium. Libsodium needs to be initialized with calling init(). But I don't think the user should be burdened to remember this and I also wouldn't like to check some global state variable.
I know that Go has package init() functions which run when a package gets included. Is there something similar in Dart?
Of course I could just wrap everything up into a class and run init() in the constructor but there isn't much sense in instatiating a class which basically only exposes static methods. Besides, I would like to preserve the procedural style of libsodium.
Of course I could just wrap everything up into a class and run init() in the constructor but there isn't much sense in instatiating a class which basically only exposes static methods. Besides, I would like to preserve the procedural style of libsodium.
You could have a singleton instance and expose library functions as methods on the instance, and you could provide a public getter function that automatically does initialization.
For example, something like:
Libsodium? _instance;
Libsodium get libsodium => _instance ??= Libsodium._();
class Libsodium {
Libsodium._() {
// Do initialization.
}
void foo() {
// ...
}
void bar() {
// ...
}
}
and then callers would need to use it via:
import 'libsodium.dart';
libsodium.foo();
This would hide the class instantiation and wouldn't look any different to callers than if you were to use only top-level functions with a namespace (import 'libsodium.dart' as libsodium).
Dart does not have any way to implicitly run code. No code runs before main, and all code running after main does so because it was invoked directly or indirectly from the main method. So, no.
If you need something initialized, there is a number of options.
You can use a lazily initialized static variable:
var _initialState = _init();
int doSomething(arguments) {
_initialState;
do the something.
}
The reading of _initialState will ensure that init is invoked the first time
it's needed, and not after that. You can even store things in the state for
later use.
The singleton implementation object suggested by #jamesdlin. It basically does the
same thing, then puts the methods on the object instead of being static.
Another variant is to do exactly that, but with a private instance, and have the
public top-level functions forward to the singleton object. Then you get the
procedural API and still ensures that the state object is initialized.
(This may be better for testing, allowing you to have multiple state objects alive
at the same time).
Require people to call init.
I wanted to write a simple behavior in Dart to be used by a custom element.
#behavior
abstract class AlignmentBehavior implements PolymerBase {
#Property()
bool alignTop = false;
// more properties ...
ready() {
updateAlignment();
}
#reflectable
updateAlignment([_,__]) {
// reference to the element the Behavior is attached to.
// 1) Is that the correct way?
var ele = Polymer.dom(root);
// We need to inherit from PolymerBase to access set(...)
// 2) Is that the correct way?
set('alignTop', aTop);
// .. to more stuff
}
}
My first two questions are already written in the code. How do I access the element the behavior is attached to? What's the proper way of doing this? I currently use Polymer.dom(root) but I don't know if that even works since I have some runtime errors which I am going to explain later in this post. What is the official way of accessing the underlying element? Is it using the JsObject? Is it calling a Behavior function from the parent PolymerElement and pass this, or should you not access it at all?
Another question is whether I have to inherit from PolymerBase or not. The Behavior example at the Github wiki doesn't do so, but in order to access methods such as set to modify a #Property I have to inherit from it. What's the proper way of doing so?
My last two questions are about errors I get. One error asks me to implement getters and setters for my properties, such as adding a getter and setter for alignTop.
And last but not least, I cannot invoke updateAlignment() from my custom element. It says Class 'MainApp' has no instance method 'updateAlignment'.
1)
var ele = Polymer.dom(root);
If you want to access the DOM of the element, this fine.
Just root gives you the same AFAIK.
If you want to access the elements class instance, there is nothing to do. It's this but that is implicit in Dart anyway.
You can only access what is known in the mixin. To make "things" known to the mixin you can create an interface class.
abstract class MyComponentInterface {
void someFunction();
int someField;
String get someValue;
set someValue(String value);
...
}
Then implement the interface in the mixin and the element class and you have a shared contract.
abstract class AlignmentBehavior implements MyComponentInterface, PolymerBase {
The mixin can now access the members because the implementsMyComponentInterface` claims they will exist and
class MyComponent extends PolymerElement with AlignmentBehavior {
will force you to implement it to fulfill the contract of the mixin.
2) looks fine
3)
Another question is whether I have to inherit from PolymerBase or not.
Is basically the same as 1) Any Polymer element in Dart has to extend PolymerBase. To be able to access the members of PolymerBase from within the mixin it has to implement it as well. This doesn't result in any limitations because the classes that the mixin will be applied to, will fulfill that contract anyway.
If you don't need to access any members provided by PolymerBase there is no need to implement it.
Here's the situation: I have an abstract class with a constructor that takes a boolean (which controls some caching behavior):
abstract class BaseFoo { protected BaseFoo(boolean cache) {...} }
The implementations are all generated source code (many dozens of them). I want to create bindings for all of them automatically, i.e. without explicit hand-coding for each type being bound. I want the injection sites to be able to specify either caching or non-caching (true/false ctor param). For example I might have two injections like:
DependsOnSomeFoos(#Inject #NonCaching AFoo aFoo, #Inject #Caching BFoo bFoo) {...}
(Arguably that's a bad thing to do, since the decision to cache or not might better be in a module. But it seems useful given what I'm working with.)
The question then is: what's the best way to configure bindings to produce a set of generated types in a uniform way, that supports a binding annotation as well as constructor param on the concrete class?
Previously I just had a default constructor on the implementation classes, and simply put an #ImplementedBy on each of the generated interfaces. E.g.:
// This is all generated source...
#ImplementedBy(AFooImpl.class)
interface AFoo { ... }
class AFooImpl extends BaseFoo implements AFoo { AFooImpl() { super(true); } }
But, now I want to allow individual injection points to decide if true or false is passed to BaseFoo, instead of it always defaulting to true. I tried to set up an injection listener to (sneakily) change the true/false value post-construction, but I couldn't see how to "listen" for a range of types injected with a certain annotation.
The problem I keep coming back to is that bindings need to be for a specific type, but I don't want to enumerate all my types centrally.
I also considered:
Writing some kind of scanner to discover all the generated classes and add a pair of bindings for each of them, perhaps using Google Reflections.
Creating additional, trivial "non caching" types (e.g. AFoo.NoCache extends AFoo), which would allow me to go back to #ImplementedBy.
Hard wiring each specific type as either caching/non-caching when it's generated.
I'm not feeling great about any of those ideas. Is there a better way?
UPDATE: Thanks for the comment and answer. I think generating a small module alongside each type and writing out a list of the modules to pull in at runtime via getResources is the winner.
That said, after talking w/ a coworker, we might just dodge the question as I posed it and instead inject a strategy object with a method like boolean shouldCache(Class<? extends BaseFoo> c) into each generated class. The strategy can be implemented on top of the application config and would provide coarse and fine grained control. This gives up on the requirement to vary the behavior by injection site. On the plus side, we don't need the extra modules.
There are two additional approaches to look at (in addition to what you mentioned):
Inject Factory classes instead of your real class; that is, your hand-coded stuff would end up saying:
#Inject
DependsOnSomeFoos(AFoo.Factory aFooFactory, BFoo.Factory bFooFactory) {
AFoo aFoo = aFooFactory.caching();
BFoo bFoo = bFooFactory.nonCaching();
...
}
and your generated code would say:
// In AFoo.java
interface AFoo {
#ImplementedBy(AFooImpl.Factory.class)
interface Factory extends FooFactory<AFoo> {}
// ...
}
// In AFooImpl.java
class AFooImpl extends BaseFoo implements AFoo {
AFooImpl(boolean caching, StuffNeededByAFIConstructor otherStuff) {
super(caching);
// use otherStuff
}
// ...
class Factory implements AFoo.Factory {
#Inject Provider<StuffNeededByAFIConstructor> provider;
public AFoo caching() {
return new AFooImpl(true, provider.get());
}
// ...
}
}
Of course this depends on an interface FooFactory:
interface FooFactory<T> {
T caching();
T nonCaching();
}
Modify the process that does your code generation to generate also a Guice module that you then use in your application setup. I don't know how your code generation is currently structured, but if you have some way of knowing the full set of classes at code generation time you can either do this directly or append to some file that can then be loaded with ClassLoader.getResources as part of a Guice module that autodiscovers what classes to bind.
i've been poking around RIM's PlayBook SDK and noticed they extend Object on a lot of their classes.
are there benefits to extending Object on a custom class that would normally be unextended?
package qnx.notificationManager
{
public class Notification extends Object
{
...
If you do not specify that your class extends another class, the compiler automatically makes your class extend Object. So the answer is that you don't gain any benefit; they must have just been trying to be explicit, or maybe the code was generated through decompilation.