android game download

Hi, my name is Nate and welcome to this tutorial on the Kotlin programming language. If you’re not familiar, Kotlin is a staticallytype programming language developed by JetBrains. It’s been around since about 2011 and hassteadily increased in popularity ever since. Today it’s actually the primary developmentlanguage for Android and in this tutorial we’re going to move from basic topics likesetting up your first project up to more advanced things like modeling data and working withhigher order functions. The goal for this tutorial is to help you understand how thework with Kotlin so that you can then take that knowledge and apply it to building applicationsacross mobile, web and native code. So without further ado, let’s jump in and start buildingour first Kotlin project. The first thing we’re going to want to dois to install JetBrains IDE Intelijay so that we can work with our Kotlin code on our developmentmachine. The first thing to do is to open up your browser and search for it. Until Jayhere, you should see a download link and we can click on that to be taken directly tothe download page. Now I’ll be working on a Mac, but intelligent is available on windowsand Linux as well. You’ll also notice here that there are two different versions of intelligence.There’s the ultimate edition and the community edition. The ultimate edition has a lot morefeatures that we need and there’s also a paid product. The community edition is supportivefor JVM development and Android development, so it’s perfect for what we want to look atin this tutorial. When you’re ready, go ahead and click the download button and that shouldstart the download. Once the download is complete, we’ll get started on installing the IDE andwe’ll take a look at hello and Kotlin. Now that our downloads complete, we can go aheadand onto the installer and I’m Mac. We’ll drag the application intoour applications folder which will start the install process here for us. Once the fileshave been transferred to your machine, we can go ahead and start intelligent for thefirst time to start the install process. In this case, we want to do a fresh install,so click that. Do not import settings and hit okay. Go ahead and accept the privacy policy. Hitcontinue. Now here you can choose your theme. I’ll choose the dark theme. Go ahead withthe standard and tell the J key settings here and we’ll go ahead and click next throughto finish the setup process and then we’ll finally launch intelligent IDE community edition. The next thing that want to do is create ourfirst Kotlin project here in intelligence. So to do that we’ll click on create new project.Now over on the left side of this panel, we’ll see a number of different project templatesto choose from because we are going to be learning about Kotlin. We want to make surethat we have selected the Kotlin template. Now within this, there are a number of differentCollin project types that we can choose from. The default here at the top is a Kotlin modulefor a JVM target, so this would be sort of a standard, just Kotlin project that couldtarget a the JVM. I have nothing else added to it. Other examples would be, you know Caitlynmodule for a Java script target or I taught in the native targeted or an Android or iOSmobile target. So all of those are interesting but more advanced. For this, we want to juststick with the basics so we will make sure that we have selected Kotlin module for JVMtarget and go ahead and hit next. Then we want to make sure that we name our projectsomething meaningful. So in this case, let’s call it hello Caitlyn. We’ll make sure thatour project location is set and then we’ll go ahead and select finish. Now we have an empty Kotlin project. Let’sstart by adding our first common file so that we can write a simple hello world example.So do that. We’ll come over here to the left and here we have the project panel withinintelligent. You’ll see at the top we have our hello Collin module. If we expand thatwe can see that we have a source directory but it’s currently empty. That’s right. Clickon source, go to new and then Caitlyn file our class. And here we’re going to type mainfor the name of our file and then we will leave this as file so that we can create ourmain dot KT file. Now we can get started by writing our main function here in our maindotK T file. So to start we’ll type in fun Maine, no parameters and then we can typeprint Ellen parentheses. Hello Collin. And from there you’ll see nowthat we have this little green arrow intelligent recognizes that this is an executable mainfunction within this uh hello Caitlyn module. So we can actually go ahead and run this.We’ll select to run main KT and that’ll take a second to go ahead and build the project.And then we will get our output window here at the bottom and you can see that we havehello Collin. Now one extra quick fun fact here and tell Jay comes with a number of livetemplates built it. This means that you can type something and it will know how to completethat and auto-generate some code for us. So

Default android game downloadtype something and it will know how to completethat and auto-generate some code for us. So we can start typing Maine and then hit enterand it will automatically generate a main function for us. And then we are free to fillin with our, hello Caitlyn text. Awesome. You’ve just written your first programin Kotlin. Now let’s dive in and start actually learning the language to get started. Let’slook at how you can define variables in Kotlin. Now there’s two types of variables. In Kotlinwe can define mutable variables, which can have their values reassigned. Those are declaredusing the VAR keyword. Or we can define local read only variables, which can have theirvalue assigned only once these are defined using the vow keyword. So to define a variable,we can use the keyword of our choice. So in this case we use vow, then we’ll define thename and then we need to indicate that type. In this case I’ll say a type string and thenyou can use an equals and then you can assign the value to this variable. So in this caseI’ve defined a variable called name of type string. And then I have assigned the string literalNate to that variable. Now, like I mentioned, vow our assign once variables, meaning thisis read only once it has a value assigned to it. So if I tried to update the name ofthis, we’ll see that we get an error. That area says vow cannot be reassigned. So thisis our indicator that if we need to be able to update the value of our variable, we’renot going to be able to use a vow. Instead we can use a VAR. Now VAR variables can bereassigned as many times as you want. So as soon as I updated that keyword, now I canupdate the value of our name variable. And then if we want to use that variable, we canpass that in to the print function here. And if we then run our main function, well nowsee the output value of that variable at this time is blank because we had reassigned it. If we remove that reassignment, well now seethat we get this little underlying saying variables never modified and can actuallybe declared immutable instead using vow. So this is nice that the IDE gives us that helpfulhint. So in this case we’ll go back to a vow. And now if we rerun this once again, wellnow see that my name was printed out to the console and this example we’re using a localvariable, meaning that the variable that we have defined is available locally within thecurrent scope. So in this case it’s available only within the main function we have defined.Now in Kotlin you can actually declare variables outside of any type of enclosing function.Our class, all you have to do is declare a variable within a Kotlin file. So in thiscase we’ve moved our variable name outside of the main function into the main dot. Kate.He file variables defined like this are referred to as top level variables. And you see nowthat we’ve moved this outside of the main function, we can still run it and our variableis still completely valid. Top level variables can be worked with justlike a local variable. So we get a fine and an additional variable. This time we’ll sayVAR greeting of type string equals hello. We now have a publicly available top levelvariable called greeting. So now if we wanted to come down here and print out a greetingbefore the name, we could do that by calling print line and passing in greeting. We canalso modify that greeting because this is a mutable variable and if we then print outthis new value, we will see that the message has changed. So when we hit run here, we should now seehello Nate. And then hi mate, let’s take a closer look at how variable types are defined.So in defining our variables, in both cases we use either the voucher or VAR keyword andthen we have the variable name. Both of these are must haves. Next step we have the colonand then the type. So in this case we have the type of string and then we assign ourvalue. One interesting difference between Java and Kotlin is that types in Kotlin arenon null. By default this means that there is a distinct difference between string anda nullable string. Now what does this look like in practice? Well in this case becausetypes are non all by default name is a nano string. So if I tried to assign a no valueto this, we’ll actually get an error and it will hopefully say no, cannot be a value ofa non Knoll type string. So if you want to actually have no as a valid value for yourvariable, you need to add a question Mark after that string value. This indicates thatnow named as a knowable string. And I can assign no or I can go ahead and sign an actualvalue. So let’s look at how we could use this with the greeting variable. So if we make greeting a knowable variable,we can come down here and we’ll go ahead and print out the default greeting value. We’llprint out the name and then we’ll see that we can modify the value of greeting to null.And then we can go ahead and print out these

1 android game downloadwe can modify the value of greeting to null.And then we can go ahead and print out these values ones again and we can then see thatgreeting has been updated. And when we try to print that out, it actually recognizesthat it’s no and prints that out to the console for us. So let’s look at how we can actuallysimplify the declaration of our variables. I mentioned that vow or bar as well as thename are mandatory. However, Kotlin supports type inferences on variables and properties.What does this mean? Well, this means that Kotlin can recognize what type the value isthat we’re trying to assign to the variable and if it can figure that out, we can actuallyomit a type declaration of the variable. So in this case we could actually remove thecolon and string and the name variable will still be of type string. Now we can do thesame for our greeting variable so we can remove this. But if we come back down here and triedto assign knowl to greeting will get an error. No, it cannot be a value of non node typestring. So why is this? Well again, because types are non nano by default and Kotlin andwe are assigning a nano string literal to greeting the compiler. In first the greetingis meant to be a non null string. So if you want to have a knowable string you might tryand just assign no. However we get a warning saying implicit nothing type. This is becausegreeting now cannot really be inferred. It doesn’t know what is a null type of. So inthis case we will need to go ahead and specify a knowable. Now down here we can assign Knowlton greetingor we could assign an actual greeting. Now that we’ve taken a look at how to create variablesand how the type system works, let’s introduce some basic control flow and we’ll do thisby working with the nullable string variable of greeting. So let’s go ahead and removethese values. Now let’s say that we only want to print out the value of greeting if it’snot no. So we could do that in a couple different ways. The first one we’ll look at is usingan if statement, if statements in Kotlin work very much the same way as in Java. So we’lluse the if keyword followed by parentheses, we use greeting. In this case we want to sayif greeting is not no printed out, so we can say not equal to know and we’ll finish itoff with curly braces. And then if we move our print statement withinthat, if conditional when we run this, we should now have no greeting printed out. Andsure enough we see that just the name is printed and if we modified the value of greeting tobe non null and then rerun this, we’ll now see that we have our greeting. Now what ifwe wanted to add and else claws? So just like Java, we could add the else, we can add curlybraces again. And so here we could define a default greeting of hi. So now if we runthis once again, greeting will be normal and so we should see the default high value. Nowanother means of control flow within Kotlin is the when statement. The Wednesday mintis very similar to a switch statement in Java. So to create that we can come down and usethe when keyword and then print the CS. We didn’t want to pass end to this, the valuethat we want to check and switch on depending on its value. So in this case we’ll pass ingrieving followed by curly braces. Now within this block we can define each value that wewant to act on differently. So in this case we can say no. And then to define what actionto take, we use an arrow and then we’ll say print line, hi. And then we can define andelse case here. And this will act as the default if none of the values above are matched. Sothis case we will print out the value of greeting on its own. So now if we run this, we should see highprinted out because greeting is still not. And once again if we update greeting to besome other value and rerun, we’ll see that the branch of the, when statement is hit andwe are printing out the value of treating. So these are two of the basic ways in whichyou can manipulate control flow within Kotlin. Now we just saw how if and when can we useas statements to take different actions based on some checked value if and when can alsobe used as expressions to assign a value depending on that, those logical conditions. So let’stake a look at how we could use an expression to assign a value to a local variable. Solet’s go down here and type vow greeting to print. I can say equals. Now if the greetingvariable in our top level declaration is non no, then we want to go ahead and stick withthat. So we can say if greeting does not equal null,then we want to assign greeting to the new greeting to print variable. Otherwise we wantto say hi and then we’ll update our print line to use the local variable. Now when weprint this out, we should see the ELs branch of high being printed out. This is becausethe top level variable is currently no. If we modify this to pass in a greeting. Nowif greeting does not equal null or return true and we’ll see that hello is printed outinstead. So if we want to assign different

