Better way to do class type alias? - flutter

From time to time, I would like to call a class differently depending on the context or to reduce duplication.
Let's assume, I have the following classes defined:
// in file a.dart
class A {
final String someprop;
A(this.someprop)
}
// in file b.dart
abstract class BInterface {
String get someprop;
}
class B = A with EmptyMixin implements BInterface;
For this syntax to check out, I have to define EmptyMixin so that the syntax is OK.
Do you know of a better/prettier way to do this "aliasing" in Dart?

I'm afraid the way you're doing it is the prettiest way to do this at the moment. There is a very old, but still open and active issue: https://github.com/dart-lang/sdk/issues/2626 that proposes the typedef B = A; syntax for aliasing types.

Related

How to declare final class in Dart to prevent extending from it?

In Java\Kotlin we have a String class that is final and immutable.
I tried to mark the class with final keyword but looks like it's not allowable.
So, I'm a little bit confusing, how to declare final class in Dart ?
Note: the case is - I want to instantiate this class outside, but forbid to extending it. So using the private constructor - it's not my case.
You can achieve this final effect from java by having a private constructor for your class, it will prevent the class from being extended, BUT it will also prevent the class from being instantiated (only in the same file both will be possible):
class MyString {
MyString._(); // use _ for private constructor.
static void print(String s) {
print(s);
}
}
Call with
String message = "Hello World";
MyString.print(message);
Dart considers that we are all adults, preventing class extension is hence part of the design and responsability of the developers to have clear class names, and not part of the language:
AVOID extending a class that isn’t intended to be subclassed.
If a constructor is changed from a generative constructor to a factory constructor, any subclass constructor calling that constructor will break. Also, if a class changes which of its own methods it invokes on this, that may break subclasses that override those methods and expect them to be called at certain points.
Difference of meaning for final with Java
Dart has a very simple definition of what is final: a variable in dart can only be set once, id est: is immutable.
Final and const
If you never intend to change a variable, use final or const, either instead of var or in addition to a type.
A final variable can be set only once; a const variable is a compile-time constant. (Const variables are implicitly final.) A final top-level or class variable is initialized the first time it’s used.
Additionally to the approach of making the constructor private and instantiating your object via a static factory, you could use the package meta and
annotate your final class as sealed:
#sealed
class Z{}
This will signal users of your package that this class should not be extended or implemented. For example in vscode trying to extend the class Z:
class Z1 extends Z{}
results in the following warning:
The class 'Z' shouldn't be extended, mixed in,
or implemented because it is sealed.
Try composing instead of inheriting, or refer
to its documentation for more information.dart(subtype_of_sealed_class)
The issue will also be picked up by the dart analyzer:
$ dart analyze
Analyzing test... 0.8s
info • lib/src/test_base.dart:3:1 •
The class 'Z' shouldn't be extended, mixed in, or implemented because it
is sealed. Try composing instead of inheriting, or refer to its
documentation for more information. • subtype_of_sealed_class
You can use the factory unnamed constructor along with private named constructor, like this:
class NonExtendable {
NonExtendable._singleGenerativeConstructor();
// NonExtendable();
factory NonExtendable() {
return NonExtendable._singleGenerativeConstructor();
}
#override
String toString(){
return '$runtimeType is like final';
}
}
In a client code, in the same library, or another library, an instance can be created, an example:
// Create an instance of NonExtendable
print ('${NonExtendable()}');
Trying to extend it, something like
class ExtendsNonExtendableInSameLibrary extends NonExtendable {
ExtendsNonExtendableInSameLibrary._singleGenerativeConstructor() : super._singleGenerativeConstructor();
factory ExtendsNonExtendableInSameLibrary() {
return ExtendsNonExtendableInSameLibrary._singleGenerativeConstructor();
}
}
will work in the same library (same 'source file') but not in another library, making the class NonExtendable same as 'final' in Java from the perspective of any client code.

Python C API - How to inherit from your own python class?

The newtypes tutorial shows you how to inherit from a base python class. Can you inherit from your own python class? Something like this?
PyObject *mod = PyImport_AddModule("foomod");
PyObject *o = PyObject_GetAttrString(mod, "BaseClass");
PyTypeObject *t = o->ob_type;
FooType.tp_base = t;
if (PyType_Ready(&FooType ) < 0) return NULL;
though you need to define your struct with the base class as the first member per the documentation so it sounds like this is not possible? ie how would I setup the Foo struct?
typedef struct {
PyListObject list;
int state;
} SubListObject;
What I'm really trying to do is subclass _UnixSelectorEventLoop and it seems like my only solution is to define a python class that derives from my C class and from _UnixSelectorEventLoop with my C class listed first so that it can override methods in the other base class.
I think you're basically right on your assessment:
it seems like my only solution is to define a python class that derives from my C class and from _UnixSelectorEventLoop with my C class listed first so that it can override methods in the other base class.
You can't define a class that inherits from a Python class because it'd need to start with a C struct of basically arbitrary size.
There's a couple of other options that you might like to consider:
You could create a class the manual way by calling PyType_Type. See this useful answer on a question about multiple inheritance which is another sort of inheritance that the C API struggles with. This probably limits you too much, since you can't have C attributes, but you can have C functions.
You could do "inheritance by composition" - i.e. have you _UnixSelectorEventLoop as part of the object, then forward __getattr__ and __setattr__ to it in the event of unknown attributes. It's probably easier to see what I mean with Python code (which is simply but tediously transformed into C API code)
class YourClass:
def __init__(self,...):
self.state = 0
self._usel = _UnixSelectorEventLoop()
def __getattr__(self, name):
return getattr(self._usel, 'name')
def __setattr__(self, name, value):
if name in self.__dict__:
object.__setattr__(self, name, value)
else:
setattr(self._usel, name, value)
# maybe __hasattr__ and __delattr__ too?
I'm hoping to avoid having to write this C API code myself, but the slots are tp_getattro and tp_setattro. Note that __getattr__ will need to be more comprehensive in the C version, since it acts closer to the __getattribute__ in Python. The flipside is that isinstance and issubclass will fail, which may or may not be an issue for you.

