image
Inheritance continued
Start course
Difficulty
Intermediate
Duration
3h 12m
Students
20
Ratings
5/5
Description

The course covers Recycler Views, which is one of the most important features of Android app development. They allow us to work with lists or grids of data with a ton of built-in optimizations. We'll then put your knowledge into practice by building an app to display a list of posts that we can scroll through, edit them, delete them, etc.

We'll also explore object-oriented programming with Kotlin, focusing on how to build objects, work with inheritance concepts and interfaces, and other highly advanced features. You'll also learn about classes and objects and how to work with them with the Kotlin programming language.

Intended Audience

This course is intended for beginners to Android app development or anyone who wants to master coding in Kotlin.

Prerequisites

Since this is a beginner level course, there are no requirements, but any previous experience with coding would be beneficial.

Transcript

Hello and welcome back. In the last video, we got started with inheritance and built an InheritingStudent class right here, which inherits from the Person class. And in this video, we'll extend some of the functionalities that the Person class provides in our class. For example, take the printDetails method right here. Right now, as it stands, it doesn't print if the student is enrolled in any courses. It doesn't have any of that information because it's not relevant to a Person. We don't know if every Person object that we create is going to be a student or not. But we know that is going to be a student and students are enrolled in courses. 

So, what we could do is take this method right here, prtintDetails, 'Command C', paste it within InheritingStudents, and try to build on it. So, if I paste it, what happens? I get an error over here. So, let's hover over it. It says printDetails hides member of supertype Person and needs override modifier. So, it's basically saying we have to use the override keyword, and it makes sense since we want to override the default implementation of printDetails, which we are inheriting from Person. So, let's do that and see what happens. Over here, I'll type an override. And if I do that, now override has a red line. What does that say? printDetails in Person is final and cannot be overridden. So, this is something we saw with the class before and it's because these definitions are closed or final by default. So, if you want to modify them or override them, we have to make them open. So, here, we have to say open before printDetails. 