android game download true and we’ll see that hello is printed outinstead. So if we want to assign different

2 android game downloadtrue and we’ll see that hello is printed outinstead. So if we want to assign different values to a variable, depending on whetheror not something is normal or some other logical check, we could use an expression. However,we can also use a when expression if we want it. So we can say when, and again, we’ll passin treating here and again we’ll use our no value as the first check and if it’s no, we’llgo ahead and return high. Otherwise we’ll go ahead and return the original greetingvalue. So now with this, when expression is saying is assign the value of high to greetingto print. If greeting is know. And likewise if greeting is nominal, go ahead and assignthat value to the new greeting to print variable. So if we run this one more time, we shouldsee high because grieving is null. And if we assign that value to greeting andrerun, we’ll see that updated value of hello. So again, like the if expression a when expressioncan be used to assign a value to a variable depending on that input value that it’s checkingto start understanding functions in top line. Let’s look at this example. Within this example,we actually are using two different functions. We have our main function and then we’re alsousing the print LN function as well. So let’s take a look at how we can define our own newfunction. We’ll start by clicking here and we’ll define the new function that is goingto return this string that we want to print out to the console. So the first thing todo when defining any function is to use the fun keyword. This denotes that we are goingto define a new function. Then we want to specify the function name.So I’m going to call this function, get greeting, and then you want to follow that up with openand closed parentheses. And within this we can actually define any function parameters.Now for now we’re going to skip any function parameters and we want to define our returntype for this function. So similarly to variables, we can define a return type by using a colon.And then the type in this case string. And then we’ll do open and closed curly braces.Now like in Java we can define the return value by saying return. And then in this caseI’ll say hello Kotlin. So now we have the function called get greeting this green toreturn the string. Hello Caitlyn. If we want to then invoke that function, we can do soby calling get greeting with open and closed parentheses. This should look very similar to what you’refamiliar with and calling methods from Java. And now if we run our code, we’ll see to printstatements. We’ll see the first one, hello world. And the second one. Hello Collin. Soone thing you may have noticed is that in our gig greeting function, we’re the returntype of stream. However, in our main function there’s no return type specified. So why isthis? Well let’s illustrate this by an example. Let’s write a function called say hello. Soagain we’ll use the fun keyword and it will maim it. Say hello, no parameter values. Andthen we’re going to declare this as returning type unit unit. And Kotlin is essentiallythe absence of any useful type. It’s similar to saying this returns nothing useful. Andthe reason we’re going to use unit in this case is because we don’t want to return anything. We’re going to simply print out our get greetingfunctions, return value, so we can then call say hello. And you’ll notice up here thatunit is underlined and it’s giving us this message that says redundant unit return type.Basically what this is saying is that if you have a function that returns unit, that isto say if you have a function that doesn’t return anything useful, you can omit thattype value. So we can actually remove unit from our say hello function and this is perfectlyvalid. So that’s why in our main function, we also don’t have the return type specified.Aside from the rules around unit return types, return types or functions work very similarlyto how you would define them and treat them for variables or properties. So for example,if we wanted to return a Knoll string from our get greeting potion, we would modify thereturn type to be a nullable string and then we could return note in our return statement. Additionally, functions support type inferenceas well. So in our get greeting example here we are returning a single string literal,in which case we could actually simplify this to a single expression. We could remove thecurly braces and add an equals and then the string literal after that. So this is what’sknown as a single expression function because the entire function definition is now in asingle expression. And now this is where the title inference comes into play. Again, becausethe compiler understands this single expression function definition and it knows that it’salways going to return a string. We can actually remove the explicit return type. Now our getgreeting is extremely simple and is functionally equivalent to the previous definition. Soif we run our code, once again, we’ll see that we now have our three different printstatements. You might be noticing a theme