Creating namespaces with classes in Swift

I am a newb to Swift, I am looking to create some nested namespaces, like so:
import Foundation
public class Foo {
class Moo {
class Bar{}
}
}
and then I can do:
var f = Foo.Moo.Bar()
do we not need to use the static keyword here? I don't understand why I don't need to do it like so:
import Foundation
public class Foo {
static class Moo {
static class Bar{}
}
}
var f = Foo.Moo.Bar()
can anyone explain why?
Foo.Moo.Bar is just the name of the class. You're not accessing a particular instance of Foo or Moo when you do this:
var f = Foo.Moo.Bar()
You're just creating an instance of the Foo.Moo.Bar class.
can anyone explain why?
Can you explain why not? What would a static class even mean? How can a class be static? Maybe you come from a language where that keyword means something special in this context?
In any case, in Swift it wouldn't mean anything. The word static has just one very simple meaning in Swift: A type member, i.e. a property (var or let) or method (func) is either an instance member or a type member; to distinguish the latter case, we say static (or class). This is neither of those. It is, as you rightly say, merely a namespaced type.

AngelScript - Avoid implicit default constructor from running

I'm currently testing some simple AngelScript stuff, and noticed something I find a bit strange when it comes to how objects are initialized from classes.
Let's say I define a class like this:
class MyClass {
int i;
MyClass(int i) {
this.i = i;
}
}
I can create an object of this class by doing this:
MyClass obj = MyClass(5);
However it seems I can also create an object by doing this:
MyClass obj;
The problem here is that obj.i becomes a default value as it is undefined.
Additionally, adding a default constructor to my class and a print function call in each one reveals that when I do MyClass obj = MyClass(5); BOTH constructors are called, not just the one with the matching parameter. This seems risky to me, as it could initialize a lot of properties unnecessarily for this "ghost" instance.
I can avoid this double-initialization by using a handle, but this seems more like a work-around rather than a solution:
MyClass# obj = MyClass(5);
So my question sums up to:
Can I require a specific constructor to be called?
Can I prevent a default constructor from running?
What's the proper way to deal with required parameters when creating objects?
Mind that this is purely in the AngelScript script language, completely separate from the C++ code of the host application. The host is from 2010 and is not open-source, and my knowledge of their implementation is very limited, so if the issue lies there, I can't change it.
In order to declare class and send the value you choose to constructor try:
MyClass obj(5);
To prevent using default constructor create it and use:
.
MyClass()
{
abort("Trying to create uninitialized object of type that require init parameters");
}
or
{
exit(1);
}
or
{
assert(1>2,"Trying to create uninitialized object of type that require init parameters");
}
or
{
engine.Exit();
}
in case that any of those is working in you environment.
declaring the constructor as private seems not to work in AS, unlike other languages.

enum-like data structuring or alternatives

I have a design issue which has proven to bee too much for my current design skills.
I hope my request is not too trivial or too stupid for the incredibly skilled people I saw in these forums over time.
Basically, this is what I need:
to be able to reference a specific class instantiation by means of another class static or constant declaration (hope it makes as much sense to you as it does to me, hah).
The 'enum' behavior would be particularly useful for its 'ease of access' and for its standard methods.
//simple class with a constructor
public class myclass {
int myint = 0;
string mystring = "";
public myclass(int localint, string localstring) {
myint = localint;
mystring = localstring;
}
}
//the core of the issue.
public enum myenum : myclass {
enum1 = new myclass(9,"abr"),
enum2 = new myclass(99,"acad"),
enum3 = new myclass(999,"abra")
}
So that elsewhere, when I need 'abra', instead of manually instantiating it, and having countless duplicates all over the code, I just
myenum mylocalenum;
mylocalenum = enum3; //no mistake, the underlying class variables are predefined
The purpose is to have a selectable, pre-set 'myenum' which basically encapsulates another data structure which I predefine in the declaration phase.
This is because I have several data pre-sets by design, and I need to interact with them as with an enum (get their number, their descriptions, and basically associate them with predefined values).
If you have a solution, or even a resembling alternative, please let me know.