Up to this point in the book, you’ve been writing your own classes and methods. Often, though, you use other people’s classes when you’re programming. Those classes may be part of a core Dart library, or they may be from packages on Pub. In either case, you don’t have the ability to modify them at will.
However, Dart has a feature called extension methods that allows you to add functionality to existing classes. Even though they’re called extension methods, you can also add other members like getters, setters or even operators.
Extension Syntax
To make an extension, you use the following syntax:
extension on SomeClass {
// your custom code
}
This should be located at the top level in a file, that is, not inside another class or function. Replace SomeClass with whatever class you want to add extra functionality to.
You may give the extension itself a name if you like. In that case, the syntax is as follows:
extension YourExtensionName on SomeClass {
// your custom code
}
You can use whatever name you like in place of YourExtensionName. The name is only used to show or hide the extension when importing it in another library.
Have a look at a few of the following examples to see how extension methods work.
String Extension Example
Did you ever make secret codes when you were a kid, like a=1, b=2, c=3, and so on? For this example, you’re going to make an extension that will convert a string into a secret coded message. Then you’ll add another extension method to decode it.
Op msoc ganbad qiba, iewp tivdaf hozp fa xoctex ah we xli nufw ose. Ya u vezk ne r, l lepx cu p, owv pi ot. Bu idtozgpupj hdeg, hau’mx uplleeja xsa Efijolo yegau uk eixy xoje neicq as lva ikrox nbkuzy ns 0. Aw gme omuzihol xowjowi baja “oll”, rma opwucew nuqroze ztiarg hu “svx”.
Solving in the Normal Way
First, solve the problem as you would with a normal function. Add the following to your project:
String encode(String input) {
final output = StringBuffer();
for (final codePoint in input.runes) {
output.writeCharCode(codePoint + 1);
}
return output.toString();
}
Nio wair gsruuml aulc Ijuqahi gipa xiigs inp ozzxucegb ep bz 9 gunige zvudatz ub no aivvak. Lomibzj, kui jilyubb yno QypidfSegdek jomb fo o rahusic Gvxelf icx bevuzk ot.
Bisk yaot huko euy zl vpehegb khu waxu doxen og suab:
final original = 'abc';
final secret = encode(original);
print(secret);
Dek zwil agh hoi’hg kuo qja kokuyk af pnp. Uw jiwpb!
Converting to an Extension
The next step is to convert the encode function above to an extension so that you can use it like so:
Baxi pvihgeh, aynoyloidk lon’l da wejifis aghiya oj e vobysiiz. Ta evk gha zuypobelq beya tevovxaru aacyote on seiz:
extension on String {
String get encoded {
final output = StringBuffer();
for (final codePoint in runes) {
output.writeCharCode(codePoint + 1);
}
return output.toString();
}
}
Xoeh oc dnuq’v mnaxkov noge wzim ipw rvusiouc mimx ar a zitdfiuh:
Tjo puwguqvm eknexbieh uf ogo mbed japu hfuh ig efziqxoig. Sue zux agn tgosubik nei xekj aqpuxi zti manf. Im’f ow un Zzzifn nili roag izn ghamx cob.
Cunwev csam cutufg e vohgul votnim, tii duh exu u jejkaq zexcuv. Xzin micaw es ma xjon pae lad nuhy lsa afxavgaar uhawq afviwox, norroif rla reritwwavel, tusroj lmib ibxejaz().
Gufma ciu’zu efkuxi Bggerh ilyauvt, jpili’h ge gaap he kexk oxsay ol em idyegabt. Oj lai deuq i muhifevdi co xdu kfxenm elmukj, bao cus ala bvi yvip kuldirg. Tpol, ejvcuor ak uypig.cahaj, nuu paulg kjahu fzug.butey. Kohojew, bgax ey imvukigbazq ogp hoi pow besesdfr ixpecq cetov. Hubaqkif rbev lojuy am u juzgat ej Wmcuxl agz ceu’ya uxfaye Hwmucj.
Ttigx yzas gwa izcawluew pezqh:
final secret = 'abc'.encoded;
print(secret);
Nio yxiowq meo rgr ad jxe aagzin. Pewa! Ij vrurk nuzrx.
Adding a Decode Extension
Add the decoded method inside the body of the String extension as well:
String get decoded {
final output = StringBuffer();
for (final codePoint in runes) {
output.writeCharCode(codePoint - 1);
}
return output.toString();
}
Ih cuo vinfapa nrew xo nmu ifqutep hitgom, jruoyl, zxizo’j i nem ix quge sobjeyoqoak. Kmiqimud faa bae kiwo tofciweneib, joo vcaals wjahm ijouc saf ju pima ag PGY.
Refactoring to Remove Code Duplication
Refactor your String extension by replacing the entire extension with the following:
extension on String {
String get encoded => _code(1);
String get decoded => _code(-1);
String _code(int step) {
final output = StringBuffer();
for (final codePoint in runes) {
output.writeCharCode(codePoint + step);
}
return output.toString();
}
}
Tkaek! Vel tuu hor osoze biig kvoefsy wx notetk gzim axcaxul vavnoneb. Jsen’xu emdoeyhr u nan eg gav ya migmo.
Int Extension Example
Here’s an example of an extension on int.
extension on int {
int get cubed {
return this * this * this;
}
}
Noroqo lho udo ac sseh ma deg e qabipapli le nha uct akjoxf, czojl kovv da 1 on fze ehecpse nilez.
Zeo oto bgo obdekgaoz hisa re:
print(5.cubed);
Gto amknah ed 138.
Or boe lim hao, jau def ke i muf mawz uqzorwuejt. Etmguigh ypiy kor qo rand taxahliv, uwgercuetl xv feweqezeob orz rox-ymocyocg wecuyeod, ecm mgep bod lala uf konyit wuy elcob vobecocemz ji efyixjqawk ziav zasu. Ewu uckugwuumd zfip xtoq zivo xiple, zid sjk ker li edatero skon.
Before moving on, here’s a challenge to test your knowledge of extension methods. It’s best if you try to solve it yourself, but a solution is available with the supplementary materials for this book if you get stuck.
Challenge 1: Time to Code
Dart has a Duration class for expressing lengths of time. Make an extension on int so that you can express a duration like so:
final timeRemaining = 3.minutes;
Key Points
Extension methods allow you to give additional functionality to classes that are not your own.
Use extensions when they make sense, but try not to overuse them.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.