Given the ‘gold rush’ of tech innovations targeting the mobile, developing apps have never been easier, thanks to cross-platform solutions like Flutter, React Native, NativeScript, PhoneGap and so on.
Flutter, in particular, has managed to successfully grab the attention of the development community by allowing an expressive style that makes it a joy building UIs for mobile apps. It incorporates certain concepts familiar to modern development experiences like reactive programming and widget composition, using the Dart platform as its main base of operations.
Prefer a video?
So, what's Dart?
Dart is an object-oriented programming language by Google, which aims to help the developer build modern web applications. It covers client, server and now mobile with Flutter. It comes with a range of tools including a virtual machine, core libraries and package management repository, lending enough ammunition to get started with on your next project.
Although Flutter is gaining traction, it can easily obscure the beauty of the Dart platform and what it offers, independently of Flutter.
In this article we will look at how we can write a Dart program, exploring some of its language features. This will hopefully gear you up with an overview to help you see Dart shining through as you develop your next app.
First Steps
Here is an example of a Dart program:
This demonstrates the blueprint for an Order with properties and methods. The main()
top-level function is where you would bootstrap your Dart application.
Here, I’m hoping that you’ll begin to see how the syntax looks pretty familiar with other OO languages and you’ll feel right at home if you’ve programmed in Java, C# or even JavaScript(ES2015 and above).
That being said, Dart comes with some language features that will surely make you more productive as a developer. See this tweak to our earlier class:
Not much done here, however we now have a shorthand constructor that saves the repetition of reassigning the parameters passed into the class properties.
We’re also using adjacent strings by removing the plus(+) symbols from our getIntro
method. Oh, and prefixing class properties with underscore (_) makes them private. It’s conventional and saves the need for typing the private keyword.
Ok, so let’s see how far we could go with this. Our constructor parameters are defined in a positional manner. This means that they are required. Dart allows us to define parameters that are optional, with two flavours: optional positional and optional named. These essentially allow us to have better flexibility in the way we define and use them:
Order(this._id, this._reference, [date]); // optional positional
Order(this._id, this._reference, {date}); // optional named
And their usage:
new Order(1, 'ref1', new DateTime.now()); // optional positional
new Order(2, 'ref2', date: new DateTime.now()); // optional named
And surely we can map this onto our internal property, although for optional named parameters the property needs to be public:
Order(this._id, this._reference, [this.date]); // optional positional
Order(this._id, this._reference, {this.date}); // optional named
I hope this seems predictable so far. Let’s now enforce some type information on our properties:
int _id;
String _reference;
DateTime _date;
Another common feature that OO languages have is the ability to declare a constructor multiple times, differentiated by the amount of parameters you pass into it. Dart instead gives you named constructors, which essentially allows you to add a namespace to your constructor, saving you from worrying about the parameter count:
Order(this._id, this._reference, [this.date]); // normal
Order.withDiscount(this._id, this._reference, this.code); // named
And we’ll instantiate that like so: new Order.withDiscount(...)
. Let’s see our refactoring so far:
One last feature I would like to cover are method cascades. These allow you to use the chaining pattern for your getters and setters, made popular by JavaScript libraries namely jQuery. To demonstrate this, we'll another public property named bookings
:
int _id;
String _reference;
DateTime _date;
String code;
List<String> bookings;
and when we instantiate our object we’ll do:
Order order1 = new Order.withDiscount(1, 'ref1', 'WEEKENDFTW1')
..code = 'WEEKENDFTW1'
..bookings = ['booking1', 'booking2', 'booking3'];
The double period(..) shows the cascades in action which always returns the instance each time. The chaining works with setters and also when you invoke methods.
Here's a complete solution:
Conclusion
Thanks for reading through to the end. Learning these Dart concepts will take you far once you start building your Flutter applications, so it doesn’t come to you as a surprise.
To start off, why not try modifying the printed output to include the other order information? The complete example is readily accessible through the online Dart editor.
Further reading
Sharing is caring 🤗
If you enjoyed reading this article, please share this through the various social channels. Also, check out and subscribe to my YouTube channel (hit the bell icon too) for videos on Dart.
Subscribe to my email newsletter to download my Free 35-page Get started with Dart eBook and to be notified when new content is released.
Like, share and follow me 😍 for more content on Dart.
Top comments (8)
Great overview, thanks 👍 I like the way Dart implements OOP features
Thank Fyodor! Would love to see what you make with this knowledge.
Ok. This looks interesting. Let me dig in and see
Dart looks like fun for sure! i love what i have seen so far. So excited to keep digging in! Thanks for the great tut
Thanks so much Chiko. Subscribe to the Youtube channel for latest videos on Dart.
Dartpad is awesome!
First time trying Dart, love your post!
Some comments may only be visible to logged-in visitors. Sign in to view all comments.