Now, if I scroll down to my InheritingStudent, you see all types of errors are gone. So, let's go ahead and modify printDetails in InheritingStudent  and try to make it do something that we want. So here, I'll say println("Enrolled in: and I'll leave it empty for now. And I'll scroll down to my main over here. I'll get rid of john.walk and john.run because I don't really need them. So, let's go ahead and run this. And now we are expecting our john object to use printDetails from InheritingStudent and let us know that john is not enrolled in any courses, so [Empty for now]. So, good. That's working. Now let's go back to our printDetails. Over here, you see the first three lines of printDetails  here looks exactly the same as printDetails  over here in the class that I'm inheriting from, which is the Person class. And if it's both the same, then we're just repeating the code, and repeating code is never a good idea in programming. 

So, what we can do instead is from my printDetails method here in InheritingStudent, I can call the parents printDetails, so this printDetails() method, and just add our courseload display below it. And how do we do that? I'll get rid of this, these three lines that I'm repeating, and replace it with a call to my parent's printDetails. And all we have to do is say super.printDetails(). And the super keyword refers to the parent that I'm inheriting from, and then you see the method pops up. So, there you go, super.printDetails(). So again, super refers to the parent class that InheritingStudent is inheriting from which is Person. So, this part will take care of these three lines, and then once it's done, it will go on to the next line. Now, if I run this, check it out, same output. Excellent. Now you see the structure of InheritingStudent so far. I have a class inheriting from another class, then I have an override modifier for my method, and then I'm calling the method from the parent  a super class using this super keyword. And what does this structure remind you of? Of course, the main activity file  we've been working with  in our app so far. 

Let's take a look. Right here, you see the same structure. We have a class that extends from another class or the parent class, we have an override fun onCreate method, which means that in app compatibility there is an onCreate method and what we want to do here is extend its functionality for use in our main activity. And then we're calling the onCreate method of the parent class first by using the keyword super, and then .oncreate. So, whatever the AppCompatActivity onCreate does, it will happen first, and then I'm adding some more code here to customize my main activity to do whatever I need it to do. And you see the same structure right here in InheritingStudent. 

So, that's what the setup and structure used there is all about, and I hope by now it's making complete sense. Now back to our code over here. What we did in our parent right here in the Person class by making the class open and then later on making this printDetails method open as well and then using an override modifier to extend the functionality of printDetails  or do whatever else we want here. We didn't have to extend anything. We could have just made our own printDetails here  that does something completely different. But anyway, whatever we did here, we can do the same with variables you want to use as well. Let's say we wanted to use a modified version of firstName in our child class, in this class right here, InheritingStudent. Let's say we wanted to use a modified version of it. I will make john and doe lower case over here when I create the object. 

So, 'Control Shift R' to run it, and you'll see First name, Last name and Full name, they'll all be lower case. What I want is for InheritingStudent, it doesn't matter how I initialize the object, I always want First name and Last name to be capitalized, which means in my InheritingStudent class right here, I'll have to do something with firstName and lastName. So, how do we do that? Well, let's try to grab it here and see what happens. So, firstName, that's a variable name. If I do that, what does it say? Expecting

member declaration. So, I'll say var firstName, and what does this say now? Property must be initialized or be abstract. So, let's initialize it. We know that we want to make it firstName.capitalize(). We want to capitalize it, but we still have this error. So, we've initialized it. What's the next error? The next error says, firstName hides member of supertype Person and needs override modifier. So, the same thing we did for the method. We have to say override over here. Now we still have an error. And what is that? Take a guess. It's basically, the firstName in Person is final  and cannot be overridden. So, to get rid of this and to make it work, we have to make firstName here, that we are constructing person with, we have to make this firstName property open as well, just like we did for the method. The way to do that is simply add open  before the property declaration. b before the property declaration. So, open var, and now if I look at InheritingStudent, you see that the error is gone. 

So, I'll do the same for the lastName, override var lastName = lastName.capitalize(). And you see I get red here as well, that's because lastName is not open, so I'll have to make it open. There you go. So, for my InheritingStudent, firstName and lastName are going to be capitalized. Let's run this and make sure it works. I'm expecting John to be capital and Doe to be capital, D and J basically. There we go. But we have a problem with Full name. It's null and null because Full name in my Person right here doesn't have the firstName and lastName properties that I'm constructing my InheritingStudent with. See here, I'm modifying firstName, lastName. So, fullName over here doesn't have access to that. So, what I have to do is I have to do the same thing for this. 'Command C', paste it down here, use override over here as well, and then make it open. 

So, now if I run this, 'Ctrl Shift R', there you go. And we seem to have a bit of a problem here. What is that? And this is interesting. You see over here, john doe is still showing up in lower case but we are capitalizing firstName and lastName here. So, why is it showing up in lower case? You see the firstName and lastName that we have here, if I click on it, you see what it highlights. It highlights the firstName and lastName from the parameters that we pass in. So, to use this firstName and lastName, we have to use the this keyword over here. So, what I'll do is put this within curly braces and say this.firstName. And here, same thing. Within curly braces and this.LastName. If I do that and run it, there you go. John Doe. So, now it's using the firstName and lastName associated with this object I'm creating rather than the parameters that I'm passing in. And in programming, you have to be careful with this. 

This is called variable scope. And the only way to really get a solid idea of this is to just run into problems like that and figure your way out of it. In general, scoping refers to the availability of variables in methods and functions and in different parts of your program and which specific variable you have access to. So, in order to use the variables associated with my object I'm creating, I had to say this. Next, for inheriting student, let's add that ListofCourses feature that we had for student, but a person doesn't have so we have to implement it from scratch over here. And in student, we had used a secondary constructor to do this to see how we could use secondary constructors. But here, we're not going to do that. We're going to actually use it in the primary constructor itself. So, we can modify the constructor of our inheriting class or the subclass, whatever way we want. See, to inherit from a class, we're doing all the basics here, This is all we need in terms of functionality to inherit everything from person. So, here, anything else we want, we can simply add next to this. So, I'll add a property, ListOfCourses. 

So, I'll say var, and I have to use the var keyword here, I can't just do firstName, lastName like I did here, because ListOfCourses I'm going to use hasn't been declared anywhere. So, var ListOfCourses of type MutableList and it's going to be a ListOfStrings. That's why we want, but I also want to set a default value for this. So, I'm going to set a default to mutableList of, and I'll specify string over here, although I don't think I need to because I'm declaring it here, but I'll just be explicit. Let's bring this to the next line so we can see all of this. Now, I'm adding an additional property in my InheritingStudent class, in my subclass, which of course means, I can use this ListOfCourses anywhere I want in this class. 

So right here, override fun printDetails. Instead of Enrolled In Empty for now, I will print out the ListOfCourses. But I also want to make sure that I handle the case where if it's empty, the display is something else and it doesn't say Enrolled In Empty. I'll use if-else clause here. So, I'll say if ListOf Courses,  which is the ListOfCourses here dot, I can use a method is NotEmpty to check for if this list that I have is NotEmpty, then I want to print Enrolled in and then listOfCourses, but I also use an else over here else I want to print line Not enrolled in any courses. Let's move the else to the next line. And since this is just one condition, I can write it in one line like this which I moved to the next line but I didn't need to use my curly braces to indicate a code block. 

Hotline already knows that. So, for simple if-else conditions like this, you can do it in one line. You could also use the curly braces if you want. So, if I ran this as it is right now, if I look at my main, I don't have my ListOfCourses. If I ran this as it is, it should still work and say that John is not enrolled in any courses. So, I'll run it. There you go, Not enrolled in any courses. But then, if I initialize my John Object with a list of courses, so I'm going to bring this back over here. I have my sample ListOfCourses, which is a list of these three courses. and I'll provide this over here when I'm constructing my John Object. So sampleListOfCourses, I'll pass this in, now if I run this. Perfect. Enrolled in and it lists out the three courses. 

So, that's a decent amount we've covered in this video, and we've learned what override does in multiple occasions, first associated with this method and then associated with variables along with extending the given or inherited functionalities of the parent and building out the child class here. So, we're going to leave it at that in this video, and try to wrap up our look at inheritance within the next couple of videos. And in the next video, we'll be looking at something called an abstract class to begin with. Hope you're excited. I'll see you in the next video.

 

About the Author

Mashrur is a full-time programming instructor specializing in programming fundamentals, web application development, machine learning and cyber security. He has been a technology professional for over a decade and has degrees in Computer Science and Economics. His niche is building comprehensive career focused technology courses for students entering new, complex, and challenging fields in today's technology space.

Covered Topics