3 android game downloadthat we now have our three different printstatements. You might be noticing a theme here of Kotlin allowing us to reduce the amountof code we need to write to get the equivalent functionality. This is a theme that will cropup more and more as you start to learn the language. Now let’s take a look at how we can definefunction parameters. Now before we get started, let’s clean up our code a little bit. So we’llremove everything from our main function and we’re going to go ahead and remove the existingfunction examples we’ve been working with. So once again, we’re gonna define a functionnamed say hello and to start it will print out. Hello Collin. Now this is exactly likewe have seen before, but what if we wanted to change the thing that we were greeting?So instead of saying hello Collin, maybe we wanted to say hello world or hello mate, orhello John. So how might we do that? Well that’s where a function parameter comes intoplay. So to define a function parameter, we’ll go within the parentheses after the functionname, and we’ll define this using a notation of the parameter name colon, the parametertype. So in this case we’re going to say item two Crete as our parameter name, colon. Andthen we want this to be a string value that we’re passing it. Now with dinner function,we can say, Val, message equals hello. Plus I even went to greet. Okay. And then we could pass in the message. Nowif we come down to our main function, we want to, when folks say hello, so we can starttyping, say hello. And now we need to pass in a parameter value which it suggest to usin this little tool tip. So in this case we’ll say Caitlyn. And now if we run our main function, we now see hello Kotlin is printed out tothe console. If we wanted to pronounce something else, we could duplicate the invocation andmaybe this time we’ll pass it in world. And if we invoke our main function again, we’llnow see hello Caitlyn and hello world printed out to the console. Now if we go back up toour say hello function. Well notice that there’s this squiggly line here. This is unrelatedto function parameters, but this is a really interesting feature in Caitlyn. Caitlyn supportsstring templates which allow us to substitute in variable values or argument values intoa predefined string template. So in this case, instead of using concatenation, we can sayhello space. And then to define a template, add value, please a dollar sign and then wecan pass in that parameter name. So now if we hit run once again, we’ll see the sameoutput as before. So this is just one more way in which Kotlincan produce boilerplate for us by allowing us to define these convenience string templates.In fact, in this scenario we can take it one step further and remove the local variableall together. And then we can actually take this one step further and define this as asingle expression. Oh shit. Now we have a say hello function that will take in a parametervalue, which is the item degree. And then it will always print out hello item degree.So now let’s update this to take two parameters so that we can customize both the greetingand whatever it is that we want to agree. So to do that, we’re going to add a new parameterand we will name this one in greeting and have it be of type string. And now we willupdate our string template here to include that new parameter. Awesome. So now we’ve updated the function.Now we need to update the invocation of that function. So for this first line we can say,Hey, common and now for the next one we’ll say hello world and if we read this well nowsee our desired output. So by adding that second parameter value, we have now made oursay hello function much more flexible. Now we can add any number of parameters we wantto say hello, but like any programming language, if you have too many parameters in your function,it might be an indicator that your function is doing too much. Now what last thing I’dlike to point out about functions at this time is that you’ll notice that these functionsare not defined within any type of enclosing class. These are free functions or as they’rereferred to in Kotlin. These are top level functions like variables, functions can bedefined outside of any in closing class or independent of any associated class. Now thereare types of functions that are associated with a class and we’ll take a look at thoselater on in the tutorial. Like most programming languages, Kotlin hassupport for collection data types. These are things like arrays, lists and maps they canuse to group values together and then operate on them at a later time. So let’s start offby looking at how we can define inner Ray and Fallon. We’ll clear out these invocationsto say hello because we won’t need them right now, but we’ll leave the say hello functiondefinition because we’ll come back to it later. Your create a basic array. We’ll create anew local variable named interesting things and then we’ll use the equal sign and thenwe can use a convenience function called array of in parentheses. This will create an arrayof whatever the inferred type is and then we can start defining values within this function.So in this case, as soon as I add a string literal, it can infer that this is going tobe an array of strings. And then we can define some interesting things like Kotlin programmingor comic books. Now that we have this variable defined, let’ssee what types of operations we can perform on it. If we start typing interesting thingsand hit dot the IDE will start to auto-complete and show us some of the methods available.So you see we have a size property, we have a get method, and we also have this open andclosed of bracket syntax that we can use to access individual elements in the array. Let’stry printing out some of these values to demonstrate how we can use the array to start. Let’s printout the size. We can do that by saying print LN and then we’ll do interesting things thatsize. Now let’s print out the first element in the array. We can do that by going print,LN, interesting things. We can use the open and closed bracket and then pass in an index.This is how we can conveniently index in fact array. This is similar to doing a jet, so if we duplicatethat line, we could say get, and again, passing is zero element of that array. If we now runthis, we’ll see three Caitlyn, Caitlyn, but this is just as we would expect. Now, whatif we wanted to iterate over all of the elements of this array and then perhaps print out eachof those values? Well, there are a number of different ways we could do that. For nowwe’ll take a look at a basic for-loop so we could start typing for, and then we couldsay interesting thing in interesting things. Then open and closed curly braces. This isnow the convenient syntax of four loops within Kotlin. So this is going to iterate over eachvalue in the array and we can access those values in the interesting thing variable thatwe have defined within this four loop. So now we can type out interesting thing andif we rerun this code well now see that we have printed out each element in the array.So that type of for-loop is what is probably most similar to what you’re used to if you’recoming from Java. However, in Kotlin because we have top level functions and higher orderfunctions, really just first class of port for functions across the board, we can writecode that is a bit more functional. So let’s take a look at how we could do a more functionalapproach to collection iteration. So or remove our four loop and now we could say interestingthings doc for each. And what this is is invoking a for each function that is available in thestandard library. That function then takes in a another function and returns unit. Thatfunction that we pass it in essentially defines what to do on each iteration over this collection. So within our curly braces here, this is wherewe can define what we want to do with each element in contrasting things. Now this mightlook a little bit confusing at first, but don’t worry well explain this, but if we simplywant to print out each item in this array, we can now say print LN and pass in it. Itis the default name for each element in the array that is passed into this Lambda functionin which we are defining. So if we run this well, now see that we have our three elementsin the array printed out to the console. Now it is not always very readable. So anotherlittle quick tip here is if you want it to be named something else, you can rename thatto value that’s passed into the Lambda. In this case we could call it interesting thingand then we’ll use the arrow and now instead of if we can reference that value by callingit interesting thing and once again if we run this, we’ll see that our interesting thingsare printed out to the console. You might be looking at this wondering whywe are not using an open and closed parentheses when calling the for each function. In fact,it might seem rather odd that we are not passing in that argument two for each, but insteadof have just specify this open and closed parentheses independent of the rest of thefor each call. So this is actually what’s known as Lambda syntax within Kotlin. Nowwe’ll look at how to implement this later. But the idea behind Lambda syntax is thatif you have a function and it’s only parameter is another function, then you can omit theparentheses all together and you can pass that function in by specifying this open andclosed parentheses. So again, if we look at for each, we’ll see that it takes a singlefunction as a parameter so we can omit the parenthesis values and past that functioninto the for each function using the open and closed curly braces. And like I said, we’ll look at how we actuallydefine this type of higher order function a little bit later in the tutorial. So herewe looked at a basic for each function on this array collection. But by doing it thisway, we’ve lost the index data for whatever index the current interesting thing is inthe containing array. So to handle that there is another function we can call. So once againwe’ll say interesting things and this time we’ll say for each indexed. Now this timeit’s going to pass into us the current index as well as the current string. Now once again,we’ll update this to be named interesting thing and that one’s again, we could printout these values. So we can say print,L ,N and we can say interesting thing is at index. And now if we print this out, we’ll see thatwe have gotten the value from the array as well as its current index. So this could bereally useful if you need to iterate and still maintain that index data. Now everything thatwe’ve been looking at here for res is applicable for lists as well. So if we clear out someof this previous code, we now go to our declaration of this interesting things variable. Now we’reusing the convenience function array of to define this variable as an array of type string.Now there’s also a list of function as well. Now if we try to work with interesting things,we’ll see that we have a lot more methods to choose from because it’s now a list ratherthan an array. And so like an array, we can access individual elements by using a jetor also by using the bracket syntax like we’re familiar with with arrays as well. And also like with the array, we have functionsavailable to us to help with integration. So if we wanted to print out all of the interestingthings again, once again we can say interesting things doc for each ad. Once again we’ll sayinterim vesting thing. We use the arrow here within our Lambda expression and then we’llprint out the interesting thing and if we hit run while that we have our three interestingthings printed to the console. Now that we’ve looked at arrays and lists, let’s take a lookat one more collection type and Kotlin which is map. So let’s remove this duration overour interesting things variable here. Now let’s create a new variable. I’ll just namethis map equals and once again there is a map of function that we can use. Now the mapof function will essentially take in pairs. Pair is a simple wrapper class containingtwo values and that there is also the convenience function to create pairs. So if you want to create a basic key valuemap we could do so like this. We’ll use a key of one and then we’ll use two and thenthe value in this case will be a, and then we’ll define it. Another pair, we’ll use akey of two. Then we’ll use the two function and then a value of B. And then we’ll defineone more pair. And we’ll say three is our key to C. so what we’ve now done is defineda map with three pairs of values in it. The keys are one, two and three, and the associatedvalues are a, B, and C. now we can iterate over this by saying map for each and it’sgoing to return to us both the key and the value. Unfortunately the default to it, not very useful name. So this case we’ll remainthem again within our Lambda expression. So we’ll say key value and then we can printthese out and we’ll use a string template and we’ll just say key and then we’ll definean arrow just for some separation and then value. And now if we print this out, wellnow see that we’re giving each of our key and value pairs and then we could do withthose whatever that we need to. We’ve seen how you can define several different typesof collections such as arrays and lists and maps. And we’ve also seen how you can iterateover those collections and access individual elements from our collection. And there’san interesting thing to point out about the way Kotlin handles the collections similarto the way in which it differentiates between knowable and nano types. Caitlyn also differentiatesbetween mutable and immutable collection types. Now what does this mean? This means that bydefault a collection type in Kotlin is immutable so that you can’t add or subtract values fromthat collection once it’s initially created. So let’s look at an example of this. We havedefined our interesting things list using the list of function here. And if we wantedto try and add something to interesting things, there’s no function available to us to dothat. That’s because it’s immutable by default. If we wanted a immutable list, we could usethe mutable list of function. Now if we want to add something, we can say interesting things.Dot add and we could add a new string to our interesting things list. The same goes formap. If we wanted to add a new key value paired wire map, you could say map doc put, but there’sno put method available. But if we change to immutable map, now we could say map dotput and we can define a new key of four and a new value of D. so this is something tokeep in mind. If you have a collection that’s going to be static, once it’s defined, thenyou’re fine to use the regular list of array of map up, et cetera functions. And that isa good thing because immutability is often a desirable trait in your code. However, ifyou’re going to want to modify the values in that collection, then you’ll have to createa mutable collection so that you have access to things like put or add that let you modifythat collection. Okay, now that we have an understanding of workingwith collections, let’s modify RSA hello function to take a collection parameter so that wecan greet multiple things, will modify first the name of item to greet two items to greetbecause it’s now going to be plural because it will be a collection. And that will updatefrom string to list of string. And then now we’re going to update the implementation ofthis function. So instead of being a single expression function, we’ll add a functionbody. And then now we’re going to want to iterate over the items to greet parameter.So we’ll say items to greet dot for each. And then we’ll paste it back in our originalprint statement. And then we’ll go ahead and update the receiver value here from it toitem to Crete. It’ll add our arrow. And so now we have a say hello function that youcan pass a collection into. And then it’ll print out multiple lines. So now we can say,say hello and we can still pass in our custom greeting so we can say hi. And then we canpass it in our interesting things variable. And now if we click run, we now see high Caitlyn,hi programming and high comic books. So this just a quick example of how you can pass itin a collection type to a function as a parameter. There’s nothing wrong with including a collectionparameter in your function, however functions. And Kotlin do provide an additional pieceof functionality that can satisfy this use case and provides a little additional flexibility.Now to demonstrate why this might be interesting to us. Let’s look at an example. So let’ssay we want to call say hello and we’ll pass on or greeting, but then we don’t want topass in any interesting things in this case. Well, because of the way that this functionis currently defined, we have to pass in the second argument. So in this case, if we wantedto pass in no items, we would have to pass in an empty list, which isn’t really a bigdeal, but it’s also not the most flexible way of handling things. So let’s take a lookand alternative means of achieving this functionality. If we come up here to our say hello function,we’re going to modify this second. So that is a VAR arch perimeter VAR ARG isa keyword in Kotlin. It essentially represents a variable number of arguments. So in thiscase, instead of taking a list of string, we’ll define a VAR R of string. This tellsthe compiler that we’re going to take a variable number of string arguments after the initialgreeting argument to this function. So now if we try to pass something in to say hello,well first pass in our grieving and now we don’t actually have to pass anything in afterthe initial argument. This is because the [inaudible] parameter will essentially betreated as an array of whichever type it’s used to specify. So in this case, items toGRI is now an array of type string. So if we don’t pass any items after the greeting,it will be treated as an empty array. If we did want to start to pass items, we can dothat by separating them with commas. So it could say Kotlin and now this would be anarray of size one. But where the real flexibility comes is we can now start to define many argumentvalues here. And so now all of those arguments that arepassed in will be grouped together, treated as an array. And so in our function implementation,we can still iterate over all the elements in that array. So if we now run this, we shouldget the same outfit as before. So by using our VAR arc parameter, we’ve eliminated theneed to always pass in a value after the initial greeting argument and lets us have greaterflexibility because it will support zero one or any other number of argument values tobe passed it. Now it’s very convenient to be able to pass multiple arguments to this[inaudible] hard perimeter. However, you’re usually not going to be hard coding thosearguments in manually during compiled time. More likely you’re going to get a array ofvalues from a network request or a database and then you’re going to want to pass it thosein. So you might think that it would be as simple as passing in an array after that initialgreeting. So let’s try that. We could change list of two array of, and then after I, we’ll pass in interesting things. Oh, unfortunatelythis does not work. And if you look at the air, the see a requires string found arrayof string. So how do you actually pass in an array of existing values to this far ARGperimeter? Well, you can do that with the spread operator and all the spread operatoris, is applying the asterisk before the array variable when you pass it in as an argumentvalue. So now if we hit run, we’ll see that the compiler is now accepting that array andwe are iterating over each item in that interesting things array. So this is how you can passin an existing collection as a VAR ARD parameter. Another really interesting and powerful featurewith Kotlin functions are named arguments. Now let’s take a look at an example of whatname arguments provide to us. Let’s start by cleaning out our main function and thenwe’re going to define a new simple function that will take a greeting and a name and thenprint that up. So now when we want to call this new Greekperson function secret person, hi, and then I’ll use my name here. Now this is fine andit’s very easy to understand because the ID is helping us and showing, okay, this is thegreeting argument. This is the name argument. However, if you are in a code review, youmight not be able to know exactly which order these arguments are supposed to be passedin. Also, if you wanted to modify the function signature of Greek person down the line, you’dhave to make sure that these are in the same order because since they share the same type,you could mix that order up without getting any type of compiler pair. Now what made argumentsallow us to do is specify which parameter this argument value is going to be used for.So what does that actually look like in practice? Well, it looks like defining the name of theparameter and then an equal sign. And then here we can say main equals. And so now we’resaying very explicitly assigned, high to greeting and Nate. To me, the cool thing that thisallows us to do is actually mix up the order of these arguments. So now we can actuallypass the second parameter first and the first parameter second so that we could actuallytheoretically modify the signature of Greek person changing the order of these parametersand it wouldn’t impact the invocations of that function. Caitlyn allows us to take thisflexibility one step further by leveraging default parameter values. So once again, let’slook at our Greek person example. So here we are now able to pass the arguments in whateverorder we want. If we’re using name arguments in tax, but what if we wanted to pass mainfirst and then not even passing the greeting? Well now we get an error because it says novalue past for perimeter greeting. So as great persons currently defined, it must take botharguments, even if they are in a mixed up order. Default parameter values allow us tochange that. It allows us to tell the compiler what the default value should be if not asspecified. So for greeting, we could provide a default value of hello and for name we’dget provided default value of Kotlin. You’ll see now great person can be called by onlyspecifying a single argument value. And if we run this, we’ll see. It’s going to sayhello mate. So it’s giving the default greeting value and then it was using the value forthe name that we passed in now because both arguments have defaults, we could actuallycall this without passing any arguments in. And if we run it now, we’ll see it’s usingboth defaults and prints out. Hello Kotlin. Now this becomes a really powerfulfeature because now we can not only mix up the order in which we pass arguments, butwe don’t even have to pass all of them in. This actually allows us to replicate functionalityof the builder pattern without actually having to write getters and setters and have privateconstructors and all of that. We can configure and reuse functions and objects by leveragingthese default values and the named arguments, syntax, Wilde, Decaux parameter values, mainargument and VAR. Our parameters are really convenient and flexible and powerful. Theydo have limitations as well. So I want to illustrate one of those limitations. So we’regoing to go back to our say hello function. Let’s redefine our interesting things areright. And so now if I want to invoke, say hello and I want to pass things in order withthe greeting and then the interesting things I can do that no problem. And if I run this,we’ll get our three lines of output. And so now what if we wanted to use namedarguments in techs? Well we could do that as well. Breathing equals high. However, assoon as I add the name argument syntax to the first parameter, I get this air sayingmixing name and position arguments is not allowed. So this is one of those limitations.As soon as you use named arguments in tax for what argument, everything that follows,that must also be named. So in this case, I could fix this by saying items to treatequals and now I can run this again and I’ll get the desired three lines of output onceagain. Now I could mix these up though and because both of them are using names,argument syntax, there are no problems here. And once again, we could run this and we wouldget our desired output. Now we’re going to take a look at how we cancreate a simple class in Kotlin. Now up until this point, we’ve been working within a singlemain dot K T file. However, now that we’re going to move into classes, let’s go aheadand add a new file. So we’ll come over to our project panel, right click source, goto new Kotlin file or class, and we’re going to come down and on this dropdown we’re goingto select class and then we’re going to name this class person and then hit enter. We cansee here, then it automatically has created a person class for us and I might notice thatthis class is quite simple. So let’s take a look at how this class actually works. Tostart, we have the class keyword followed by the class name and then really that’s it.We could actually even optionally remove these curly braces. Since we’re not defining anyproperties or methods at this time, if we wanted to then use this class, we could returnto our main function here. And then we can create an instance of the class like this.So we’ll create a variable named person equals person. Now this syntax right here is howyou create a new instance of a class. Notice there’s no new keyword and Caitlyn, you donot have to explicitly call new. You can simply specify the class name and then the constructorand any arguments that you need to pass into. It can may notice that we were able to create an instance ofthe person class using this empty constructor. However, if we go back to our class definition,we don’t have any constructor defined. This is because when you’re defining a class inClaplan, if you do not have any properties defined in your primary constructor or anyarguments defined in your primary constructor, then you can actually just omit that primaryconstructor altogether. So what we see here, class person is really a shorthand form ofthis. If we wanted to explicitly define this primary constructor, we can do so by addingthe constructor keyword and then the opening closed parentheses. You’ll see here that itactually gives us a message recommending that we remove the empty primary constructor. Nowwe could also modify this primary constructor by just removing the constructor keyword andmoving the open and closed parentheses directly after the classmate. However, we still getthat same recommendation to remove the empty primary constructor. So let’s add a primaryconstructor once again. And this time let’s actually define a parameter that must be passedinto this constructor. So if we’re creating a person in class, let’s pass in a first andlast name for this person. So we could say first name string, last name string. So now we have two unused parameters thatwe pass it into the constructor. And now if we come back here to the creation of an instanceof our person class, we’ll see that we now have a compiler error saying no value passfor our printers. So I’ll go ahead and I’ll pass it in my first and last name here sowe can come back here and we’re not actually doing anything yet with these perimeters.So let’s change that. Let’s define our first property on our person class. So since we’repassing in first name and last name, let’s define properties for first name and lastname. So we can say Val, first name street, thou last name street. Now you notice thatboth of these, now I have red areas underneath them saying property must be initialized orbe abstract. And there’s a couple of different ways that we can initialize these. The first way we’ll look at is using and thenhit block can define it in a net block by using the unit keyword and then open and closecurly braces. And a net block is a piece of code that is run anytime. An instance of thisclass is run and you can actually have multiple admit blocks that will be processed in theorder in which they are defined within your class body. So within this a net block wecan initialize our property values using the parameters from our primary constructor. Sowe’ll say first name equals underscore, first name, last name equals underscore, last name.Now we have initialized properties. But if we look up at where those properties are declared,we will see these little warnings saying, can be joined with assignment. What does thatmean? Well this is the other way in which we could initialize these values. We could actually get rid of the NIC blockhere and we could initialize these at the point where they’re declared by saying equalsunderscore first name equals underscore last name. So now we’re passing in those parametersto the constructor and then immediately declaring and initializing properties on the class.So now if we go back to our usage of this person class, after we create the instanceof person, we can now access those properties. Jax as the properties where you type person.Dot and then we can access the properties by their names directly. So we can say lastname or person dot first name. Now you noticed that we’re not using a getter here in Kotlin.This is known as property access syntax. You can reference properties directly by theirname without having to worry about the getter or the setter. So now if we go back over trackclass, we could actually simplify this even a little bit more. And to do that we’ll goahead and remove these properties. And so now instead of passing in a parameterto the constructor and then defining a separate property that mirrors that parameter, we canactually declare the property directly and the primary constructor. So to do that, we’llcome up here, we’ll remove this underscore since this is now going to be the propertyname and then we’ll add the vow keyword. And now when we have defined a first name andlast name properties within our primary constructor directly, and if we go back to our usage,we see that nothing has changed here. We can still initialize the class in the same wayand still access our last name and first properties the same way. So far we’ve been working withthe primary constructor within our class declaration, but it’s also possible to define what areknown as secondary constructors. Secondary constructors can provide alternative meansfor you to instantiate an instance of your class. So let’s work with an example. Let’s say wewant to create a secondary constructor that takes no parameters so that we don’t haveto always pass values in what we want to create a new person object. So to create a secondaryconstructor, we’ll use the constructor keyword and then open and close parentheses. And inthis example we’re not going to pass in any parameters. We didn’t need to call throughto the primary constructor. To do that we use colon and then the this keyword open andclosed parentheses. And then now we need to satisfy any parameters that are declared inthe primary constructor. So in this case, let’s define some default first and last namevalues. So for our first name we’ll use Peter and last name. We’ll use Parker. Okay. And then we can define a body for the secondaryconstructor. And to just take a look at how this works with the NetBox. Let’s go aheadand add a print statement here that says secondary constructor [inaudible]. Well then add and then that block, and we’llput a message here that says, and that one. And then just for fun, let’s add a second,a net block after the secondary constructor and we’ll print out in it too. Now let’s runour main function and just see what happens. [inaudible] so in this case we’re using the primary constructorso we can specify and explicit values for the first and last name. So we’ll see thatthe secondary constructor is never called, but both admit box are called and log outto the console. So now let’s remove the explicit arguments that are being passed in. And nowlet’s rerun this [inaudible] and now this time we’ll see that I didn’tblock one is run and Nickboch two is run and then our secondary constructor was run [inaudible]. So what this shows is that the admit blocksare always going to run before the secondary constructor. Now the Invitbox will executein order in which they’re defined within the class body and the secondary constructor willbe called. Now in this example, and actually in many practical examples when using Kotlinon real projects, a secondary constructor isn’t strictly necessary because of the powerof default parameter values. So in this case we can remove all of this within our classbody and instead we can define default values here in the primary constructor. Okay. Now if we go back over to our usage, we canstill use the person class as if it had this empty primary constructor because both parametershave default values. Now let’s look a bit more closely at classproperties. Now we’ve already defined two properties within our primary constructor.Both of these are read only properties so they have no center, but they do have a getteravailable. That Gitter is how we are able to leverage property access and tax and referencethose properties directly as we are doing here in our main function. Let’s explore thismore fully by adding another property. Let’s add a nickname property. In this case we’lluse VAR because it’s not going to be set initially. We’ll call it nickname string and we’re goingto go ahead and make this a notable string and then we’ll go ahead and set that initiallyto know. Now let’s see if we type person. Dot. We see that we have a nickname property,but unlike last name and first name, this is a mutable property. So we can actually assign a value to this.So we can say equals. And then my nickname growing up was shades. So assign that stringto this nickname property. So if we go back to our person class, let’s look at this propertya bit more closely. We’ve already mentioned that properties and Caitlyn will get gettersand setters generated for them automatically by the compiler. So if your property is avow, it will have a get or generated. If it’s a bar, it will have it getter and a settergenerated. But what if you don’t want to rely on the default behavior of these getters andsenators? Maybe you want to do some complex logic within that. Or maybe you want to logsomething out for debugging purposes. Well, you can override the behavior of these defaultgetters and setters and provide your own implementations. So let’s log out every time a new nicknameis set. To do that. We go to our nipping declarationand then we’ll go to the next line and then we’ll space over four times. And now if westart typing set, we’ll see auto-completion comes up with several options here. So I’mgoing to choose this bottom one. So what this essentially does is allows us to define thefunction behavior for wins set is called. Now when we do this, this will generate abacking field for this property. So to actually assign the new value to our nickname property,we need to use a special keyword called field equals value. If we didn’t make this call,then the value of nickname would never actually be updated. And now we are free to implementwhatever you want. So in this case we can update this with a log message that says thenew make name is dollar value. So now if we go back over to our main, let’s see what thislooks like. So we’re assigning one nickname, person that nickname that. Let’s assign another nickname. In this case we’ll just say new nickname. Now if we run this, we can takea look at the log. So you see here each time for assigning a value to the nickname property,our log statement is being run. Similarly, we can override the default Gether. We dothis very much the same way. I’ll start by saying get, there’s no new value to set so there’s novalue being passed in. So instead we’ll just lock this out. Say print line. The returnvalue is dollar field. We still have that field backing value, which is what his storingthe actual value of nickname. And then we’re going to return the value of field. So nowwe’ll come back over to our main, we’ll use a print statement here, person dot nicknameand if we run this, we’re seeing that our center is being called multiple times. Thenour getter is being called and the value logged out. And then finally our print statementhere in the main function. Now that we’ve explored class properties, let’s take a lookat how we can add a method to our person class. To add a method, we really just need to defineit function within our class declaration. That’s great. A method called print info.It’ll take no parameters and it’s just going to print out the user’sinfo. So in this case we’ll use a print statement and then we’ll use a string template to pronouncethe first name, the nickname, and the last name. So we go back over here to our mainclass. Let’s go ahead and remove most of this. Now if we want to call the method on our personvariable, we can type person dot and then print info. So now if we run this, we seePeter, no Parker. So our method worked, however, the formatting is maybe not quite what wewould have wanted because nickname was no like print info was called, we printed outthe word no rather than anything possibly more useful. So let’s refactor this methoda little bit and see if we can improve that. So that’s great. A variable called nicknameto print. And then let’s check whether or not this is no. So we can say if nicknamedoes not equal no, we’ll go ahead and use the nickname else. We’ll use this more descriptivestring of no nickname and now we can update this implementation and instead of using nicknamedirectly, we’ll use this new local variable. So now if we go over to our main again andwe run this, now we see our output is formatted a little bit better now while the output nowlooks better, this expression right here is a little bit verbose. This type of check wherewe’re comparing whether or not something is no and then providing one of two values comesup quite a bit and Kotlin and because of that there’s actually a convenient syntax we canuse that simplifies this expression. So what we can do is this like maybe question MarkColon, no nickname. The question Mark Colon is what’s known asthe Elvis operator and Caitlyn, what this expression is saying is check what’s on theleft side of the Elvis operator. If that side of the expression is not no, then go aheadand return that. Otherwise return what is ever on the right hand side of the expression.So if we go back to Maine and run this once again, well now see that we’re still gettingour updated output. So this case, the Elvis operator is just a much more concise way ofdoing that. If else check. Now I want to take a minute and talk about visibility modifierswithin Kotlin. Looking at this code here, you’ll see nowhere do we have any type ofvisibility modifier specified. However, if we go over here to our main, we’re able tocreate a new instance of this class. We are able to call the print info method and weare able to access all of the properties. This is because in Kotlin classes, properties,methods, really visibility in general is public by default. If we wanted to modify the visibilityof any of these, we can add one of for visibility modifiers. So from the class we could addpublic here. However, because it’s public by default, this is not needed. We could addinternal. Internal means that this class is public within the module. So in our case,because we’re in a single module, this doesn’t change anything. We can also make this private. Once we make it private, we’ll now see thatit’s no longer available in our main dotK T file and this case a private class is onlyavailable within the file in which it’s implemented. Now we get to apply similar rules to our nicknameproperty. If we make this an internal property, nothing changes and we can still access that.If we make this protected and go back to our main function, we’ll now see that we’re gettingan air cannot access nickname. It is protected in person. A protected property or methodwill only be available within that class or within any subclasses. And as you might expect,if we make this a private property, once again, we cannot access it from our main dot KT file.And the same goes for our method. If we make this private or protected, it’s not goingto be available within main bat. K T now that we have an understanding of how classes workin Kotlin, let’s take a look at how interfaces work. So we’ll go back to our source directory,go to new Kotlin file or class. This time in the kind drop down, we’ll select the interfaceand let’s go ahead and call this person info provider and we’ll hit okay. So now the IDE has created a person info providerdotK T file and it’s auto generated this empty person info provider interface for us. Now,like with the class, because the curly braces are empty, we can actually remove those andthis is a completely valid interface within Kotlin. It’s MD. There’s no methods that canbe implemented and there are no properties that can be implemented. However, this couldstill be used as a marker interface, for example, in other classes, could in fact implementthis interface. In fact, why don’t we do that right now? Let’s create a class called thebasic info provider, the implements person, info provider. We can actually do that withinthe same file. We don’t need to have one file per class or interface within Collin. So tostart we can say class basic info provider. Now we want to indicate that this class isgoing to implement person and vote provider. To do that we’ll use a colon and then we’lltype the name of the interface and just like that, we’ve now created a new class basicinfo provider that implements person info provider. And because person info providerdoes not currently have any methods or properties, basic info provider has nothing that needsto implement. Oh, let’s add a method to our person. Info provider interface can do that.We’ll come back up to the interface declaration, we’ll add back our braces, and now we’re goingto define a function signature within this interface. Now we don’t have to actually implementthis, we just have to define the name and the parameters that are required by this method.Now once we’ve added this, we’ll notice down below now that our basic info provider classhas a compiler error saying that it does not implement the required interfaces or add theabstract keyword. So let’s take a look at how we can addressthis issue. Could you, so we’re going to start off by adding a main function so that we canplay around with this class. Now what are the ways that we could solve the compile issuewith basic info provider is by declaring it as an abstract class. This means it doesn’tneed to implement all the methods available on the interfaces that includes, but it alsocan’t be instantiated. So if we tried to come down here and say vow provider equals basicinfo provider, we’ll get an error saying cannot create an instance of an abstract class. So this case we don’t want to makethis abstract cause we do want to work with this class so we can remove the abstract classkeyword and that we want to actually implement the required methods from person info provider.So to do that we can start typing print info and the IDE will recognize that. And if wehit enter, it will generate a step down version of that print info method. Now let’s take a look at how this was generated.We see that it starts by including the override key word. This is different than in Java whereit was an override annotation. And Caitlyn, if you remove the override keyword, it’llactually give you a compile error in this case saying print info hides member of supertight and needs the override modifier. So it’s very specific in indicating that youdo need to include that override. And then after that it’s simply matches the rest ofthe method declaration from the interface. So here we’re now free to define the behaviorof this interface, however we want you also seen down below that now that we have implementedthe interface fully, we can actually create an instance of this class. So if we implementthis right for now, just printing out print info, yeah, we can come down to our main function, wecan type provider doc and then we can invoke the print info method and we’ll pass it ina empty instance of the person class and we’ll see here that it executes that print infomethod [inaudible]. So that’s a very simple example of how wecan define an interface to find a method on that interface, implement it, and then runit on that. Implementing class. Let’s improve upon the implementation of print info. Sohere we’re going to say basic info provider and then below that we’re actually going tocall the print info method on our person class. So now if we run this, we’ll see that we havethat basic info provider being printed out and then the info from the person. Now perhapswe want to encapsulate this logic within the interface itself. Maybe this print info method,it should always generally work in this same way. Well, we could actually move the implementationthat we’ve just defined right here up into our interface C and Kotlin interfaces providedefault implementation of an interface method. So now we can actually remove the implementationof print info from basic info provider and the code will still compile and run. So now if we run this, we’re going to getthe same output. However, there’s an issue with this. We see now in our person info providerinterface, we are including the basic info providers string. Well, we probably don’twant that since it is an implementation detail of basic info provider. So here we could actuallyleverage another interesting feature interfaces in Kotlin. We can provide properties on ourinterfaces as well as methods. So we’ll define a property called provider info of type strength.Now you might be tempted to give this a default value, but if you do, you’ll see that we actuallyget a compiler error saying property initializers are not allowed to interfaces. So you willin fact have to override this and any implementing class. But now that we have this providerinfo string, we could modify our print info default implementation to print out that providerinfo. So now we’ve kind of encapsulated this logicinto the interface itself. And then the basic info provider class can now just overridethat provider info property. And we override a property in much the same way as a method.So we’ll use override vow provider info type string and then we have to provide the getter.So in this case we’ll say basic info provider. And now if we run this once again that we’llsee that we are picking up the overwritten property value and then still relying on thedefault implementation of print info in person info provider. And now if we wanted to stilloverride print info we could absolutely do that and we could call through to the superimplementation if we would like and then we can print out anything else here and if we were in this one last time we’ll see that we are now relying on the property,the default implementation of print info as well as now our additional logic and the overwrittenimplementation of print info. Next up, let’s look at how we can implement multiple interfaceswith a single class. To start we’ll add a new interface called session info provider and then we’ll add a method to those calledget session ID and that will return a string. And so now if we come down to basic info provider,we want to make this class implement session info provider as well. Well I’ll be askedto do is to add a comma after the previous interface declaration and now add sessioninfo provider as well. And now once we do that we’ll now see you basic info providertelling us that we don’t implement the required methods so we can come down here and implementget session ID and we can return some session ID. Now down here on our provider class, wecan now see that we can call get session ID on our basic info provider instance. Now’sa good time to talk about how type checking and typecasting work in Kotlin. To do thiswe’re going to create a new function here called check types and we’re going to takea parameter of type person info provider. Now let’s say that we want to check whetherthis person info provider is also an instance of a session info provider. How about we goabout doing that? Well we can say if info provider is session and vote provider andthen we’ll print that out. Say is a session info provider. Otherwise print Ellen, nota session info provider and now we will call this check types function and we’ll pass inour provider variable. So now if we run this we’ll see is a session invoke provider printedout to the console. So this conditional was able to determine that the past in info providerwas also an instance of a session in both provider. Now if we wanted to flip this logicand check that it is not a session info provider, we can add an exclamation point before thatand then we’ll just flip these print statements here and now once again if we run this we’llsee is a session in both providers. So you have the flexibility there to checkthat either way. Now let’s take a look at how typecasting works. So within this elseblock we’ve already checked that info provider is a session info provider. So we can castit and then call methods on it as if it was a session info provider. So we could say infoprovider as session info provider. The as is the keyword used to cast something to anothertype doc, get session ID. So now we’re able to cast info provider is that session andfrom a provider and call any methods or access any properties on it that are specific tosession info provider. Now Caitlyn also includes what is known as smart casting, which meansthat if the compiler can check a type and validate that that type will not change, thenyou don’t need to do any additional casting. So in this case we’ve already validated thatinfo provider is a session info provider. So we don’t actually need to explicitly recastthis. We could say info provider dot. Get session info. And the compiler is performinga smart cast for us. So here we can access get session ID or other properties and methodson the session info provider without having to explicitly cast it each time. We’ve never seen how a class can implementmultiple interfaces as an example of our basic info provider. Let’s now take a look at howa class can inherit from another existing class and override methods and propertieson that base class. To start, let’s create a new file called fancy info provider. Withinthis file we’re going to create a new class called fancy info provider. We didn’t wantthis class to extend the basic info provider that we already defined. So we can do thatby adding a colon and then typing the name of the class that we want to inherit fromin this case basic info provider. Now as soon as I do this, you may notice that we havea red squiggly line here indicating an error. The error says this type is final, so it cannotbe inherited from this is a characteristic of classes in Kotlin by default and Caitlynclasses are closed, meaning they cannot be inherited from or extended. To extend thisbasic info provider class, we meet to add the open keyword by adding the open keyword,it now means that you can inherit from this class. So if we go back to our fancy info provider, you’ll now see that our error hasgone away and we can now override methods and properties in this class. Now let’s startby overriding the provider info property. So we’ll add the opening closed curly bracesto our class definition and then I can start typing provider info and you’ll see that theIDE is suggesting the property available to us to overwrite. So I’ll hit enter and thatwill go ahead and auto complete the property. Now notice it has the override modifier indicatingthat this property is being overridden and I noticed that it automatically provides acustom getter and you’ll see that it defaults to deferring to the super implementation ofthis. So we could actually override this just like this by saying fancy info provider. Ifwe were to then come back to our main function here and replace this with an instance offancy info provider and we rerun this, what mousey is printing out fancy info providerso that provider info is being correctly overwritten in our new extended class. Now let’s try overwriting the print info implementationin our fancy info provider class. So if I start typing print info, once again, we’llsee the IDE suggesting the method that can be overwritten. I’ll hit enter and again bydefault this will call through to the super implementation of print info within basicinfo provider. And so I can then add another line here that just maybe says something likefancy info. And if I come back and run my main function and that we’ll see the baseimplementation is the basic info provider implementation. And now this extra line addedby our implementation of fancy info provider. Now I want to illustrate one last point inregards to inheritance, but before we do, let’s refactor basic info provider a littlebit. Instead of hard coding the session ID here, let’s add a property to hold that value.So we’ll come here and we’ll say Val and we’ll say session IB prefix, let’s say equals session.And now we roll return session ID prefix right here in our implementation of GIP sessionID. So now if I come into fancy info provider, I want to override that new session info prefix. So to do that I might start typing sessionand you’ll notice that it’s not auto suggesting that new property that we just added. Thisis because to overwrite a property and a derived class, you have to Mark that property as open.This is just like extending a class so we can come here to session ID prefix and addthe open modifier as soon as we do that. If we start typing once again, now we’ll seeit’s suggesting the option to override session ID prefix. So just like the provider infoproperty, I can now override this and I can say fancy session. So this is just one otherway in which Kotlin works to enforce immutability. It forces you to Mark both your classes, yourproperties, and your methods as being explicitly open for extension. Now there’s a small problemwith this new session ID prefix that we’ve added. It’s really meant to be an implementationdetail of the class. However, if we come here to our call site where we’re using a fancyinfo provider variable, you might notice that we can actually access that prefix directly.This isn’t ideal because like I said, it’s an implementation detail. Our API shouldn’treally be exposing that property. Now the reason it’s available is because we have definedit as a public property. So what can we do about this? Well, if we want it to be availableand our child classes but not to the public API, we could add the protected modifier.So now that property is protected down here, when we try to access it, we get an errorsaying cannot access session ID prefix. And if we come back to fancy info provider, you’llsee that we can still override that property without any trouble. Now that we’ve explored how we can extendan existing named class, let’s look at how we can create an instance of an anonymousinterclass using an object expression. To do that. We’ll come over to our main functionhere and now instead of instantiating an instance of fancy info provider, we’re going to createan anonymous interclass. So we’ll delete that. And to start off to create our object expression,we can type object, colon and then the name of the class that we want to extend. In thiscase it’ll be person info provider. Now within this class we can override any available properties or methods.So in this case I’ll update the provider info and just say something like new info provider.Now notice below here that our provider dot get session ID call is now being marked asan error. That’s because there is no guest session ID on person info provider. But wecould go ahead and add a new method to our object expression here. So we can just sayfun, get session, I ID equals and then we’ll just put in a value here. So you see you cannot only override the existing properties and methods, but you can add to them as well.Just like you could in any other name to class. And now if we run this code, we’ll see newinfo provider being printed out to the screen. So an object expression allows you to createan anonymous inter class so you don’t have to create a new named class. So this mightbe useful for things like a click listener. If you were working in, let’s say, Androiddevelopment. Now that we’ve explored object expressions,we’re going to now look at companion objects. And to do that, we’re going to create a newfile and we’re going to name that file entity factory. Now imagine we want to create a factoryto create instances of something called entity. So to start we might create an entity classand maybe that class will have a single ID property to start. Now we want to make thisa factory like we said. So what we might want to do is change this constructor to be private.And so now if we add a main function and we try to create an instance of entity, we’llsee that we have an issue here. Well notice that there is this error saying cannot accessin it. It is private to entity. So this is because of that private constructor. Well,so what can we do? This is where a companion object could comein handy. A companion object is an object is scoped to an instance of another class.So within our block body here, we can type companion object. Now we could create a createfunction called fun create and we’ll have that simply return an instance of entity.And for now we’ll just pass it in a placeholder ID. So now we can come back down to our mainfunction and we can type entity dot companion dot create. And we can use this to createan instance of that class. This works because companion objects have access to private propertiesand methods of that in closing class. Now in this case, we can actually shorten thisby removing the reference to companion altogether. That new companion is implicit and if you’reusing it from Kotlin, you can leave it off. However, if you were using this companionobject from Java, you would have to reference that companion object instance directly. Youcan also rename your companion object. So if we wanted to name this something like factoryto be a bit more explicit, we can then say doc factory and reference it that way. Andso again, not needed from Kotlin but it could be a good way to make your code more understandablefrom the Java side of things. If you’re doing a lot of Java to Kotlin interrupt, we canalso store properties within our companion objects as well. So in this case we can createa const thou well ID equals IB and then we can come down hereand replace our entity and pass that in. Now that we have this ID property added to ourcompanion object, we can reference it from other calling code as if it was a static propertylike we’re familiar with from Java. So we could do that by typing entity dot. And thenwe can reference that ID property directly. Now competing objects are like any other classand that they can also implement other interfaces to demonstrate that we’ll create a new interfacecalled ID provider with a single method this called get ID. It will return a string. Nowthen come down to our companion object declaration and we can make it implement ID provider thesame way we would with any other class. We can then choose to implement the requiredmembers and then here we will just return a simple ID and so now when we create ourinstance of ID, we could rely on this ID method if we want it. So you see companion objectscan be quite flexible if you need them to. You could use those to compose other typesof behavior, store your semi static properties or methods and use them to create factoriesby referencing private inner properties or methods of the enclosing class. This is reallywhat you would want to leverage if you want functionality similar to that of static members and field from the world of Java. Now thatwe’ve covered object expressions and companion objects, let’s take a look at creating anobject declaration. To start, we’re going to clean up some of this code we’ve been workingwith so we will remove this implementation of ID provider and we will go back to usinga placeholder ID. We’ll remove this reference to entity ID and we can remove this ID providerinterface. Now what our object declarations and object declaration is a convenient wayof creating threads saved singletons within Kotlin. We can do this by using the objectkeyword and then a class name in this case entity factory. Now within this you can addany types of properties or methods that you would like. So let’s start by migrating ourcreate method from our companion object into heart entity factory and now we can removethat companion object and instead we can reference entity factory dot create. Now there’s one small problem with this sofar, which is that entity still has only a private constructor. Now we’re going to removethat private modifier for now so that we can use that constructor. However very shortlywe will continue to refactor this code to limit the ways in which entities can be created.Now before we go on and continue to explore some of these other class types in Kotlin,let’s add to our entity class by implementing two string so that if we print out an instanceof entity, we get some nice user readable text. So we can start typing two string. Andthen I’ll use a string template here and we’ll say ID colon is ID. And then we will alsoadd in a name property here, Val name of type string. And then we’ll say name and then substitutein that main property. And then here in our create method we will just put in a genericname. And now down here we can use a print line statement and pass in our instance ofentity. And now we see our new two stream texts being printed out to the console. Sothis will help us going forward demonstrate some of how these other classes are goingto work. All right, now that we can print out useful information about an instance ofan entity, let’s refactor our create factory method to actually differentiate instancesof entity. So to do this, we’re going to change this and make it no longer a single expressionfunction. So we will add a return type of entity and then we’ll add a return keyword.And that will, we’ll add entity. Now the first thing you want to do here is actually adda proper ID value. So here you could say Val ID equals you doID dot random U U ID dot two string. So this will give us a new random identifier and thenwe can pass that into our entity. But now we have this main property. So what can wedo to pass in a name here? Well one thing we might do is think about differentiatingbetween different types of entities. So in a very basic case, maybe you want to differentiatebetween easy, medium, and hard difficulties of these entity types. So we might want tothen have some way of passing or indicating to this factory method, what those differenttypes should be. So what am I, we could do, this is with an ENM class. Now if you’re familiarwith Java and Enim class is going to be very similar to what you’re familiar with from[inaudible] in Java. To do that, we can start typing email and then class. And then in thiscase we might name this something like entity type and open and closed curly braces. Andthen we can iterate the different instances of the email. So in this case we might sayeasy, medium, hard. So now we can come down here to our create method and then we canadd a type parameter of entity type. And so now we could say vow name equals whentype. And then we are going to add in the remaining branches. So now we have a branchfor each of our entity types. And then for a basic name, I’m just going to map theseto a string. So say easy, medium and hard. And so now I can pass in that name. So nowour factory method actually allows us to differentiate and create different types of instances. Sodown here we might start off by creating an easy entity and then we’ll print that out.And then we might say vow medium entity equals entity, factory dot. Create entity tight medium.And then we can print that out as well. And if we run this well, now see that we havea unique identifier for each entity. And then we have the customized name based on thatentity type. So the addition of this ENM class to represent our entity type has allowed usto pass in different types to our factory method and then customize the way that thoseentities are created by mapping the entity type to a name. Now in this case, we’re mappingthe name very closely to the name of the actual class itself. So to make this a little biteasier and more encapsulated, there’s a couple of things we could do. So the first thingwe could do is take advantage of the name property on an ITAM class. So to do that,we could reference our type dot nay. So this is referencing the name of that actual [inaudible]class. And if we run this, we can see what that name looks like. So you see it’s easy all in capital letters.This matches exactly the way that the class name is actually defined. So this allows usto reference the classes name directly without having to map it manually. Now this is nice,however, we don’t have a lot of control over the formatting here. So another thing we coulddo is actually add a new method to argue in class. So in this case we get add fun, getformatted name, and then we can reference that named lowercase dot capitalize.So this will return us that preform at a name and capitalize the first letter. So now downhere we can update our medium mapping and type type dot get format in name. And so nowif we run this code again, we’ll see that the first one by using the name property directlyis all capitalized. But now by using our new format and method, we have a nicer formatsimilar to what we were using before. So that’s just one example of how you can define anEnon class and then add additional properties and methods that class like you would anyother class. Now let’s continue refactoring this code tofurther differentiate between different types of entities. To do that, we’re going to leveragea sealed class seal classes allow us to define restricted class hierarchies. What this meansis that we could define a set number of classes all extending a base type, but those classeswill be the only ones that can extend that base type. So one example of this could bea loading state or results state for a network operation. It’s either going to succeed orfail and there aren’t really any other options. So in the right place we’re going to createa sealed class with an easy, medium, hard and help entity types. To start creating oursealed class hierarchy. We’re first going to remove the properties from our entity classas well as this existing override of the two string method. The next step is to add thesealed keyword before the class keyword in the entity class declaration. As soon as we do that, we’ll start gettingan error above where we tried to create an instance of entity. This is because you can’tinstantiate based sealed class type directly. So this is now where we will create each typewithin our sealed class hierarchy. So the first type we’re going to create is a Davidclass to represent easy entities. And then we will add the properties we want in thiscase the ID and name, and then we want to make sure that we inherit from entity. Sonext up we can copy that and update the name for the medium type. And now for the thirdtype, once again we’ll copy that, we’ll name this hard, but now we’re going to add an additionalproperty. This property will be called multiplier and we’ll be afloat and this can representsome type of difficulty, multiple fire if we were creating a game for example. Now notice that all of these types withinthe sealed class all extend from entity but have different types of properties. This isone of the key differentiators between sealed classes and [inaudible] classes. With sealclasses, you can have different properties and methods on each of these type and thecompiler can perform smart casting to allow you to use these different properties andmethods as you would like. We can also use different types of classes itself within oursealed class. So you notice that these are all created as data classes. However, if wewanted to remove data from one of these, that would be perfectly fine. We could also useobject declarations within our seal class hierarchy. So this case will create an objectclass called help to represent some type of generic static help entity within our program.Now because help doesn’t have a constructor because it’s static. In this case, we canadd a class body and we could add a name and add help directly. And in this case, moread ID. Since it’s a Singleton and there’s only going to ever be one instance anyways, now that we have our seal classes defined,we’re going to update our factory method to instantiate and return different types ofentity classes. So we’ll come up here to our return statement and instead of returningan entity directly, we’re going to use a wind expression based on the entity type beingin class. We’ll then add all of the needed branches. And so when we have an easy type,we want to instantiate an instance of the easy class. So to do that we’ll type D Z andthen we will pass an ID and name. And similarly for media type, entity dot. Media ID, combatname. And now for hard, once again we’ll pass it and entity dot hard ID name. But now againwe have this additional property type and the compiler recognizes that. So for now we’lljust pass it in to F as our multiplier. Now notice though that we have this help entitybeing unused. So let’s update the factory to allow us to create instances of the helptype. So we’ll come up to our entity type Unum class and add a help type here. Now noticeas soon as we added that additional type on the entity type in them class are when expressionsone to us that we need to add an additional branch. So to do that, I’ll add the remainingbranch here and I’ll default to typed up get format name. And once again below here I’lladd the remaining branch. And in this case I’m just going to return help directly. Oh, notice here that help is giving us anerror. It’s saying required and to be found entity that help. This was done to demonstratewhat happens if you do not extend from the base entity type. So if we come down to ourentity class here and you notice our object declaration for help, if we then add a colonentity to extend from entity, we’ll now see that error go away. So this is a good exampleof how the compiler can help give us this nice static type checking and all of thesethings. And if we are combining even classes was sealed classes with these, when expressionsget allows us to be sure that if we add a new type or a new branch somewhere that wehave to handle that effectively because the compiler will warn us or even give errorsif we’re not handling all of those different branches. Now let’s come down to our mainfunction and demonstrate one of the advantages of representing our entities as a seal classhierarchy. So if I remove everything, but this firstinstance of creating an entity, I’m going to specifically add a type here of entity.And so now if we, if we come down again, we can use a one expression and we’ll say, nowwe can go down here and use a wet expression to do some type checking about the entitythat we have just instantiated. So here we’ll say Val, message equals when entity. And nowagain we’re going to rely on the IBE to add all the remaining branches. So there’s a fewthings of interest to note here. So we’ll see that for an easy, medium and hard, it’sadding. This is check. So this is going to basically tell if it’s an instance of thatclass or not. But then notice for the help class, because that’s an object declarationand as a Singleton there’s no need to have it is. So in that case we can reference that classdirectly. And so now here we could add whatever message we wanted. So we could say help class,easy class, medium class and hard class. And then if we simply print that message out andrun the code, we can see in this case we’re getting an easy class. And then if we changewhat we pass into our factory method and rerun this, well now see that we’re getting thehelp class. So now we have static type checking both and specifying what type of entity wewant back and and checking the type that we’re actually getting back from that. And so wecould use this to then call any methods or properties that are specific to that class.And if we were operating on these types as in a one expression here, if we ever addeda new type, that compiler would be sure to make sure that we handled the addition ofthat new type. So now let’s return to our sealed class hierarchyfor a second and dive more deeply into what data classes are. So you see here both easyand medium and hard are all defined as data classes. Data classes are cotton’s way ofproviding very concise, immutable data types. By defining a class as a data class, it meansthat it is going to generate methods such as equals hashcode into string automaticallyfor you. What this allows us to do is perform a quality comparisons on instances of thesedata classes and treat them as equal if the data they contain is equal. So here’s an example.Let’s explore what this looks like. So we can say Val entity one equals entity factorythat create and will create an easy entity. And then we’re going to create another versionof this. And then now we can check their equality comparison. So you can say if entity one equals entitytwo per DeLeon, they are equal else per Delon, they are not equal to. Now if we run this,what will we see? They are not equal. And that’s to the expected. That’s because ifwe come back up to our factory, we’ll notice that we are creating different unique ideaseach time. So even though that the name is the same, the unique ID is different. So nowlet’s update this and see what it looks like if we pass the same data in. So in this casewe could create an easy directly and this case will pass in ID comma name and then wewill duplicate this for entity two. And so now if we run this, we’re going to expectto see you. They are equal and of course they are. So this is really convenient. This allowsus to represent data within our applications and compare this data no matter where it comesfrom. And as long as those properties are all thesame, we’re going to be able to evaluate these as true. Now another really interesting thingthat data classes give us are effective copy constructors. So we can create an instanceof entity two by copying entity one entity, one dot copy. And because this is a directcopy, if we run this once again, we’re going to see they are equal. However, we could alsouse named arguments with the copy constructor to change the value. So let’s say we onlywanted to change the BAME and you could say name equals new name. And once again, if wererun this, we’re going to see they are not equal. So you could see changing a singleproperty and the data class is going to impact whether or not two instances evaluate to trueor not when compare. Now one thing to notice is this is comparingthe value of the data themselves. If we wanted to U S referential comparison, we hit adda third equal sign here and this will check whether or not it’s the exact same referenceor not. So in this case they are not equal. However, this isn’t all that surprising sincethe data was also equal. So what about if we revert this and make this an exact copyagain? So before if we were just using two equal sign, the data would be the same. Soit would print, they are equal. However, by using three equal signs and using referentialequality, we see they are not equal. That’s because it’s not the same exact referenceof the object. If we updated this to be entity one equal equal equals entity one and runthis, now we’ll see they are equal. So that’s just one way in which we can checkwhether or not we have the exact same object or if it’s two different objects that havethe same data. Now also keep in mind that these equality comparisons are working offof the generated equals and hash code methods generated by the compiler when indicatinga data class. However, we could update this to change how the equals or hash code is evaluatedand to do that we would do it like any other class. We could add a class body and thenwe could simply override equals and or hash code. Now as in Java best practice, if you’regoing to override one of these, you should really override both of them and you haveto follow the same rules, but you have that freedom if you would like to. Another really useful feature in Kotlin isthe ability to define extension functions or extension properties on an existing class.This is particularly powerful if you’re working with classes that you can’t control but wouldlike to modify the way in which they’re used. You can define your own properties and methodsand defined kind of a new API around the existing class. So an example of this would be addinga new method to the medium class without actually defining that method within the definitionof the medium class. So to do that, let’s come down here and you can start off by typingthe fun keyword. And then instead of directly typing the method name, we can reference theclass name. Dot. And this case will type print info. And then we can define our function buddy.So in this case we’ll just say medium class with the ID and that’ll be it. And so if wewanted to come down here and now create an instance of entity dot medium directly, wecould do that. And then we could call that print info method. And if we run that code,we’ll see a medium class and then that ID printed out. So this is great if we know thatwe have that exact type that we’re working with. And in cases where we don’t know ifwe have that direct type, we could rely on smart casting. So if we update this to you,their factory say entity factory, create entity type medium. Now we can say if entity twois medium entity, now we can reference that new print info method. This is done because the if statement willonly evaluate to true if that cast is successful. So anywhere within that context it will automaticallyperform the smart cast for us. And like I said before, not only can we define extensionmethods, but we can also define extension properties as well. To do that, we could startoff by saying Val or VAR. In this case we’ll say vow and then again we’ll reference theclass type. So medium dot we’ll say info will be this property name string equals some info.If you do that, notice that we have this air. If you look, it says extension property cannotbe initialized because it has no backing field. So to actually create an extension of propertyfor an existing class, you need to rely on backing fields. Thankfully the IDE can generatethis forest, convert extension property initializer to a getter. So once we do that and notice here that wehave still defined our property but now we’re relying on this custom getter for that propertyand so now if we come back down here within our, if statement that’s doing our smart castfor us, we could reference that new info property directly. So this is how extension functionsand properties work. You could use these anytime you want to add additional functionality toexisting class. You might notice within the Kotlin standard library that many functionsand operations work by using extension functions in classes be are particularly effective whenusing them with template ID types because it allows you to define the same commonfunctionality across any type that matches that template. Now up until this point, we’vecovered a lot of things. We’ve looked at the basic type system of Kotlin, how to work withdifferent variable types, how to work with basic functions and then diving into moreadvanced functional topics like named arguments and default parameter values. And then wetook a deep dive into modeling data with Kotlin. So now I’m going to circle back to functionsand specifically take a look at higher order functions and how to work with functionaldata types. Now what are higher order functions? Higher order functions are functions thateither return another function or that take functions as perimeter values. Now much ofKotlin standard library is built on top of higher order functions and it’s what reallyallows us to write highly functional code by leveraging that standard library. So let’s take a look at how we can write ourown higher order function. To start we have a new Kotlin file and we’re going to definea new function. So we’ll call this fun. And then we’re going to call this print filteredstrengths. And now the first argument to this is going to be a list of strings. So we’llcall this list and then define it as list of string. And now the next thing we’re goingto do is define a parameter which will in fact be a function. That function will takein a string and return a bullying. We can then use that to filter out values in thepast collection. So to define a function parameter, you could start off by defining the parametername as usual. And this case, we’ll name it credit kit, followed by colon. And now youhave to define the type as you normally would to define a functional type. You can start by adding your parentheses.This will define the parameters of the function being passed in to your other function. Soin this case we are going to take a string. He’ll then add the arrow, and then you wantto define the return type. So in this case, that will be bullying. And now we’ll add theopen and closed curly braces to define our block body. So now we have a parameter calledpredicate, which will be a function that takes in a string parameter and returns a Boolean.Now we can implement our print filtered strings function to make use of that predicate functionto filter out any strings in that past list. So to implement this function, first off,we want to iterate over each string in the past list. So to do that, we could say listdoc for each and now we will be able to iterate over each of those strings. So now what we want to do is evaluate thepredicate for each stream in the collection. So we can call the predicate function in severaldifferent ways. So to start we’ll say if, and then the easiest way to invoke the predicateis to simply say predicate open and close parentheses and pass in the parameter value.A parameter that is a functional type can be called as if it was a regular function.As long as you can satisfy the required arguments. So in this case we can say if predit kit returnstrue, then we can print out that string. Now to test this, we’ll come down here and wewill add a main function and we will say vow list equals list of, and then we can say somethinglike Kotlin, Java C plus plus Java script. And now we could call print filtered stringspass in our list. And now we need to pass in a function as thesecond parameter to print filters, drinks. So we can do that by specifying a Lambda,and in this case we will say it starts with K. so this Lambda is going to evaluate totrue if any of the past strings begins with a K. now if we run this function, we’ll seeonly Kotlin print it out to the screen. If we were to update this to print things out,that started with a J, well now see Java script and Java. Now one thing to notice is it inour invocation of print filtered strings, we’ve passed our Lambda within the parenthesesof that function in vacation. However, this is something that we don’t have to do. Aswe mentioned earlier, we can take use of Landus syntax, which says that if the last parameterof a function is a function, you can specify that as a Lambda outside the function body.So we can restructure our function to look like this. We can pass in the list first andthen specify or Lambda outside of the parentheses. So this is actually very similar looking tothe for each function which we called up above. And in fact if you look at the implementationof for each is in fact a higher order function. The Lambda that we specify after invokingfor each is a function which will operate over each string and that list. Now if wecome back up here to our implementation notice we are calling the function parameter directlyas if it was a regular function. So this works absolutely great in most situations. However,if we were to make this function, type a NOLA ball type by wrapping it in parentheses andadding new question Mark. Well now see an error in our implementation of print filteredstrings. That error basically says that you cannot invoke that function parameter by usingthe parentheses directly. If it’s a nullable type to get around this, we can make use ofthe invoke method on that functional type and then we can make use of the safe calloperator and now, but updating this to do a safe invoke call on the predicate function. We can handle this rather not the predicateis no calling invoke will invoke the function just as it would any other indication of afunction. So now down here nothing has changed and how we can call print filtered strings.However, we could also pass it in list and now we could pass in no as a no function.So we’ve seen how we can treat functions as parameters to other functions and these functionparameters are really treated as tight. Just the same as let’s say integer or string. Caitlynhas this idea of functional types. It’s a first-class part of the language. This meansthat we could define a variable of a functional type and then pass that variable in any time.We needed a function parameter that matched that function signature. So an example ofthis might be something like vow credit kit and then we will define our function typeto match that of our print filtered strings function. So in this case it’ll take a string and returnbullion and now we’ll define our function the same way that we were doing it before.By saying if the string starts with aJ , go ahead and return true. Now instead of invokingprint filters, strings with a landed pass to it, we can pass in our predicate variabledirectly. And now if we run this, we’ll see the same output as we would before. So thisallows us to store function as variables. This can be really useful for things likeoptional input handling. For example, maybe you have a view on some screen and you wantto be able to specify a ClickList center for that view. You could define that as a Lambdaproperty on some class and allow client code to set that ClickList center as needed. Aswe mentioned before, higher order functions include functions which take other functionsas parameters, as well as functions that return other functions. So let’s define a function called get printpredicate and it’ll take no parameters, but we defined its return type as a function whichtakes a string and returns a bullion. And now we can return that value by saying return.And then we could pass a Lambda and say it. That starts with J. So we’re passing essentiallythe same type of Lambda that we’ve been using in these other examples. But now we’ve wrappedit in this other function and so now and so then passing predicate directly or insteadof defining a new Lambda as our function parameter, we could instead call get print predicateas a function on its own, which will then return a function which then can be used asthe predicate for print filtered strings. And if we run this once again, we’ll see thatour output hasn’t changed though. So higher order functions can work as both inputs andoutputs and Kotlin allows you to define properties with functional types. So through this function’s really become avery powerful and first-class part of the language that can start to replace a lot ofother instances. For example, you might find yourself relying more heavily on functionsto define things like event or a ClickList centers rather than defining concrete interfacesfor those same types of functionality. Now this was recently mentioned. Much of the Kotlinstandard library is built around higher order functions and especially a higher order functionsdefined with generic types. So if we look at the implementation of four each, well noticethat this is actually an extension function as well as a higher order function. So foreach works on generic Iterable type and takes in a function parameter that takes in thatgeneric type and returns unit. So this essentially allows us to iterate over each element inthe collection and then call that action on it and it doesn’t have to return anything. And similarly for each index takes in a singlefunction parameter as well. But this one takes in an event to represent the index as wellas the generic type. This allows us to iterate over each element in the collection whileincrementing a counter and then passing that counter into the function parameter as theindex. The power of generic types, extension functions and higher order functions allowsus to write single implementations of these methods and then reuse them over any typethat we can think of. Now this is very powerful and can allow us to write much more functionalcode without having to redefine these methods and functions for all of our different types.So let’s take a look at example of how we can combine some of these different functionaloperators to perform complex operations with very little code. We’ll come into this newmain function here and we’ll start off by defining a list of strings. Once again. Now let’s look at some ways inwhich we can chain these functional operators together to do more interesting things. Soas we’ve seen before, we can do a simple for each to iterate over each item in this collectionand print it out. And if we run it, we’ll notice that we see all of the programminglanguage printed out to the console. Now what if we wanted to print out only the stringsthat start with J plus similar to the functions we were working with before, we could do thatby making use of a filter operation. So we have a lot of options to choose from. In thiscase, we will just choose a generic filter and then we will use a predicate which saysit starts with J and now if we run this was he, he had only Java and Java script printedout. Now, what if our collection included some no values? So as soon as we add, no, we see now herein our filter operation, it’s warning us that Hey, this value might be no, you need to adda safe call weld in Kotlin. Oftentimes we don’t want to work with no, we want to tryand hide no as much as possible. And so we could make use of another functional operatorcalled filter not know. What this does is immediately filter out any no values up front.So everything past that in the functional chain will be guaranteed to be not. No. Soas soon as we added filter, not know, we no longer had to deal with a possible no string.And if we run this once again, we’ll see only Java and JavaScript printed out. Now what if we wanted to change the type ofthis? Let’s say we wanted to convert this from a string to an integer, which representsthe length of that input string. We could do this type of transformation using a mapfunction. The map function will take in whatever the previous type is in this case string,but it’ll allow us to return any other type we want. So in this case, we might defineour map function as simply returning the length of the string. As soon as we’ve done that.Now below that in the for each, the type has changed from string to end. And now if weprint this out, we’ll see four and 10 printed out for representing the four characters inJava and 10 representing the 10 characters in Java script. Now let’s remove this mappingand let’s remove the filter. And instead, let’s imagine that we want to take only acertain number of items from this collection. So we can do that by using the take functionand passing in. Let’s say three. What that’ll do is we’ll take the first three items fromthat collection and then we’ll be printing out each of those three names. So you seein this case we’re getting Kotlin, Java and C plus plus. Alternatively, if we didn’t wantto take the first three elements in the collection, we could use take last today, the last three.So in this case we see Java C plus plus and Java script and it has skipped over Kotlinsince that was not one of the last three elements. We can also do other transformations suchas associating the input values with some other value to return a map. So let’s createa map that essentially maps the string to the number of characters in that string. Soto do that we could say associate, and then in this case we could say it to it dot length.And so now in our, for each function, instead of iterating over strings, we’re iteratingover map entries of string and event. So in this case we can now use a template stringand say it got value comma it dot key. And if we print this out, we’ll see the lengthcomma followed by the name. This makes it really easy to map all of the input stringsto some other value and then iterate over that map. Now, what if we didn’t want to iterateover the map but instead just wanted to hold on to that in a variable? Well, instead ofusing a fork each at the end, we could assign this to a variable just like this. The continentstandard library also provides a variety of functions to help us pull out individual elementsfrom a collection to demonstrate that that’s created a variable called language. And thenwe’re going to perform different operations on our list to grab a single language stringfrom our list. So we could do that in a number of ways. We could say list dot first and ifwe print this out, we’ll expect to see Kotlin as that is the first language in the list. Alternatively, we could say we’ll start lastand in this case you’ll see that it’s actually printing out. No, since [inaudible] was thelast value in that list. Now, if we didn’t want to retrieve a null value from our listand instead wanted the Alaskan non-male value, once again, we could add the filter, not nofunction, which we used previously. And now if we rerun this, we’ll see Java script printedout instead, since this is the last non no value. Now what if we wanted to find a specificitem in the list? Let’s say we wanted to use the find function and in our predicate we’llsay it got starts with and we’ll pass in Java as a street. So this is going to find thefirst value in this list that starts with Java. So in this case it actually returnsus Java and alternatively we could use find last to find the last element in the collectionthat matches this predicate, in which case it’s going to return JavaScript. Now what happens if we are searching for astring which doesn’t match our predicate? We can test that by looking for a string whichstarts with food. If we then run this, we’ll see no print it out to the console. This isbecause there is no matching string. So fine. Last is going to return. No. And then theprint line statement, we’ll print out. No if it has a null value. Well what if we didn’twant to work with no? What if instead we wanted to use an empty string as the placeholder?Well, strings in Kotlin have a useful function called or empty. So we can actually chainthat directly off of find last here and call or empty. So at this will do is return eithera nano string or a static empty string. So now if we run this once again, instead ofno, we’re just seeing empty, we’re not printing anything out. So this is one way in which you could defaultyour collections or your strings to an empty value as opposed to a no value. And this issomething you might want to consider doing more and more of in Kotlin as you start tomove away from relying on null. So as we’ve seen, Caitlyn has first-class support forfunctions including functional types and higher order functions, and the Kotlin standard librarybuilds upon those tools and provides a rich set of functional operators for us to use.This allows us to build powerful functional chains to transform our data and make complexworkflows much simpler. All right, that’s it for this tutorial. You now have a goodunderstanding of the fundamentals of Kotlin and how to work with it, and you’re now readyto start taking that knowledge and applying it to other domains. Until next time, devs.

Leave a Reply

Your email address will not be published.