Classes
Use a dot .
to refer to an instance variable or method.
This is the same in Dart and in Kotlin
Use ?.
instead of .
to avoid an exception when the leftmost operand is null
.
This is the same in Dart and in Kotlin
methods inherited from Object
in Dart all types inherit from the supertype Object
the methods operator ==
, toString()
and the property hashCode
.
in Kotlin all types inherit from the supertype Any
the methods equals()
, toString()
and hashCode()
.
Creating a class instance
In Dart the new
keyword before call to a class constructor is optional. In Kotlin the new
keyword does not exist at all.
Constant Constructors
In Dart If your class produces objects that never change, you can make these objects compile-time constants. To do this, define a const constructor and make sure that all class fields are final. Constructing two identical const class instances results in a single, canonical instance:
In Kotlin there is no such concept as const constructors.
var a = const ImmutablePoint(1, 1);
var b = const ImmutablePoint(1, 1);
assert(identical(a, b)); // They are the same instance!
const
keyword before the call to the constructor. This define a const context: all const constructors used in the same line of code will be also activated, with no need to specifiy the const
keyword before each of them.
// Lots of unneeded const keywords here.
const pointAndLine = const {
'point': const [const ImmutablePoint(0, 0)],
'line': const [const ImmutablePoint(1, 10), const ImmutablePoint(-2, 11)],
};
// the following line is equivalent to the previous one
// and define the same const instance
const pointAndLine2 = const {
'point': [ ImmutablePoint(0, 0)],
'line': [ ImmutablePoint(1, 10), ImmutablePoint(-2, 11)],
};
assert(identical(pointAndLine, pointAndLine2));
const
keyword is not added before the call to a const constructor (or an outer constructor calling a nested constructor as explained above), the constructor will NOT create a compile-time constant:
var a = const ImmutablePoint(1, 1); // Creates a constant
var b = ImmutablePoint(1, 1); // Does NOT create a constant
assert(!identical(a, b)); // NOT the same instance!
Getting an object’s type
In Dart to get an object’s type at runtime, you can use the Object
property runtimeType
, which returns a Type
object.
In Kotlin instead you can use the syntax ::class
Better use is
than runtimeType
to test an object’s type.
In Dart, in production environments, using is
to test the object Type is more stable than using object.runtimeType == Type
.
Basic Class declaration
class Point {
var x:Double
var y:Double
constructor(x:Double,y:Double){
this.x = x
this.y = y
}
}
class Point {
double x=0; //initialization required for avoiding compilation error unless field is nullable
double y=0; //initialization required for avoiding compilation error unless field is nullable
Point(double x, double y) {
this.x = x;
this.y = y;
}
}
Constructors
Initializing formal parameters
Both in Dart and Kotlin there are better ways to write the code above. in Kotlin there is the concept of primary constructor, in Dart there is the concept of initializing formal parameters that allow for a much more concise syntax:
class Point(var x:Double, var y:Double) //primary constructor
class PointXY(var x: Double, var y: Double) {
var z: Double
init { //init blocks are executed in the order they are found in the class definition
z = x * y
}
}
//or even better
class PointXY(var x: Double, var y: Double) {
var z: Double = x*y
}
class Point {
double x,y;
// initializing formal parameters:
// use the first parameter provided to the constructor to initialize this.x
// use the second parameter provided to the constructor to initialize this.y
Point(this.x, this.y);
}
class PointXY {
double x,y;
double xy=0; //initialization required for avoiding compilation error unless field is nullable
// NOTE: this.x and this.y are set
// before the constructor body runs.
PointXY(this.x, this.y) {
xy=x*y;
}
}
Default constructors
In Dart If you don’t declare a constructor, a default constructor is provided for you. The default constructor has no arguments and invokes the no-argument constructor in the superclass.
In Kotlin, for the JVM platform a parameterless constructor will be also generated if all the primary constructor parameters have default values.
Initializer list
In Dart if you want to initialize some fields in a constructor (with values not provided as parameters) there is a special syntax called initializer list
This syntax is useful for example in named constructors.
class Point {
double x; //x not initialized here!
double y; //y not initialized here!
Point(): x=0, y=0; //initializer list
}
class Point {
double x; //x not initialized here!
double y; //y not initialized here!
//named constructor with parameter validation in initializer list
Point.withPositiveX(this.x,this.y): assert(x>0); //initializer list
}
class Point {
final double x;
final double y;
final double distanceFromOrigin;
Point(double x, double y)
: x = x,
y = y,
distanceFromOrigin = sqrt(x * x + y * y);
}
Named constructors
In Dart named constructor are constructors with a name appended (after a dot).
In Kotlin an identical syntax at the constructor usage site, can be obtained with factory methods in the class companion object.
class Point(var x:Double,var y:Double) {
companion object {
fun origin() = Point(0.0,0.0)
}
}
var p = Point.origin()
class Point {
final double x;
final double y;
Point(this.x, this.y);
// Named constructor
Point.origin()
: x = 0, y = 0; //this is called an initializer list
}
var p = Point.origin();
Redirecting constructors
a constructor whose only purpose is to redirect to another constructor in the same class.
class Point(var x:Double,var y:Double) {
// Delegates to the main constructor.
constructor(x:Double): this(x,0.0)
}
class Point {
double x, y;
// The main constructor for this class.
Point(this.x, this.y);
// Delegates to the main constructor.
Point.alongXAxis(double x) : this(x, 0);
}
Constant constructors
In Dart If your class produces objects that never change, you can make these objects compile-time constants. To do this, define a const constructor and make sure that all instance variables are final.
class ImmutablePoint {
//all fields are final: it is
//possible to have a constant constructor
final double x, y;
//contant constructor
const ImmutablePoint(this.x, this.y);
}
Factory constructors
In Dart use the factory keyword when implementing a constructor that doesn’t always create a new instance of its class. There are also other reasons to use a factory constructors. Factory constructors does not have access to this
.
In the following example, the Logger factory constructor returns objects from a cache, and the Logger.fromJson factory constructor initializes a final variable from a JSON object.
class Logger {
final String name;
bool mute = false;
// _cache is library-private, thanks to
// the _ in front of its name.
static final Map<String, Logger> _cache = <String, Logger>{};
//a factory constructor that create a new object only if not already present in _cache
factory Logger(String name) {
return _cache.putIfAbsent(name, () => Logger._internal(name));
}
//an internal named constructor
Logger._internal(this.name);
void log(String msg) {
if (!mute) print(msg);
}
}
Operators
For Dart see here, for Kotlin see here
class Vector( var x:Double, var y:Double) {
operator fun plus(other:Vector):Vector {
return Vector(x+other.x,y+other.y)
}
override fun toString():String ="x:$x, y:$y"
}
var a=Vector(2.0,0.0)
var b=Vector(0.0,3.0)
var c= a+b
println(c) //x:2.0, y:3.0
class Vector {
final double x, y;
Vector(this.x, this.y);
Vector operator+(Vector other) {
return Vector(x+other.x,y+other.y);
}
@override
String toString() => "x:$x, y:$y";
}
var a=Vector(2.0,0.0);
var b=Vector(0.0,3.0);
var c = a+b;
print(a+b); //x:2, y:3
Getters and Setters
For Dart see here for Kotlin see here
class Square(var side:Double) {
var area:Double
get() = side*side
set(value) { side = Math.sqrt(value) }
}
var sq=Square(10);
print(sq.area); //100
sq.area=81;
print(sq.side); //9
class Square {
double side;
Square(this.side);
double get area { return side*side; }
set area(double newArea) { side = sqrt(newArea); }
}
var sq=Square(10);
print(sq.area); //100
sq.area=81;
print(sq.side); //9
Static Variables and Methods
For Dart see here. For Kotlin see here
class Point(val x:Double, val y:Double) {
companion object {
val origin = Point(0.0,0.0)
fun distanceBetween(a:Point, b:Point):Double {
val dx = a.x - b.x
val dy = a.y - b.y
return sqrt(dx * dx + dy * dy)
}
}
}
var a = Point.origin
var b = Point(3.0, 4.0)
var distance = Point.distanceBetween(a, b)
println(distance); //5
class Point {
final x, y;
Point(this.x, this.y);
static final Point origin = Point(0.0,0.0);
static double distanceBetween(Point a, Point b) {
var dx = a.x - b.x;
var dy = a.y - b.y;
return sqrt(dx * dx + dy * dy);
}
}
var a = Point.origin;
var b = Point(3, 4);
var distance = Point.distanceBetween(a, b);
print(distance); //5