Transcript for:
Object-Oriented Programming in Java (Option D - IB Computer Science, SL)

Hey guys, welcome back to the CS Classroom. Today in this video, I'm going to cover the SL content for Option D. Now, this is a weird video for me because, first of all, I think this is really one of the few topics in the IB Computer Science exam that should really be covered by a teacher in a real-life classroom. So, I don't know if this is the best video to be making, but hopefully I can help you out as much as possible, particularly before your exams. The other thing I wanted to say is that this is a weird, this is like, I started doing Java when I was about 15 years old, and I used it in university as well, but it's been about 10 years since I've really used Java, so it's been a walk down memory lane, but some of the concepts, like particularly object-oriented programming, are so poignant and such a defining feature of Java that I haven't really forgotten them. And I hope from this video you get a sense of that and you're able to really get a deep and intuitive understanding of object-oriented programming. Now in this video we're going to start out with some basic info about programming languages in general. Then I'm going to pose a scenario around which we're going to develop a program that makes use of object-oriented programming. Part of the reason for this is that I didn't really feel like I understood object object-oriented programming until I actually started doing a job with a software engineering job where I had to use object-oriented programming. I hope that you guys can understand it well before that. And in addition to that, we're going to cover some theoretical content interspersed with the coding. And finally, we're not going to have IB practice questions, but I am going to give you a list of basic tasks that you need to be able to accomplish in Java object-oriented programming to be able to succeed on the exam. And then I'm going to code them and describe what I'm doing. So that being said, let's go ahead and let's get started. So first I want to talk a little bit about modern programming languages. So some modern programming languages include Java, C++, and Python, and they all have certain features in common. Firstly, they use Unicode, which if you remember from topic two, allows us to basically utilize a bunch of different types of symbols and display a variety of text as output or using the programming language in general. A second common feature is portability. So we can write a program in Java, C++, or Python, take it from a Linux machine, and then run it on a Windows machine, for example. And the final feature I want to talk about is abstraction. So abstraction basically allows us to take programming concepts and and display them in a more simplified manner. In the case specifically of modern programming languages, we can take the underlying mechanics of a programming language. and we can write code as if we are mimicking a real-life process. So basically, we can mimic the way that real life works using programming because of the way that it's designed. And that's kind of a hallmark of modern programming languages. Specifically in Java, object-oriented programming is abstraction. So it basically allows us to kind of not think so much about memory and how kind of the nuts and bolts are working under the hood. And it just allows us to write code that mimics the sort of process that we're trying to model in our computer program. And I know this is kind of difficult to understand, but when we go through our programming-based scenario, I hope you guys get a better understanding of what abstraction is and how modern programming languages fill that role. Now, one thing that we're going to be practicing throughout this tutorial is coding style and naming conventions. And this is basically how to write what is called in the software engineering world, clean code. So code that can be easily used by a team, and that's easy to understand upon first glance. So some examples of coding style naming conventions include indentation. Comments, explaining what lines of code are doing. Meaningful variables, so instead of calling a variable x, maybe you give it a name that corresponds to its function. And meaningful names for methods, which are functions, and class names as well. Now the benefits of these are that it's easier for other programmers to understand your work. So if you're working in a team, everyone's kind of on the same page. And furthermore, it's easier to debug this code because you know what's going on when you just look at the code. So if there is an error, it's easier to identify the flaw in the logic of the code and then fix it. Now let's get started with talking about what we're going to be building. So we're going to be using object oriented programming to write the program of programs we're working on today. Now. This is a big topic. Object-oriented programming is a method of organizing information in a computer program that seeks to model the real world. Now, what does that mean? It basically means that we're going to take the data that we want to work with and try to... I mean, first of all, we're going to organize it into categories. So we're going to take all the data in our computer programs and classify them into different categories. And then once we've done that, we're going to give each of those categories certain... methods and certain variables to describe them. And using that sort of that way of organization, we're going to generate a computer program. So then our programs are going to be passing around these things called objects, which are basically a collection of information and functions that manipulate the information. And these objects are created from a class, which is a template, sort of a plan for what our object is going to look like. So we're going to be working with objects and in order to create an object we're going to write a class which is sort of like a template or a plan from which an object can be created. If you think about human beings, being created from DNA. I guess a DNA code would be our class and a human being would be an object, right? A DNA code kind of describes everything about us, but it's not actually human being. It's not a biological being. But from a DNA code, we could then create an object, which is in this example, human beings. Each object will have variables and functions associated with them called attributes and behaviors. Now this is just a high-level overview. If this doesn't make sense, if this seems too abstract, we're going to look at it in a more concrete way. So, in order for us to really understand object-oriented programming, we're going to be kind of playing with a scenario throughout this tutorial. That scenario is a well-known fast food chain known as Los Pollos. Los Pollos would like to implement a software-based system to keep track of their employees. Each employee has certain data associated with it, and will need to be updated at various times. When we're talking about categories of data before, what we're really talking about in the case of this program is employees. Each one of the employees is going to be an object. We're going to have an employee class or template. Each one of those objects is going to have certain data attached to it, because each one of those employee objects is going to represent an employee. There will also be other functions or methods attached to an employee object so that we can manipulate or we can carry out certain operations to update that employee's data or a variety of things. Anyways, the CTO accordingly has decided to use object-oriented programming. So the first thing we're going to work on is an employee class. And we're going to be working with a concept called instantiation. But before we do that, we're just going to go ahead and start writing some Java code. So let's go ahead and let's get started. So we're going to be working in this folder, Pollo demo tutorial. Now I'm going to create a new file called main.java. And every single Java file should have a name that corresponds to the class that we're working with. So actually, I actually just really want to capitalize this just for consistency. I want all my class names to be capitalized. It's kind of one of those things that goes along with writing clean code. So let's say main.java. Okay, cool. All right, just a little thing. But. all right cool so we've got public class main and we're always going to have this main class to execute to kind of work with our other classes so this main class isn't really going to be playing a big part in terms of just our demonstration of object-oriented programming but all the operations that we do with our classes are going to go through here this is sort of like our main staging ground so we're going to have a function called public static avoid main Also, this should be pretty familiar with you because you should know something about Java. I mean, this is meant more to be a review. But anyways, we're going to just kind of create this function and we're going to be executing really any of our code in here. So that being said, what we want to do first is we want to create an employee class. Now this employee class is going to be a plan or a template for employee objects. and it's going to be used to model employees in our program. So the first thing we're going to do is we're going to create a new file here. called employee.java. All right. So it's going to be called, we're going to have public class employee. The public is called an access modifier, and we're not going to go into that at the moment, but we will later on in this tutorial. So what I want to do first is I want to define attributes. So by that, I mean variables that we can be used or that we can use to describe every single employee. So I'm going to start by saying by, I mean, I guess in every employee has a name, right? So we're going to say string name, string being the data type and name being the name of the attribute or variable. Next, we're going to have int employee ID. We're going to have, because every employee is going to have an integer employee ID. Next, we're going to have double salary. Next, we're going to private. Well, we're not going to go with the private quite yet. We're going to have string with an array symbol and then complaints. We're going to have an array of strings and the name of that array is going to be complaints. Right here, these are all the attributes or variables that describe an employee. If you look at our chart right here, we actually specify these right here as our attributes. the data type and the name of the particular attribute. Now, this format might seem strange to you, and you may not understand everything on it, but this is actually called a UML diagram, or this is part of a UML diagram. And UML diagrams, which we'll get to later on, are used to basically describe object-oriented programs and be able to give a visual description of how an object-oriented program functions. Now, we have some attributes, but we also need to have some behaviors as well. And we're also going to need to have some functionality so that we can actually take this class and turn it into an object, which is the process of instantiation. So the next thing we're going to do is we're going to create something called a constructor. So a constructor is a function that we access or it's a function that we access in order to create, in order to take our class and turn it into a template. I'm going to say public employee string name. We're going to have a parameter for name. We're going to have an int employee ID, an integer employee ID, and double salary. Now this may not make so much sense right here, but just bear with me for a second. Also, we probably have something we need to fix up here. Okay, we'll get to that in a second. So double salary. So these are all the parameters for employee. And okay, I know what we need to do. We just need to get our braces right. So we're going to have one brace or we're not going to be, we're going to have, this is a part of our class. We're going to have braces for a class and then for this constructor method right here. Right here, we're going to say this.name equals name. This.employeeId equals employeeId. This.salary equals salary. And this.complaints. equals new string 10. So we're actually going to, here we just created an empty array of complaints. Here we're going to make sure that our complaints is going to be an empty array with 10 positions in it. Now before we go on to all the other methods right here, I'm going to go ahead and I'm going to show you basically what role this constructor plays right here. And kind of just give you a better idea of where we're going with objects in general. So right here in main.java where we're actually executing all of our code, we're going to create, we have this employee class and we're going to create a new object from it. Keep in mind that inside this folder, our main.java, actually any file here has access to all the other files. So what we're going to do is we're going to create a variable called employee1. We're actually going to give that a data type of employee because our employee1 is going to be an employee object. And we're going to say new employee. And right here, we're going to create this employee object. And we're going to give it a name of Walter. it's going to have we're going to have an employee ID of three five six and a salary of it should be 1 million dollars a year let's say 1 million and this is as we are creating a new employee object that represents Walter with employee ID three five six he makes 1 million dollars a year and that's going to be employee one Now right here, if we look at this right here, this matches up to this constructor function we wrote right here. Our first parameter was a name, employee ID, and double salary. So in every single class, I'm also actually going to tab this for clarity, but every single class we're going to have a function or a method. It's going to be public, which again we'll get to later. It's going to have the same name as the class. And it's going to have all the parameters we want to enter in order for us to be able to create this object. Basically in order to be able to give the values we want to any attributes. We can also do other things we want when we create this object, like for example, give an attribute a blank array. So this executes when we actually create an object from a class. We go from the class as being a template to it actually allowing us to create objects. So that's that right there. So now that we've done that, we can go ahead and add other functionality to our class. So we're going to do a few things. So first of all, What I'm going to do is I'm going to create what are called mutator and accessor functions. So right here I'm going to create what's called a mutator function and that's going to go look like this. Public void, add, well let's say set salary. And double salary. So I'm creating a method called setSalary with a parameter of double data type. And that returns nothing. And we're just using this function to change the value of this particular parameter right here. So we're going to say this.salary equals salary. Now, you might wonder why we used this. So when we're working with classes and with methods, we have a concept called scope. So basically, this name right here, so this particular variable only exists inside this method. So all of these parameters for these methods only exist inside this method right here. Similarly, this salary parameter we specified also only exists within this method right here. However, we want to be able to take our parameters. and set and basically allow them to interact with our class attributes with these right here so when we're using this when we're using this we're referring to our we're referring to the variables associated with our class or really it's going to be with our object so this is so while name is referring to this parameter right here this dot name is referring to what's on our class right here So we had this right here. We created a function called setSalary. And we could actually do, if we wanted to, employee1. dot salary equals 5 million. That's how classes work. Okay. We could do that. Really, any of these class attributes we have here, we can access in this way. Taking the name of the object we created and then just putting a dot and then a period. Or we can have employee1. employee ID equals 550,000. Okay. But we're not going to do this actually. So there's a few reasons for that. So firstly, we want to force... Well, first of all, the bigger thing is actually one of the most important parts of object-oriented programming is that it's kind of built for us to work in teams, right? So we want other programmers to only interact with our class in a certain way. So we don't want them to set any salary. We want them to set a salary. We might want them to set only a salary that is greater than, say, if salary is greater than or less is greater than zero. So we may only want them to set a salary that's greater than zero, which kind of actually makes sense. And that's not something we could do right here with our previous example. Okay? That's why we don't do this. So we're going to take this, we're going to put this right in here, and we're going to do that right there. Now we're also going to make these something called private, which limits the access of other classes to them. And private also means that we can't do what we just did right here. So if we give them a private designator, one of the things that happens is this is not allowed. This won't work. So again, that's so that anyone who's programming and using our classes has to abide by certain rules. Again, with the private and public, like I am doing this right here, but we are going to get into this later on. It doesn't play a role in the functionality, but just bear with me. So this is our mutator method right here for salary. Anything that changes an attribute is called a mutator method. Next we're going to do public void, public double, get salary, which is an accessor method. And we're going to add a few more methods. We'll go through this a bit more quickly because I've covered a lot of the concepts that I wanted to cover early on. So let's say get salary, and then we're going to return a double of salary. We're also going to do public string get name. return name we're going to do the same for employee id because again we want to limit access to those so the only way that someone should be able to get access to this attribute right here in name is by using get name and they shouldn't particularly since these are private up here they won't be able to just change them particularly because we don't have any set name function we're not going to set name function same is going to be true for get employee id Okay, cool. I'm just going to return employee ID, which was actually of an int data type. One thing I do want to do as well is I'm going to change these. So one thing that, one mistake I made here is I want to use something called camel case. which means that we're going to start all of our variable names with a lowercase letter, and then the next word in our variable name is going to be uppercase. So we have employee, uppercase I, and then the rest of the other word. And that's just good coding practice. That's part of those coding conventions that we talked about earlier. So I'm just going to go ahead and fix that before we go any further. That's how I named these methods as well. We have set, it starts with a lowercase letter and then a capital salary, get and then a capital S and then salary. Now the last thing we want to do is we want to allow the user to add complaints. So we're going to say, we're going to create a way to do that, particularly since this is an array. We're going to say a public add, complete a string complaint. And then we're going to go through the array using a for loop. So we're going to say for int i equals 0. Again, I think this is syntax you should already be aware of. i is less than complaints dot length. And i plus plus, which is a for loop that allow us to iterate. to this array complaints right here and we're going to say if complaints I so we're going to look for the first blank element in our array and we're going to set whatever complaint we want to add to that right there And if you understand the concept of, or if you understand the background behind the scenario, you understand why none of the employees are likely to have any more than 10 complaints. It just doesn't work that way. So this is how we'd be able to add a complaint to our employee object. Now, let's see, we've got an error right here. We have no return type. So we're not really going to be returning anything, so it's just going to be void. We're just going to be adding something to the array. Now that we've done this, I'm going to give you an idea of how we can actually go about using these methods and what this really means in a more pragmatic context. So right here, we actually went ahead and we created this object from our class. We're going to give that a more appropriate name. So now some things we can do is we can access information. We can add information to our object. So one of the first things I want to do is I want to add a complaint about Walter. So I'm going to use that add complaint method that we just created right here. And I'm going to say employee1.addComplaint. And then, yeah, scarily smart. I don't know if that's a complaint, but I think so. And, yeah, I mean, that's pretty much. as adding a complaint. So we added that complaint. What I also want to do is I want to try to get some information about Walter from this object that we just created. So I just want to get his salary and print it out. So I'm going to do system.out.println. And I'm going to do employee1. And then we're going to get our method. We're going to have... get salary. We'll just get a salary, see if we can print it out. So.get salary. And I think one of the other things I want to do is I want to write, like, so our complaints array is private right here, which I could actually change, but I think I'm just going to add a method instead that is like public void, or public string. No, I guess it'd be public. string because we're returning a string array get complaints okay but then must return and then I'm going to return this dot complaints Basically, in the context of this right here, I'm returning whatever complaints arrays attached to the object we're working with. We're going to see all the complaints for this particular object right here. Probably what I could do is I could also do system.out of print line, and then I'm going to say employee.getComplaints. and that's going to just return an array. So if that's going to return an array, I'm just going to get the first element in that array. It's going to be employee1. Okay, cool. Now, one of the beauties of working with Java and not pseudocode is we can actually run this in a machine. So let's give it a try. Odds are there'll be some errors, but that's a part of learning. Okay, right here, we have 1 million for the salary. We have scarily smart for our comment. So that's a basic introduction to how to write a class. Just to recap, we have our class attributes. We have the pieces of data that will be attached to every object that we create from our class. We have our constructor, which is just a method that has the same name as the class and that is initiated or executed when we create an object from a class. And we have methods that are attached to our class that allow us to access or manipulate the data on the object that's been created. Furthermore, what I want to say is that this process where we create an object from a class, So, what was taking place in this line right here, that is called instantiation. Okay, so now that we've had sort of a practical introduction to what object-oriented programming looks like, let's talk about some of the concepts that we just went over in a more theoretical sense. We talked about constructors. A constructor is a special method that is used to initialize an object of a class. So when we looked at it in our code, I basically described it as a method that's called when we create an object in the midst of instantiation, in the midst of creating an instance of an object from a class. And that is basically what we mean when we're talking about initializing an object, basically creating or starting an object. Now, its purpose is to set the initial values of the object's data members or perform any other required initialization tasks. So in our example right here, we, if I can just fix this window right here, we did actually set the attributes, the initial data members of an object. So for example, when we created this Walter object right here, we set the name equal to Walter, the employee ID equal to whatever it was, and the salary equal to whatever it was. We set complaints equal to an empty string array. We could have also done something else. Like we could have done a system.out.println and say a new object created. And this is a function that would take place any time, or this is a line that would be executed any time we create a new object from an employee class. And that's an example of what we mean by any other required initialization tasks. So if you look at this example right here, again, this is kind of a repeat of what we just looked at. We have a class called public class person. We have two data attributes, or you can call them class variables as well. We have our constructor right here, notice as the same name as the name of the class. We have two parameters for that particular constructor. And we are setting our class attributes equal to whatever parameters were entered or whatever input there was to that constructor. And we also have another line of code that we're just running. And this is how we would go through with that process. So this constructor right here is exactly what's being utilized right here. John would become name, 33 would become the age, but 33 would be the age, and so forth. So that's basically an overview of how we use constructors and what the role is in instantiation. Now next, this is just another example. So one thing that you should know is a class can have more than one constructor. And these can both be used to create a new object. But which one is used is dependent on the parameters that are entered in when we're instantiating or creating an object. So right here we have person, person1 equals new person John. We have one parameter which is name. So we're going to use this constructor right here, which just has one parameter. Now right here we said person, again same class, same object, person2 equals new person, but here we have a string as input and then we have an integer matching this constructor right here. So this is the one that's going to be used. So both these constructors look the exact same. Their method, the name is the same as the class, but they have different types of parameters. and that determines which constructor is being invoked or used. Now, this is also an example of something called method overloading, this idea of having methods with the same name but different parameters, and we're going to go over that in a later slide. Now, the next concept we want to talk about from a theoretical sense or a theoretical perspective is the this keyword. So it refers to the current object instance of a class. So right here we had this.name equals name and this.age equals age. So this is referring to the attribute that's associated with a given object. And these names right here are just parameters in this method and don't exist outside of this constructor method right here. So now we're using this, we're talking about these attributes that are specifically associated with the object or with the class or with the object that's been created. So for example, for this object right here, this.name would be Walter, this.employeeId would be 356, and this.salary would be 1 million. Now let's look at the next step in our scenario. So this is going to involve a concept called inheritance. Now, Los Pollos is a large organization and there are many types of employees. The CTO wants to model this aspect and is therefore creating classes to represent different types of employees in the organization. These new types of objects will contain all the attributes and behavior of employee objects in addition to some additional customized attributes and behavior. So right here We initially had the employee class. Now we're going to create what's called a subclass or a child class of our employee class. So that refers to a class that has all of these in addition to its own distinct attributes and methods. So if employee class is the parent, we're going to create a new class called salesman class. That's going to be a child. And a child is going to have these attributes and these methods in addition to everything on the employee class. So here when we create an object. a salesman object, this is what it's going to look like. We're going to be able to set our name, our employee ID, our salary, and our complaints from our employee class. But we can also set our sales array. a commission rate, and total sales value, because those are associated with the salesman class. And our salesman object will also be able to access all these methods, or will also be able to use all these methods with our salesman object that are on the salesman class, in addition to all these methods associated with the employee class. So let's go ahead and let's write some code so that we can see what that really looks like in practice. So what we're going to do is we're going to create a new file called salesman.java. So we're going to have a class called salesman. And in this class right here, we're going to have a double variable called commission rate. We're going to have a double variable called total sales value. And we did actually have this sales array, but I think we're going to leave that off for now. We'll get to that in a second. So we're just going to have these two for right now. And in order to establish this relationship between our parent employee class and our child salesman class, so that salesman gets all of the methods and attributes of the parent, in addition to having its own, we're going to do public class salesman extends employee. Now that's weird, why does it have a red line over it? Okay, yeah, it doesn't have a constructor. Okay, so, next thing we're going to do is we're going to create a constructor. So that's always going to happen in a class. So we're going to say public Salesman. and we're going to have several inputs. So when we create a salesman class, we don't just want these three, but we also want an additional input for our commission rate. So we're going to have a string name, int employee ID. Actually, I want to change the style of these. So we're going to make that commission rate and total sales value. Anyways, we're going to add int employee ID, double salary. And we're going to have double commission rate. And I'll just do that right there. And then we're going to actually create that method. And why is this all red? Okay. And what we want to do first is we're going to do super, which actually represents employee or employee class. Name, employee ID, and then salary. And what this line does right here is this actually invokes or uses the constructor from the parent class. So this constructor right here, which means we're also going to have this line of code right here. So we're going to do that, and then we're going to say this.commissionRate equals commissionRate, so whatever has been entered. And then we're also going to do a few other things. So we're going to say this.totalSalesValue. So remember this is a salesman, so they're going to have a total amount of money that they brought in. It's going to be zero. And for now, that should be good. Now, we're also going to write some unique methods which we specified right here. Again, we're going to leave the add sale one off that corresponds to this array, but everything else we're going to add. So we're going to get out of our little... Okay. So we're going to have... So double, get total sales value. return total sales value. We're going to have public double net salary. That's going to be kind of a unique one because that doesn't actually correspond to either of our attributes. What that's going to do is return the net salary. So that's going to be return total sales value. So how much they brought in times whatever their commission rate is. Because that's really going to be the amount of money they're taking home. And next we're going to have, yeah, we should probably have a method in order to be able to get the commission rate. So we'll say right up here, a public double get commission rate. Now, actually looking right here, there are a few other methods that we all have access to like add complaint and add sale. But we're going to get to that a bit later because that refers to some concepts that we haven't gone over yet. Okay. So, yeah, that's going to return, yeah, commission rate. Cool. Okay. So, what I want to do now is I want to show you like how this actually works when we're executing some code. So right here we're going to create a new object. We're going to say, it's going to be a salesman type. So we're going to say salesman, salesman1. Equals new salesman. And we're going to input a name. So that's going to be Tuco. Well I suppose Tuco never really worked for Los Pollos, but whatever. His employee ID is going to be 666 for obvious reasons. He has a salary of $500,000 a year. I don't know, I just made that up. And then he has a commission rate of.75. Seems appropriate for a complete lunatic. And, okay. So, now that we've done that... We can access this as any other object. So we're going to start by just accessing a... So this is a salesman object, but just to demonstrate that this is a child class of employee, we're going to access a method from the employee class. So we're going to access getSalary. So we'll run the system.out.println, just so you can see how it works. Then we're going to do salesman1.getSalary. Then we're also going to use a method that's salesman-specific. We're going to say salesman1. I'm actually going to backspace these because that's not really that relevant to us right now. So let's go ahead and let's run this. All right, so we got $500,000 for Tuco's salary and we've got Tuco's commission rate right here. And that is a basic application and demonstration of inheritance, a concept called inheritance. Now, Salesman class was a subclass of our superclass, Employee. Salesman inherited all of these attributes and these methods so that we could use them in a Salesman object in addition to the methods and attributes specific to the Salesman class. That's a demonstration of what we call inheritance, thinking about a child inheriting the traits of a parent. the best of both worlds. So in order for us to again look at the theoretical definition, we can say that inheritance allows new classes to be created based on existing classes. thus inheriting their properties and behavior. This term behavior refers to methods, and this term properties refers to attributes. There are different names for practically the same thing. So an existing class or a parent class is also called a superclass, and the subclass can also be called a child class. And the extends keyword is used in order to establish that relationship between both those classes. Now here we have an animal class, it has an attribute called legs, we have a constructor right here, and then we have a function called makeSound, and it just prints out the animal makes a sound. We have dog, which inherits from animal, because dog is a specific type of animal, similar to the way that a salesman was a specific type of employee. And in public dog we have the super keyword which we talked about. basically doing this right here, invoking this constructor. We have makeSound, which we're going to use this makeSound. If we do dog.makeSound, we're using this one instead of this one because we're using the dog class. We also have a function called fetch that wasn't on the animal class and the parent class, but is here. Now, this is another example of inheritance. Now, there's some pros and cons to inheritance like everything, and this is something you do need to know for the IB exam. One of the pros is that it allows for code reusability. So if we want to create a new class and it has very similar behavior to a class we've created previously, we can use inheritance to allow our new class to inherit from the old class, which reduces development time. Next, it makes code maintenance easier. Because if changes to a base class or a superclass are reflected in all derived classes, you just need to change that one class instead of like eight different classes. So, for example, if we have an animal class and we have a dog class, a cat class and a raccoon class, you want to make a change to a make sound function. that all of those classes inherit. We only need to edit that on the animal class instead of all three or four of those classes. Next we have modularity. Modularity is an advantage of inheritance. And this means that we can break down our programs into smaller specialized components. Our smaller specialized components being those subclasses. Each with their own particular, each with their own specific attributes and functionality. Now, some of the concepts or some of the cons are tight coupling. So the problem is that when you do inherit from a base class, you are kind of stuck with that functionality. And you can't modify that class without it affecting all of the classes that inherit from it. And kind of hand in hand with this particular con, if you make a certain change in your base class or super class, you could break functionality in your child classes as well because they make use of that. So those are kind of the same thing but two cons we could say of inheritance. Okay, so the next concept we're going to cover is called aggregation. And let's see how that fits into our scenario. Now Los Pollos wants to keep track of all the sales each salesman has made. So each salesman needs to have information about each sale that that salesman has made attached to it. Now, each sale should have certain information, as I just said, attached to it, and each salesman will have a maximum of 100 sales. To be honest, in this scenario, salesmen don't really survive more than 100 sales, if even that. It's a rough business. So in order to do that, what we're going to do is we're going to take a look at our salesman So right here we've got our Salesman class. We want to attach Sales to it. And by that, we want to have a collection or an array of Sales objects that are attached to this particular class. So what we're going to do first is we're going to create that. We're going to see what that looks like. So we're going to have private sale Sales. Okay, and we haven't created the sale object yet. So let's go ahead and do that. You file sale.java. Okay, so now that we've got that right here, what we're going to do is we are going to give it some attributes. So for example, we're going to have private int transaction ID, similar to our employee ID. Just a way to kind of keep track of that sale in the system. We're going to have private. double sale value. So how much was that sale for? We're going to have private string buyer name. So who bought that? Probably not the best thing to keep track of, but whatever. So we're going to have a pretty typical constructor. We're going to say int transaction ID. So, value and buyer name. And that one should be a string. And then in order to make sure that we're setting our class attributes, we're going to use this equals the transaction ID that's been entered as a parameter. Okay, cool. That's our constructor. And then we're just going to have some typical mutators and accessors. Although I don't think I really want to change any of these. I think that once we create a sale, once we instantiate this information, that's all we're really going to do with it. If we want to edit the sale, we're just going to have to create a new one. So in that light, I'm just going to say public int getTransactionId. It's going to return this.transactionId, public int getSaleValue. It's going to return this.saleValue. And, oh, sorry, that's going to be a double, I think. All right, double return type. And then we're going to have public string return by your name. Now generally, particularly when you have scenarios on the IB exam, you will have both mutators and accessors, so both gets and sets. But for this one, we're just going to, I mean, we don't really need to do that. Just by your name. Cool, okay. So we've printed a sale class, okay? And in our salesman object, our salesman class, we're going to have an array of sales objects attached to the salesman class. Now there are a few things that we need to do to modify our class to deal with these sales. The first thing we want to do is we want to initialize it. So we want to say this.sales equals new sale 10. which is basically creating an empty array with 10 spaces for sales objects. So basically, we're basically adding an array. So this already has a type of array of sales, but we're initializing it and we're making sure that it's equal to an empty array with 10 spaces that are reserved for sale objects. Now we can also put this right up here, doesn't really matter, either in the constructor or up here. We could just say sales equals new sale. We can do that for any of our attributes. Now that we've done that, we also want a way to add sales. So we're going to create a function right here called public void add sale. and we're going to have a sale object as a parameter. So we're going to have sale, sale. And then what we're going to do is we're going to say, we're basically going to find the first empty space in this particular array and then put our sale there. So we're going to iterate through it. We're going to say for int i equals 0 times i is less than sales.length, and then i++. and then we're going to have if sales i equals null then sales i equals sale so we're going to go through the array and if we have the first element that we find that is null We're going to set our sale equal, or we're going to put it in that particular element. And then we're going to say total sales value equals or plus equals. Or it's going to be equal to the initial value of total sales or initial total sales value. or actually we can say total sales value plus sale.getSaleValue. And then we can just break. You don't need to go through the array any longer. That's how we're going to add a sale and we can also do something like public, well, it's public sale, getSales. and then we can just return this dot sales. So this can be our accessor, our mutator and our accessor for that particular array. And now let's go to our main class, and let's see how we can work with that and how that looks like in practice. So basically what we can do is we have this right here. We can say we'll create a new sale. We'll say sale. sale equals our remember our transaction ID we'll just say 988790 our I think it was actually sale yeah sale value so we'll say that was a I don't know if that was a big one or a small one I guess a big one thousand dollars the buyers name was Emilio oh we got to do new sale my bad Okay, cool. So now we've done that, we want to go ahead and add this sale to our particular salesman object. So we're going to say salesman1.addSale and put that in there. Okay, so we've add sale and then sale. That pretty much does what we wanted to do. We'll just run this to make sure that everything works. What that would have done is that would have added a sale to the salesman1 object. That's pretty much it. If we got the array and we went to the first element, we would be able to see the details of this particular sale. And that's an example of how aggregation works. Now right here, this is a chart that illustrates basically what we had done in our program. So right here we had a Salesman class and we had our array Sales and we had multiple Sales objects, or we had the possibility of having multiple Sales objects that are created from the Sales class associated with our Salesman class. We also had our AddSale method. And then we had the accompanying methods right here on our sale class. Now an aggregation is a relationship between classes where one class contains an instance or an object of another class as a member variable. When that class is instantiated, we end up with an object that contains other objects. So aggregation means an object that contains other objects. If the container object is destroyed, which in this case would be the employee object or the salesman object, then the contained objects, which are the sales objects, would still exist. Okay, so now that we talked about aggregation, let's compare it to inheritance. So with inheritance, the behavior of a class, meaning the attributes and methods, are transferred to another class. So for example, from our salesman class, we can also use the methods and attributes in our employee class. And with inheritance, we're modeling a situation where one thing is a specific type of another thing. So again, the salesman is a specific type of employee. And because the behavior one class is usable from another subclass, we can actually reuse code, meaning we have to write less code. Now with aggregation, a class or an instance of a class is contained inside another class. So in our salesman class, we had instances of the sales of sales. So basically, it's sales objects. And we're basically modeling a situation where one thing has many of another thing. So salesmen have many sales. Each class has to be written in full. Here we have more of a relationship, a one-to-many relationship, rather than actually sharing code. And the next concepts we're going to talk about are going to be polymorphism and method overriding. Now, the CTO has a problem. The CEO wants complaints to be in a different format for salesmen and for employees. For example, that means that Tuco is going to have complaints in a different format than Walter is. He wants a SalesTransactionId to be included in every complaint for every salesman. To do this, even though the employee class already has an AddComplain method, We're going to create a new ad complaint method in our salesman class, different parameters and functionality. Now what I want to do is I want to go to sale right here or I want to go to employee rather. So I have our ad complaints, our ad complaint class right here. And this is actually should be private for now. But I have our add complaint method right here. And we're just going to go ahead and copy this. And we're going to stick this in our Salesman class right here. Now you might think there's a problem given that both of them have the same parameters and same name. But what we're going to do is we're going to add a parameter. We're going to say string transaction ID. Now just to avoid problems with casting and using different data types, I actually want to go to sale and change the transaction ID to a string, which I've already done right here and right here, and I'm also returning a string. And if we go to main.java, right here I'm going to input a string as the input for transaction ID. Now, one last thing I need to do right here is right here, this private string complaints. It was previously protected. I'm going to change it back to protected, because protected means that we can access this array, both within this class and within our Salesman subclass. Otherwise, it could only be accessed in the current class, which is employee. We're going to go to Salesman right here, and we're going to have the same method, but with different parameters, which is the only way this works. And we're going to do complaint.concat. And we're going to have transaction ID. So how this is going to look in practice is we're going to go back to main.java. And so right here we had add complaint where we had one parameter. Now what we can do with our salesman is we can say salesman1. and we have two options. So we can actually do the one we previously had. So we can do add complaint and we can say insane. I mean, we're describing Tuco. And or we can use the other option, which is to do salesman one, add complaint and we'll have insane but with the transaction ID. Because this may be the transaction ID of the complaint. I don't know. It probably is. We're just going to get rid of this one. But either of these are possible. And the main differentiator here is the fact that this has different parameters. So which of these functions, whether we use the one on the employee class or on the salesman class, is dictated by what the parameters are. And that's basically how method overriding works. Now another concept I want to talk about is method overloading. Right here, let's go back to our employee class right here. We just saved. Let's say that rather than having this be an option just for salesmen, we want it to be an option for everyone to use that transaction ID. Instead of having this in salesman.Java, what we're going to do right here is we're going to put it in our employee class. Instead of having a transaction ID, let's say we'll have a complaint ID of some sort. I don't really know what that is, but we're going to do that. So this also works. So we have two methods with the same name in the same class, which is employee. but they have different parameters. So we can use either one of these. Now, this is called method overloading. When we had a method with the same name in our salesman class, I guess I might as well just put that back here. This is an example of method overriding. We have a method with the same name in a subclass and in the superclass, and they have different parameters. That's method overriding. This right here, where they're in the same class but have different parameters, would be method overloading. And both of these are an example of what is called polymorphism in Java. Now polymorphism just in nature, just in generally, is a situation in which something can occur in different forms, and we can therefore perform the same action in many different ways. So thinking about a donkey kicking and a human kicking. It's a weird example, but anyways. And in Java, this is really referring to method overloading and method overriding, which we just went over. Method overloading, again, being a situation in which there are different methods in the same class with the same name, different parameters. Method overriding being a situation in which there are different methods in the superclass and subclass with the same name, but with different parameters. In all these cases, the number of parameters is a distinguishing factor, as we saw before. Next, we're going to talk about libraries. So a library is a collection of pre-written code. It's kind of like an addition or an expansion pack. It contains reusable classes and methods that can save developers time by providing common functionality they can incorporate into their own programs. Java includes a number of libraries, but third-party libraries can be downloaded and used as well. So here's an example of how we would use a library. Now, if you wanted to manipulate arrays in a certain way that's not part of the standard Java library, you go to employee right here and we could do import java.util.arrays. Then we'd have access to some additional functionality, which in this case allows us to make copies of arrays. I'm not going to do that right here, but this is some additional functionality we didn't have before that came from this library. We know it did because here the last string is called arrays, so we're using this down here to access the functionality on that library. Now mainly in the SL exam you're not really going to use libraries. You will extensively on the HL exam. But on the SL exam, you just need to know that these exist and the fact that they contain reusable classes and methods. Now later on, we will look at an example involving the use of libraries. That should help you regardless, just get a better understanding of how object-oriented programming works and give you a little bit of a bridge into the HL content. Now some of the advantages of library use are that they save development time, because actually you can download libraries off the internet that take care of certain functionality so that you don't have to rewrite it. So classes and objects do not have to be rewritten every time certain functionality is required. A lot of times these libraries are shared and used by multiple programmers, so they're more likely to be error free, because if there was an error, given how many programmers have used it, it's likely to have been found. And many times, these are tested before they're used. Moreover, because you're not implementing the functionality in these libraries, your code is going to be shorter and easier to use, making development faster. And finally, we can promote abstraction through library usage. Now, abstraction is basically hiding away the internal workings of a particular piece of code. Now, if you're using a library, you don't have to understand how it works. You can just use it. And that's an example of abstraction, which just makes coding a lot faster. It reduces development time. Now, the next concept we're going to talk about is a big one. It's called encapsulation. Now, To go back to our scenario, Las Pollas is expanding rapidly and the new software system is being used in nearly every branch. This means that there are many programmers working on the system. Therefore, we want to do something called data hiding. We don't want programmers to allow users, we just don't want programmers in general to be able to modify or view data in a way that would compromise the integrity of the system. So some attributes should be edited and some attributes should not be editable. We want some attributes that can be edited outside the class and some that can be edited only inside the class or in subclasses. Encapsulation refers to the practice of hiding the internal details of an object from the outside world. And really it's referring to the technique of binding data and functions together in a single unit and controlling access to the unit from the outside. So there are two components, just the fact that we have attributes and methods in the same class and object, and then the ability to control access from the outside. But without further ado, let's see what this means in practice using something called access modifiers. So if you look at our code right here, we basically have private, private, private, and protected. Now, private means that these attributes are only accessible within the employee class. So for example, if you go to main.java, we want to just access employee1.one of these attributes, which is, let's say, name. That just doesn't work. Right here, it says that it's not visible. However, inside here, if you want to access name, we're free to access it using this or just in general. The same is true for employee ID and salary. However, if we change this to public, meaning we can access it outside our immediate class or subclasses, all of a sudden there's no error right here and we could just go ahead and do system.out.println, employee1.name, and that would work. So public allows us to access this attribute anywhere, and private means it can only be accessible within this class. We're going to change it back to private because that's the way we want it. Now, with private, within the class, we can use mutators to change the value of the salary, and accordingly we can control what the salary is. We can put some limitations and some validation on that. This means that through using accessor methods like private, we can control how those methods are modified. Hence, the reason access modifier, or hence the reason it's called an access modifier. is protected. we can only access or we can only modify this complaints array in our in this class in our main class or in a subclass so for example in salesman right here we're modifying complaints and that's why we have to change this from private to protected protected only means that we can edit this within our class or subclass or object or sub-object if you're thinking in those terms if something is public that means it can be accessed anywhere outside the object anywhere outside the object so anything that's public you We can access outside, hence, like these methods like addSale, addComplaint, addComplaint, which are all public methods. If we change addComplaint to private, it wouldn't really serve any purpose. That just means that we can only really change it within this class, which just again makes no sense. Then this doesn't work right here. Unless we're using it in another function inside of this class, there's not really any reason to make this private. But any methods and attributes can be changed, can have their access modifier changed to either private, public, or protected. Now, we can also change the access to classes, but we're not going to get into that. You're never going to see that on the SL content. And it's just, there's just no point covering it right now. Now here's a little graphic. So private data is not accessible outside of a class. Protected is accessible to derived classes or subclasses. Public is accessible to the outside world. Actually, methods can be made private, public, or protected as well, depending on how and where we want to be able to instantiate methods. For example, in our salesman class right here, if we just only wanted to be able to create a sale, Well, actually, that's not a great example. Never mind. Well, I would say, well, I guess if we made this private right here, that means that we'd only be able to really create a sale inside this class, which doesn't make any sense. It's almost like a recursive situation. So that doesn't really make that much sense. But anyways, that can be done in a constructor, though there's not really a point to doing it. Anyways, so going back to this right here, public protected and private. And yeah, so basically what, like the reason that we're doing all this is so that when we're working with other programmers, we can make sure that they don't modify something they're not supposed to, right? So if you want them to directly modify name, if you want to force other programmers to have to use this method, like get complaints, or sorry, like set salary or set complaints or whatever, add complaints. If you want to force them to use methods and play by our rules, we can make them private. And generally you're asking, okay, why couldn't those programmers just change this code? Well, a large organization, there's just rules against that. Same thing is true for protected. If we don't want that behavior to be changed anywhere besides in the class and subclass protected, public means we can just access these anywhere. Public is what we're leaving open to other, basically the main class and other aspects of our program. So access modifiers are used to prevent unauthorized access from other programs in order to retain the integrity and maintain the functionality of our classes. Okay, so the next concept we're going to cover is going to be static methods. So in our scenario, some users have a tool to calculate after-tax salary. Now they want this to be a standalone tool. It does not make use of any data from an employee object, but it's still a piece of functionality that's related to the employee object. Now it's a bit irritating, but the user wants what the user wants. So we're going to use something called a static method in order to implement this. Now, what a static method means is that the method is the same for all instances of a class. And before we get more into the theoretical underpinnings, let's go see what this looks like in code. So what I'm going to do is I'm going to go to employee.java and I'm going to do, I'm probably going to go all the way down here. I'm going to do public static double calculate. Notice the main difference right here is static. I'm using the static keyword. Calculate net salary. And my parameters are going to be the salary. and the a tax rate so now that I've done that I'm going to say double taxable income equals salary times 1 minus tax rate Now, we can say double net salary equals salary minus taxable income. Does that really make sense? Let's see, salary times, okay, I guess that kind of makes sense. Oh, well. And then we can just return the net salary, which is going to be a double. So keep in mind that in the body of our method right here, we're not using anything from our class. We're not using anything that would be in our object. There's no this, there's none of our attributes that are being used here. This is kind of just a function that is its own thing and relies only on the parameters that have been put in. And once we do this, what we can do is we can go to main.java and the way we can make use of this is we can say... What we've been shooting here... Anyways, what we can do is we could say, for example, employee, we're not instantiating it at all. We're just going to say, we could say, um, just say twocos after tax. Eh, okay. Let's just choose a different character. Let's say sols. We'll say double equals double sols salary equals employee. dot calculate net salary and his salary is 40,000 it's the old days and the tax rate is 0.25 so then what we could do is we could just say print solve salary and sorry not print still thinking in terms of python out dot print line solve salary and that should work actually Let's go ahead and get rid of these right here. I guess that should be insane. And save it. And we have a new object created. But we also have 10,000 right here, which makes sense, I guess. Kind of. Well, maybe not. I guess I got the arithmetic wrong. But you get the point. Rather than having to instantiate an object and then call a method on that object, we can just call the method directly from the class. Just do employee.calculateNetSalary. And that's basically how a static method works. We can also have static attributes. So for example, if we did, we could say static, let's see, static, we could say public static. I'd say tax rate maybe. We could set that equal to 0.3. Or just initialize that to 0.3. Okay, so that's weird. We've got to set a double and then 0.3. Now, we're not going to get into what the combination of public and private and static does, because you don't need to know that for the SL exam. But safe to say this is accessible anywhere outside of the class. If it was private, then we would just do... We would probably just do employee. So if this was private, for example, we would have to do employee.name. No, that's not going to work. Anyways, I'm not going to get into that at this point. But we could even just leave it like this, static double. And it would do what it's supposed to do. In that case we went to main.java. We would just do solveSalary. We could do system.out.println. And then solveSalary, actually not even solveSalary, we could just do employee.taxRate. And again we're not instantiating anything, it's just directly from the class. Now, static methods are the same for all instances of a class and it's defined at the class level as we saw. So it's going to be contained in the class rather than an instance of the class. So this isn't something that's attached to an object like these other attributes that aren't static right here. So all of these non-static attributes besides this one are attached to a specific object instance. You're going to create an object and then you're going to give these all values. However, with the static method or attribute, it's just attached to the class. Because it's only attached to the class, we only need to allocate memory for one instance, rather than for every single object. Because otherwise, every single time you create an object, we're using memory to store the attributes, the methods, etc. So it's actually more memory efficient. The next concept we're going to cover is going to be modularity. Modularity is just something you need to know. It's representative of what we are doing when we're doing object-oriented programming or what we're trying to achieve. Now, modularity refers to the practice of breaking down a program into smaller self-contained and independent parts. It's basically taking a large program and breaking it down into smaller parts that can work together, but that can be individually maintained, reused, and tested. So every single part has a specific responsibility, like every single class in an object-oriented programming, and an object-oriented program has a specific responsibility or functionality. So obviously modularity is achieved through the use of objects and classes, with each class representing a different role. I say obviously because this is literally repeating what I just said. So if we're talking about object-oriented programming as a concept, we have flexibility through polymorphism, reuse of code through inheritance, and we have good organization maintainability and easy debugging through modularity. And those kind of all lead to effective problem solving. I don't know why I just did that. So some of the advantages of modularity are faster development. So different programming teams can work on different components separate from each other, and they can put them together because they're working on modules. It's also easier to debug because if you want to find a problem, you can look at each individual module, or you can see which module failed rather than trying to have to look at the program as a whole. And smaller modules, because they have less code, will lead to simpler, less complex mistakes that are easier to debug. Easier to update. So it's easier to update just one module or one piece of a program rather than the entire program itself. Reusability. You can take modules from libraries or from one program and use them in another program. Now, one of the final concepts we're going to go over is just how to graphically approach object-oriented programs. And now the most common way is by using UML diagrams or unified modeling language diagrams. These are graphical representations of software systems used by software developers to visualize, design, document their systems. And through those, we can see classes, attributes, methods, and relationships between the classes. Although weirdly in the IB exam in general, we don't use UML to illustrate relationships. They have their own weird way of illustrating them, which we'll go into here in a second. This is an example class or an example UML diagram for a class called a POSLINE. So at the top, we're going to have the name of the class. Then we're going to have the attributes in the second portion and then all the methods in the third portion. And with all of the attributes, we're going to have the data types. And then with all the methods, we're going to have the return types as well as the parameters with their types as well. Now these minus and plus signs stand for public and private. So minus means private and plus means public. And then an ampersand, so like an and sign, generally means protected. So right here, sorry, it's not an ampersand, a hashtag means protected. So right here we have this class, it may be difficult to see. We've got a bunch of private attributes. These are all minus and we have all of their data types as well with a colon and then the name of the variable itself. So right here we have flight, myFlight. So we have flight, the data type, followed by the colon, followed by colon and then the name of the variable itself. Actually, if we went back here, it wasn't exactly illustrated that way. I don't think it makes a difference on the IB exam, but this is taken directly from Mark's scheme, so this is probably best to go with, having the colon in between. And right here we have our methods, which are all public right here. And we've got our return data types as well as our parameters. Here we actually don't have the parameter names. Here we have the parameter names, like int n and then ucart. Here we just have the data types of the parameters, but I'd actually recommend including the names of those variables as well. It says don't penalize the absence of accessor and mutator methods. Remember, accessor and mutator methods are like setRunway, getRunway, setGate, getGate, and you don't necessarily need to put those if they're just accessors and mutator methods. In fact, on the exam, you'll be expected to just assume that those exist. Now for our own program, for our scenario right here, these are UML diagrams. In the employee class, we had these four attributes. Three of them are private, one of them is protected, hence the hashtag. We had all these public methods. These are pretty run-of-the-mill, just illustrates as a whole what our program looks like. Now here's an example of a diagram. We haven't really drawn one for our own class. But right here we have a transport superclass and we have isA right here. So this is our transport class and we have these arrows pointing towards it because bus, plane, and train are all subclasses of our transport superclass. And then we have a train followed with a diamond and an arrow. So the diamond with the hasA means that there are many journeys for one train. So there's an aggregate relationship here. So remember on our own program, when we had a salesman with many sales, there we would have salesman right here and then a diamond and an arrow pointing to sales. And train just uses instances of codes. There's no like hierarchical relationship. There's no like subclass, superclass, or aggregation relationship, but we're just going to have some code objects in our train class right here. Or we might just have one code object in our train class. And that doesn't mean it's going to be an attribute, that just means we're going to use it in a method. And we'll see more about this in our exam-based example. Here's another example right here. So we have a vehicle class. The car and motorbike are subclasses of the superclass. And the vehicle has an aggregate relationship with parking area. Or sorry, I mean parking area as an aggregate relationship with the vehicle. So that means a parking area has many vehicles. That's why we have this diamond and this arrow. The parking area has many vehicles and the vehicle is a superclass to the subclass of car and motorbike. And those are basically relationship diagrams. Let's go ahead and let's draw one of our own. Okay, so what we're basically going to do right here is we are going to have, okay, this is my terrible drawing. So you've got an employee class employee. And then we're going to have our Salesman class. That's going to be pointing up to our Employee class. And then our Salesman class has many sales. So we're going to have a little diamond there. And then that's going to be pointing to our Sale class. And that's basically what we have in our own scenario. Again, sorry for the terrible drawing. I am far from an artist. Okay, so next, now that we've kind of gone over a lot of the main object oriented programming concepts, what I want to do is I want to talk about the pros and cons. So some of the pros of OOP are modularity, code is easier to maintain and modify, encapsulation, We have some protection against data from being modified accidentally through private, protected and public, and inheritance, which allows new classes to be based on existing classes, and that means that we can reuse code and we can easily make changes across a wide number of classes. Now some of the cons are that OOP isn't suitable for smaller projects. So if we're just writing a simple script, like just maybe to, I don't know, calculate, calculate sign or something like that. Using object-oriented programming would just increase the complexity with no real benefit. Also, object-oriented programs take up more memory and are therefore slower. Finally, just this whole process of modularity takes more time and effort. I think the payoff is there, but it is just going to take more time and effort than just writing a program in a more procedural manner without the use of object-oriented programming. Right here, we have a list of different terms. We've gone over all of these. What I'm going to do is I'm going to include the slide most likely in the description, and you're going to have access to all of these terms. I think the only one I want to go over that we haven't gone over, the only two is identifier. Now, identifier is just a name that is used to identify a variable method class or other programming entity. For example, when we are looking at our Code right here, name would be identifier, employee would be an identifier. Right here, add complaint would be an identifier. Those are all classified as identifiers. Additional object reference. When we're talking about an object reference, we're talking about a variable that is used to access an object. That variable contains the memory address of the object, which is the reference. Right here, when we have employee, employee1, And that's basically a reference to this employee object. That's an object reference to this object that we've created right here. The other terms we went through in this video, also I guess method signature. That includes the name of the function and all of its parameters. Right here, the method signature would be, let's say an employee. It actually include this part as well. We'd have public void, the return type, the name of the method, and then all the parameters. I mean, there are two variations. I've seen definitions include this. I've also seen definitions that just include the name as well as the parameters. I would say in Java, this would make sense to be the method signature. If anyone's asking you for the method signature, it's not going to hurt to write all of this. These we've all gone over. Okay, so I kind of had a little project planned, but I think in the interest of brevity, we're just going to go straight to an example. Basically, I just worked out an example paper two, and I think that'll probably give you more insight into the exam and into these programs in practice than the tedious project that I made up would. So let's go ahead and let's get started with that. Okay, so right here it says a restaurant uses an object oriented program to manage the cost of the food and drink consumed by customers. Every time a table is occupied, a payment object is instantiated, which will contain the details of the items ordered. So basically, we have a restaurant, we've got tables in that restaurant. And every time someone sits down at a table, that is going to be represented by a payment object. and connected to each payment object is a well it says as each item is ordered a food item or drink item object is added to the payment object as appropriate so we look down at the at the payment class we actually have an array of food items and we have an array of drink items and because these are food item and drink item type we can assume there's also a food item class and a drink item class in addition we have other attributes so we've got So we've got an integer of phyCount, which presumably keeps track of the number of food items and we have an integer dieCount, which keeps track of the die items. We also have a static food tax and a static drink tax right here. And we have our constructor in which the phyCount and dieCount are initialized to zero. Beyond that, we're going to have a getDie method. So based on the index entered, we can get a specific drink item. And it says all other accessor methods are included. So we have add food and drink item and presumably we also have a get a get phi as well. That also returns a specific item in the the fire array. We have a another static method here that's find price. And that takes the input and into an input of items. and I don't know what that is yet, I guess presumably we'll see that later on, and a string C, and a calculate bill item here, which is not as clear. That returns the bill, or the total value of the items consumed for a particular table. And that's not inside the static method, that's just kind of here, which is weird. But anyways... Moving on, we also have, this is our food item method, and we have a item code attribute and a quantity attribute as well as a constructor, which both of these are initialized to whatever the input parameters, as well as accessors and mutators, presumably for both of these. And a drink item that is defined, it's basically the same thing as this. So, going to our first question. We have A, outline an alternative method of initializing these variables that would not require the use of the code in the constructor. Now basically right here in the constructor, we initialize these to zero right here, but instead of doing this, we could actually just say phi count equals zero and die count equals zero right up here. And that would just be the answer there. Next is state the implication of the use of the term static in the payment class. So right here we have a static attribute here for food tax and drink tax. And we also have a static method right here. So that means that these values can be accessed without instantiating the payment object. So, in other words, they're the same for all payment objects and they belong to the class, not the object. So, in practical terms, if we wanted to access the food tax, we could just, or if we wanted to print it out, we could just do system.out.println and then we could just do payment.foodtax. And that would be it. Versus for the other attributes, we'd have to say payment, payment one, we basically have to instantiate the class, we have to create an object. So we can do this with a static attribute or a method, and we can't do that with a regular attribute or method that's connected to the class. So with reference to two examples from the class in page 10, explain the benefits gained by the use of different data types. So there's a couple of benefits. I would say like the biggest distinction right here, the biggest ones that stand out to me are the the quantity, like these values, the integer and double numerical values, because unless we have numerical values for these, we can't really do any mathematical calculations with them. And that's particularly relevant to FUTACs, because we are going to be doing some multiplication and probably some other arithmetic with these. With phi count specifically, unless this was defined as an integer, we wouldn't really be able to use it as a index for our arrays. Moreover, another data type right here would just be these arrays. So, I mean, these are basically arrays of objects and having that allows us to attach a large number of objects of the same type to a particular class or object. And without doing that, that is simply not possible. So, I mean, I guess some other things we can talk about as well is that depending on the data type that we use, we're using less memory. So an integer is going to take take up less memory than a double. So that can also have an impact on a program as well. Same amount of memory that's being used. And that can be a benefit. Right here it says describe the purpose of the following statement. Private food item phi equals new food item 100. So basically what this is doing is this is initializing the array of food items phi with a blank array with 100 items in it. That's basically what it's doing. I can't really think of any other purpose there. I guess the other aspect of this would be the private accessor method right here. And all this means is that we can't access this attribute outside of an object. So we can't just do payment.phi. That's impossible. And additionally, it can't be accessed by any subclasses that we have of payment. So if you have any subclasses, like for example, maybe we had I don't know, friend payment or something like that, we wouldn't be able to access the food item array in that particular class. Right here it says the payment class method addFoodItem is passed as a food item object as a parameter. Construct the method addFoodItem. Okay, so there are a couple of ways to do this. So we want to construct the method foodItem right here, which is, I guess it was shown right up here. So we add foodItem. So if we want to add a new foodItem object, what we're going to do is we're probably going to say public. And it's going to be void because we're not really returning anything. It's going to move this here a bit. We're going to say public void and then add food item, obviously, with a parameter of food item, of type food item. We'll just call that ft. And yeah, actually, I think I will just kind of make this smaller right now. And I think the way what we can use is we have this phi count. So that phi count should be, well, let's see if it gives us any details about it. But the phi count should be like incremented every time we add a new food item. And so basically what we can do is we can say phi. So, if I count equals FT, because basically let's say that we add a food item to this particular array. That means we're going to increment a phi count by one, and the index zero is going to be occupied in the food item array. which means that phi count, which means that phi one is going to be available. So this actually pretty much works, allows us to put the food item in the next available index in our array. And we also want to increment phi count once you've done that. That's how we're going to add a food item to our phi food item array. So that's actually the first part. That's number 10 right there. Let's move down to number 11. So right here it says the global variable tables is declared as follows. So you've got a payment array called tables with 50, basically 50 elements in it. And this is going to be a blank array. And by global variable, this means this is going to be declared probably in a main method. So it's going to be declared outside of a particular class and it's just going to be there. Now, the indices in this array represent the table number, so tables1 is a payment object for the customers occupying table number 1. Now, the driver, the main class, which is what also contains this, contains the following code. State the output after this code is executed. Okay, so right here, let's just walk through what this code is going to do. So we're going to have tables one and tables two. So we're going to have new payment objects there. And then we're creating two food items right here and then one drink item. So we are adding, so basically adding these two food items to table one. this drink item to table two, then we're actually creating a new drink item right here inside these parentheses. And then we're going to immediately add that to table two. So table one is going to have two food items and table two is going to have two drink items, including this one and one just created or instantiated right here in the parentheses. So if we do table one dot get phi count, we're going to have... We're going to have, so the first time we add this, we'll have one. And the next time we add this, we'll have two. So we should print out right here for this one, two. And then right here it says payment.getFoodTax. So food tax, I believe right up here was set to 0.2. So that's just going to be 0.2. So we're going to have two for this line, or two for this line, we'll have two, 0.2. and then it says right here system.out.println tables2.getDie1.getItemCode. So if you look back up here to our getDie method, and that's on tables2, getDie is going to allow an index input, and then we're going to get the drink item at that index. So if you look at this right here, this drink item would have been an index 0 in the drink items array. and this one right here would have been index one in the drink items array so and if this one is at index one which is right here this is gonna be the item code remember because if we go back to that method up here for that method well okay so for that method actually well I guess this is food item but drink item has the same We have an attribute item code that we're inputting, and then we have an attribute quantity that we're inputting. So the first one is going to be item code right here, and the second one is going to be quantity right here. So that means if we go down right here, this would have been the item code, and this would have been the quantity. So if we do get item code on this particular item, which is an index one, then we would just be getting D103. So that's going to be the answer to A. Now it says construct statements and code that will print out the following. Number of drink items ordered by table 40 and the item code of the third food item ordered by table 2. Alright, so if these are going to print out the following, then we're going to have system.out.println. And then we're going to have and we're gonna have okay so ordered by table 40 so right here it says that tables one is for customers occupying table number one so for table 40 that means we're gonna have tables 40 we want to get the number of drinks if we go back up here we should be had a get die So this is getting a specific drink. When we have a get add food item, add food item and add drink item. And if you want to get the numbers right here, it said the number of drink items. That means we probably want to get the die count right here. And if we have all of their accessor and mutator methods, and this is private, that means we're probably going to have a getDicount method. It's going to allow us to do that. So that's going to be the answer to that one. Now right here it says the item code, we want to get the item code of the third food item ordered by table two. So if you want to get the third food item ordered by table two, that means that we're going to do system.out.println. We're going to go to tables two. I'm actually going to put this right down here just so it's easier to see. And we're going to... So if that's the third, so when I get that third food item, so if we have to, so in order to get food items, we need to do as we saw right up here, we're going to have a, we're going to have, if you have an add food item, we're going to have a get food item and add drink item class or add food items and get drink items method rather. However, we're talking about the third item, right? So the third food item, so that means the index, it's going to be an index of 2 in the food items array. So we can do tables2, and then similar to get die right here, we're probably going to have a get phi. Index 2, and then we want to, if we get phi that means we're going to get a food item, and we want to get the item code, so it's going to be.get item code. Now, I just want to point out to the fact that there is a lot of assumptions here about what methods are here and what aren't. If you have variables, if you have any of these variable attributes, expect for the static ones. sorry I can't talk today except for the static ones, then you're going to have a get and set method for those. And if you've got any methods right here with arrays, you're going to have an add method to add an object to them. And you're going to have a get method to probably get a specific item from them. In this case, it's get die or get phi. But you're going to have both of those things either to get all of them or to get the item in a particular index. So you can just kind of assume that when it says all their accessor and mutator methods are included. I know that might be confusing, but that's kind of how it works. Okay, so this is still question 11. So it says the price of each item is stored in an object of the item class. Now if you don't remember the item class, that was right here on this static method right here. Where is it? So we had find price item, we had an item array called pl, and a string c. And we didn't really know what that was, but I guess we're going to find out now. So right here it says the price of each item is stored in object of the item class. The class is outlined below. We have public class item and on that we've got three attributes. We've got string, we've got code, name, and price. Two which are strings and one which is the price. All of the accessor mutator and constructor methods are included. I assume the constructor methods are initializing all of these. So it says all the objects in the class are held in the global array PL according to the following declaration, item PL equals new item 200, which means we've got an array potentially with 200 elements. The number of objects held in this array will change from week to week. The method findPrice item PL string C in the payment class looks up and returns the price of the item with code C. Construct the method findPrice, you may assume that the item exists in the array. All right, so basically what we're going to do is we're going to start with the method definition. So, we're going to have, we're basically returning a price. And that, the price right here is known to be double. So, we can say public, I'm just going to go ahead and make this a bit smaller here. Price for public double. And price. item, p, string c. That's going to be our method definition. All right. And now we want to go through this array and we want to find the particular item that matches the item code. So what we can do is we can say for i equals zero. i is less than p.length, i++. That's going to be our loop right there, initializing 0. And then continuing until we get to the length of the array. p i dot get let's say it's probably gonna be get code equals C then we're just gonna go ahead and I think we're gonna return PI And we can do return because as soon as we find it, we want to return that value. And we don't really want to get anything else. When we do this return right here, it will end the execution of the function. So basically exit is out of the function. So that's probably a good way to do it. There's obviously other ways to do this. Let's see if there's any other particular... Okay, it says the number of objects held in this array will change from week to week, looks up and returns the price. Now there are a few other things that we could do if we really wanted to. I mean, if... So if you want to check all 200 entries, then we could do that. We could just say, well, yeah, if you want to check through all 200, we would just say found equals true and price equals zero. And then we could just do price equals p of i. And then after the for loop, we would just return price. It's another variation that I just mentioned because in the mark scheme for some reason, it said you have to check all 200 items, but they both accomplish the task. Okay, so let's go back to the exam and let's move on. I'm going to zoom in a little bit right there. Okay. So we constructed the find price method. Now it says when a customer wishes to pay the bill, the calculate bill method is called. If the bill was for table 10, then the following call will be made. So tables 10.calculateBillItemPL. So this global item array is going to be put in here so that we can get the prices of whatever items that the particular table has ordered. And so we need to calculate, or we need to construct the calculate bill method. So let's go ahead and let's do that. And we're going to start by creating the method definition. We're going to say calculate bill. Well, look, so we're going to be returning a double, something of double data type. So we're going to say public double calculate bill and then item PL. And this is going to be on this particular class right here. So we're going to go right back up here. So right here we have calculate bill. And, okay, so we're also going to have access to all of these different methods right here. So there's a few things that I think I want to do. What I want to do is I want to go through every single food item and every single drink item. So I'm going to say 4. I'm going to create two loops. I'm going to say 4i equals 0. i is less than phi.length. I plus plus and I'm gonna go I'm just gonna get every single item so I'm gonna say okay how do I want to do this so right here let's see what else do we have right here okay so every food item has an item code and I think we want to use that item code in our, well obviously we're going to use that in our particular method. But also one thing to keep in mind is we're going to have access to our find price method. So actually I'm going to copy paste this. I'm going to make sure that we still have that. And it may not be completely clear, but any of these questions, if you have previously written a different method, then you can actually make use of that in subsequent questions. So we're going to leave that right up there. Then we're going to paste what we have. And I guess I need to rewrite that. So we're going to do public double. Let's see, calculate or find, yeah, calculate bill. Then we had item C. Let's go down here and make sure that's what it was, or it might have been item P. item pl let's go back to creating our array we'll say for i equals zero i is less than pl dot length and i plus plus and then we're going to go and we're going to say see we have a food item tax as well we take into account um But we'll go back right up here and we will start by getting the prices of all of the different items. So I'm going to create, I want to say like, okay, we'll write, I'm going to create a methods like double food. We'll say food total equals zero. Okay. And we're going to do, for each of these, we're going to say item price equals, well, we want to get the item code first, right? So for each one of the food items right here, we're going to say item code equals, we're going to have phi i. Because that's going to be the accessor that corresponds to this particular object. And then we're going to use find, we're going to say item price. We'll just say food. I'm just going to make this clear because we're going to do this with drinks too. We'll say food code, food price. equals, because we got in the item code, so then we can use our find price right here. And that's going to return our price. So we can say find price, PL, and then food code. And then we're going to say food total equals food price times one plus our food tax because you want to increase the value of each one by 0.2 so we'll say one plus uh food tax okay so so far so good well okay we want to do food food total because we want to add our existing total so i'm going to write that with the correct camel case notation equals food total there we go Okay, so we can do that and then we can do the exact same thing basically for, well, although this shouldn't be PL dot length right here, that's a mistake, because PL corresponds to items. So I think this is actually just going to be phi count, or we could even do, we could do phi dot length, but we'll just do phi count because we've already got that from right here. And now what we're going to do is we're going to go, I'm just going to copy this. Like, this isn't good programming practice really, but like... And there is a better way to do this that uses less code, but just for keeping things simple, because the process is the same for both of them. And I don't even really need to change the names of these because of scoping. Like this i only exists within this block of code, and this j only exists within this block of code. But we'll just do it just to keep things clear. We die. drink price, drink code. I'll just move this over just even a little bit. Then we're going to change this to drink total. Drink total plus drink price, that particular item times one plus drink tax. Because drink tax is different, the drinks tax is only 0.1. And then we can say that the total... Okay. Ooh, I guess I made a mistake right here. So right here, I forgot to leave out the quantity. So each of these right here is going to have a specific quantity. So it's not just going to be one of those items. It's going to be how many ever of those items there are. So just food price isn't enough. I guess we can say food total. Now we already have food total. Food order total. equals food price times food times FII dot get quantity. And then we will have food order total right here. because each food item, it could have multiple, it sounds really unintuitive actually now that I think about it, it could have multiple things associated with it. So, for example, you might order three beers, and then three vodkas, and then three wines, although we'd probably be really drunk by the end of that. So I'm going to do the same thing right down here, just to take that into account. That really, that's kind of weird the way it is, but... Yeah, I guess we order more than one of a particular item. So maybe not that weird. We'll say drink price times DI docket quantity. Okay. Cool. Looks good. All right. So now that we've done that, I'm just going to say, actually, I need to initialize this right here. I'm going to say double food total. Actually, yeah, it's going to be a double right there. And double drink total as well. Okay, and right here I need string, food code. Double food price. I guess I kind of forgot about this because we don't really have to do this in Python. But, hey, we're doing Java right now. And we're going to have double. and double drink total right here. Okay? And you do really need to get all of that right. So now that we've got that, we can say double total. Or actually, we can just return. I'm just going to make this like as clear as possible. We'll say double total equals food total plus drink total. And then return total. Okay, so that was pretty long, but I think that's the last coding question. Okay, so we're going to go back down to 12 right here. And we did actually successfully complete that particular question. Oh, so that was actually still 11. So now 12 is kind of more theory. It says construct a diagram showing the relationships between the payment, food item, drink item, and item classes. Now... This is kind of drawing diagrams from the relationships is something that you have to do on a lot of the different option D papers. You've had to do in a lot of different option D papers. So you should know how to do it. We're going to look at a, we've already seen some diagrams, but we're just going to look at the answer real quick. To just so I can kind of illustrate what this is supposed to look like. Okay, so right here remember payment has, it says has A, but this diamond means that there are multiple of these food items associated with payment. Payment also has multiple drink items, so we have a diamond, we have hasA, and then we have an arrow to drinkItem. And then we can just say that payment uses item. Because item is not subclass, it's not really in the hierarchy, but payment is just making use of item objects. So we have what the payment object uses, which is items, in that static method. And then we have what it has, which is multiple food items, multiple being denoted by the diamond, multiple drink items with multiple drink items, or multiple again being denoted by the diamond right here. So now it says, by making reference to any of the above classes, describe two benefits that a programming team would gain from the use of encapsulation. So what encapsulation basically means is, one, having all the attributes and methods all together in one object. And that's useful because that means that we can actually go up here. And for example, if we want to get calculate bill, we can make use of all the other attributes in this object and aggregate them in order to be able to find the bill in conjunction with another method that we have, which is find price. So just being able to have those all in one place and be able to make use of them to do complex calculations is one benefit. I would say another benefit is to the other use of encapsulation, which is those accessor methods, right? So because these right here, because these are private, this means that if we want, we can control exactly how they're used through our accessor or more importantly, mutator methods. For example, right here, if we wanted to have a specific criteria for the indices, we want to make sure someone's putting in a valid index, we could do that. So basically what we can do is we can use accessor methods, which are a component of encapsulation in order to make sure that only those values are being edited, that we want to be edited from outside the object, and then also control how they can be edited by forcing other programmers to use accessor and mutator methods. And now, let's see. It says by making reference to any of the above classes, okay so we already just did that, it says the company who owns this restaurant also owns hotels, shops, and a car hire business. Programs that manage the finances of these different businesses include classes similar to the ones shown in this paper. Explain how inheritance could be used as a tool to both improve the clarity and the design and to reduce the amount of code that needs to be written. So probably what I would do is I would create a generic payment class. And remember the payment class actually corresponded to tables. But I would have in hotels, it would probably be hotel rooms. In shops, it would probably be just a customer. And in a car hire business, there'd probably be a car. And I think they could all share a payment class. I mean, obviously, that payment class wouldn't have payment or drink items, but it might just have price or it might have the quantity of units. So that could be one way which inheritance could be utilized. We could have a generic payment class and we could have the different types of goods being sold in each one of these different places inherit from that payment class and have their own attributes and methods assigned to it. That also means that we wouldn't need to write the code in a payment class over again. We could just write the code once and share it between these different subclasses. I think that it's probably the most... significant way. We could also, well I guess static methods or attributes don't really play into that, but yeah just this idea of having a generic payment class and then having classes associated with the specific type of business. Anyways, that's basically a whole option D paper. I was going to do two of these, but this is running into 37 minutes, so I think we're just going to stop here. I hope that was useful to you. I know this may have been hard to see. I've never actually done this before, like having a paper on one side and writing code on the other side. Hopefully this was of some value to you and I could walk you through some of my logic. Okay guys, so that basically wraps up the SL portion of option D. I would have liked to do another exam paper work through and potentially a little project, but I really wanted to balance between brevity and content, and that's particularly true as I'm putting this out two or three days before the exam. Now HL is topic 5 on steroids. It's basically taking all the topic 5 content and then applying it to object-oriented programming. And I just really don't have time to go through that before the exam. So this will be my last video before the exam. For those who will be taking the test next year, I will have HL up and ready to go. And potentially some other like just examples, some of their like option D examples. I'm planning on making a recursion video as well. But for those of you who have followed me or have used my videos, I'm happy to have been able to help. And good luck on the rest of your exams.