[MUSIC] What we've learned in the first course, and so far in this one, falls within the category of procedural programming. We've organized our code into functions, typically creating a main function that utilizes helper functions to compute whatever it needs, and then returns the results to the command window. The data that our programs have worked on have been passed around as function arguments, and have been stored in local variables, and in a few rare cases, in global ones. This approach has worked just fine for us, mainly because the programs and exercises in this course are all necessarily small and relatively easy to comprehend. What happens if we have to write large complex programs? Does this approach scale well? The answer is sadly, no. Procedural programming focuses on the operations that a program needs to carry out. But as the size and complexity of the program grows, it becomes more and more difficult to manage the data that the program works on. Modern computer programs today consist of many tens of thousands or even millions of lines of code. Having only local and global variables and function argument at our disposal, makes it harder to keep track of the data. Harder to make sure that we don't make unintended changes to the data, and harder to understand and modify existing programs that process the data. Object Oriented Programming, commonly abbreviated as OOP, was invented to help with all these problems. And we're going to look at Object Oriented Programming in this lesson. Before we dig in though, we need to set your expectations. Object Oriented Programming is typically taught as a semester long course in college. Also there are many long books on the topic. What we can do here in a single lesson, is introduce the basic concepts, and show you how they work in MATLAB. If we managed to pick your interest in the topic, you want to turn to additional resources after this lesson. Object Oriented Programming unlike Procedural Programming, is centered on data as opposed to functions. In the object oriented world, data are stored inside something called an object. Of course in everyday speech, the word object can refer to almost anything, from an apple to a zebra. But you can probably guess from its name, Object Oriented Programming gives the word object a very special meaning. That meaning will not be completely clear until you've seen some examples. But one thing that'll help you get started, is to think of an object as a struct with some extra features. We explained the struct in the seventh lesson of our introductory course, but just to refresh your memory, here's an example. Here by using the struct function, I've given the variable very cool guy, the field name, and the empty array as its value. I didn't use a semicolon to suppress the output. So, MATLAB echoes the contents very cool guy showing it single field and the fields value. Since we're using a version of MATLAB released after 2015, we also get this message telling us that it's a struct. Never thought about this before, but since there's only one field, seems a little awkward that MATLAB says fields here. Maybe I'll drop a note in the suggestion box. Well, now let's name this very cool guy. This time, instead of using the struct function, I've used the dot operator to access to field, and I've assigned the string Mike Fitzpatrick to it. Now, let's add a second field. And there it is, as in Mike Fitzpatrick is my name, professor is my game. That's a very cool guy. But what about that blank space after struct with fields? Do we really need that? Well, that's where suggestion box is anyway. Well, the reason that I said an object is like a struct, is that an object also includes one or more fields. And as a matter of fact, the data that an object contains is stored in those fields. And you can assign values to those fields using the dot operator. So there are definitely similarities. But I also said that an object has extra features. So, what are those? Well, for openers, in addition to data, an object can contain functions for operating on its data. So, functions stored with data. Okay, well, I told you, you got to see some examples to understand objects. And we'll show you lots of examples. But before we do that, we need to nail down some object oriented terminology. First off, an object is stored in a variable. Just like that struct we just saw, was stored in the variable named very cool guy. And like any other variable, it has a type. But unlike the variables that we've worked with up to now, whose types are built into the MATLAB language, like doubles, sales string, structs, and so forth. The type of an object must be defined by the user. And in a typical object oriented programming application, many different types are defined. And to distinguish them from built in types, user defined types are called classes. And to define a class, we use a new keyword named classdef, c-l-a-s-s-d-e-f. So without further ado, let's write our first class definition. If you're starting from scratch, you can click the new icon and select class. You'll get a template to work with. But for a newbie, it's kind of complicated, and we want to start simple. To do that, let's open this m file that we've prepared for you, named contact underscore v1. Before we talk about it, I'm going to save it with a simpler name, Contact.m. There, and I'll close contact underscore v1. The v1 means version one of our examples, and you can see that we have quite a few versions to show you Now we can talk about it. We're looking at a definition of a class for storing people's contact information. And to keep it simple, it includes only first names, last names, and phone numbers. As you can see, a class definition starts out with that keyword classdef. And it's followed by the name of the class that we want to define, which in this case is contact. And we follow the object oriented convention of starting the name of the class that we're defining with an uppercase letter. The reason that I quickly saved this file with the name contact, is that a class definition is legal only if it's defined in an m file, and only if that m file has the same name as the class. Inside our contact class, we've added three properties after the key word properties. Each property is a data field just like the fields in a struct. And here again, we've started the property names with uppercase letters, and we've used uppercase letters inside the names to highlight where new words begin. This capitalization approach is a good habit to get into. And we'll continue doing that throughout this lecture. And we added a couple of end keywords at the proper places to mark the end points of the list of properties and of the class definition itself. Okay, you've seen how easy it is to create a class. You just use class def with the class name to write its definition in an M file, and then save the M file with the name of the class. And now I bet you'd like to see how to create an object to this class. That's even easier. At first, it might seem that this command just assigns a copy of the class named contact to a variable named person. But that is not what this command does. In fact, it's not even possible to assign a class to a variable. Instead, this command creates an object of the class contact and assigns that object to the variable person. And during the creation of that object, MATLAB assigned a value to each one of the objects properties. And the value it chose was the empty array. Why did it assign the empty array to the properties, even though the user has put nothing in there yet? Well, it did that because every property of every object must have a value at all times. And nothing says there's nothing here like an empty array. Of course, empty arrays and not the best values for names and phone numbers. So we need to get busy assigning them the values that we want them to have. Now we can do that in just the same way that we assign values to fields of the struct, very cool guy. Let's rearrange the desktop and then start with the first property. And let's repeat this approach for the other two properties. Well issuing multiple commands to create an object and then assign values to each of its properties certainly works. But it's cumbersome, especially if we have a lot of properties and need to set them for a lot of objects. Well, we can get this work done with just one command that creates an object and gives values to its properties, if we introduce a couple more features. The first feature is something we've already alluded to, and that is that we can add functions to an object. We do it by putting function definitions inside the definition of the objects class. This function definitions appeared a new section of the class which is introduced by the key word methods. The word methods is used because in MATLAB a function defined inside a class is called a method. The name is not unique to MATLAB. In fact, it's older than MATLAB itself. The name method was the name first used for functions defined in a class way back in the 1960s, when object oriented programming was introduced in a programming language named SIMULA. In more recent languages like C++ and Java, a class function is called a member function. But you're safe with either terminology. When people talk about object oriented programming there's likely to use method as member function. That's our first example of a method. We're going to introduce another feature of object oriented programming. The constructor. A constructor is exactly what we need to avoid the cumbersome approach of adding values one by one to the properties of an object after we create it. A constructor is a method that creates an object and gives values to its properties at the same time. Let's add a constructor to our contact class As promised, we've introduced the methods section, with the keyword methods. To define a function in the methods section, we start as usual with the function keyword and conclude with the keyword end. The function signature has a usual form argument list, equal sign, function name and formal input arguments in parentheses. So far we've defined only one method for this class and its name is the same as the name of the class, contact. Usually a method does not have the same name as its class, but this function is a constructor. And a constructor must have the same name as the class it's defined in. The output of a constructor is the new object that it creates. And in the body of that constructor, it builds that object and assigns it to its formal output argument, which we've named OBJ. This constructor has three formal input arguments, lname, fname, and phone. But there is no restriction on the number of formal arguments, and it can in fact, use the argument again so that it can be called with any number of actual arguments. In that sense it's just like an ordinary function. But the possibility of having varying numbers of actual arguments is especially important for constructors. Because unlike most object oriented programming languages, in MATLAB, a class can have only a single constructor. Notice how we access a property of the object is no different from a struct, we use the dot operator. The first operand is the variable that holds the object, which in this case is obj, and the second operand is the property name. MATLAB does not allow you to use a property name by itself. That's also consistent with the way a struct works. But most other object-oriented languages do allow it. And those languages also provide a keyword to access the current object, while MATLAB does not. If you've programmed in another object oriented language, you know what I'm talking about, and you just have to get used to this different approach. It's not a big deal. But if not, then you don't have to break any habits. Well, let's create a new object with our shiny new constructor. It's really nice that we can create and properly initialize a new object with a single call to the class constructor method. If we look at the constructor code again, an added benefit is that we can also control the data types of the properties in the constructor. As you can see, we make sure that each property of the contact class is a string. Note how we use a double for the phone number when we call the constructor. But the property itself becomes a string because we make sure of that and the constructor method. Still at this point, this is not much different from a struct. So what's the big deal about classes and object oriented programming? Well, let's consider a problem with our current class. If I wanted to modify our property, I could do it without restrictions and I could mess up the object. A number for a last name doesn't make sense. And even worse, it can break other parts of our program later since we assume it was a string. You might say of course that I would not make a mistake of assigning a number for last name. Just imagine if you're writing a large program with tens of thousands of lines of code, maybe hundreds of classes, and thousands of instances. Some of the classes you didn't even write, other team members might have implemented them, or maybe you're using freely available software libraries. Are you sure that you're going to remember every assumption, about every property, of every class in that case? Not likely. So it's much better to design classes for which users of the class cannot violate the assumptions. That's actually one of the reasons object oriented programming was invented. So in our simple case, how can we prevent somebody from accidentally changing the last name to a number? Well, we add a special kind of method to the object called an Access method. If we do that, and when someone tries to access the property for which we've created this Access method, MATLAB will silently call our method instead of letting the caller have direct access. Let's write our first access method. This is a set access method for the last name property, also known as a property set method. The syntax is a bit unusual. The method name must be set dot property name. The first input argument must be the object itself, and it must be the output argument as well. The second input argument is the new value that we're going to assign to the property. As far as our implementation is concerned, we do what we did in the constructor. We set the last name property to the new value, making sure that it's a string. Let's try it. I tricked you. You're not allowed to use an access method directly. The whole point is that when someone tries to assign a new value to the property by using the dot operator, MATLAB will check to see whether there is a set access method for this property. And this access function will get called automatically. Well, we changed the last name. How do we know that our set access method was called? Let's try to assign pi as the last name again. It might not be obvious at first, but our access method did its job. The last name property is not pi, it's the string 3.1416 which is what the string function produces when you give it the argument, pi. Of course, we could go further with our access method and have it checked to determine whether someone tries to assign a number to the last name property and send an error back if they do. But for our simple case, we'll just leave it as it is. Now I want to show you a pitfall so you can avoid falling into it. Let's make a simple mistake in our access method. I used an underscore as opposed to a period, in the name of the method. Let's see what happens if I try to use it. Yep, we're back to having a number for last name. The point is this, when you create an access method, you need to make sure that it is indeed working and being called. One way is to set a break point inside. So let's set our method back to the way it's supposed to be, And put a break point in it and see what happens. As you can see, we are indeed inside the access method. Okay, let's add access methods to the rest of the properties. So here's the latest version of the class. We can also provide get access methods to our properties. Which are also known as property get methods. Now, for our simple contact class, this is not really necessary. Here's the syntax to show how we would do it. The method name is get dot property name. The single input argument is the object. And the single output argument contains the value of the property that we're returning. Get access methods are called whenever we query the value of a property. For example, But how do we check to see whether this get access method is actually being called? Well, we can use a break point again. Or we can temporarily modify the method say like this. And you can see that it worked. While set access methods are frequently used, get access methods, not so much. We won't use them for our contact class either. So where are we? We have a nice contact class that allows us to create objects as instances of it. These contact objects each have properties for storing the first and last names of persons as well as their phone numbers. Well, what if we wanted to store not just personal contact information, but business information too. Our existing contact class wouldn't work for that because every business contact needs a property to hold the company name. And the contact class doesn't have one. We could add a company name property, of course, but it wouldn't get used for personal contacts, so we'd have a wasted slot sitting there empty for all of them. And it's not ideal for another reason too. We might want slightly different behavior for personal contacts from business contacts. So what do we do? Well, another option would be to create a brand new business contact class by copying the contact class, adding a property to the copy and renaming it. But there's a disadvantage to that too. Because if we make some improvements to the way that contact class handles its names and the phone number and to get those changes into the business contact class. We'd have to copy him into it. This situation's not so likely with our simple Contact class, but happens a lot with more complex classes. Wouldn't it be wonderful if we were able to create a new BusinessContact class that incorporates properties of the existing Contact class that are relevant to its purposes without any copying? Are you kidding? It's a piece of cake, walk in the park, day at the beach. Because one of the most important features of object oriented programming is that one class can build on another class. And that feature even has a name, it's called inheritance. We can create a new class and specify that it is, indeed, a new modified or derived version of another class. Such a class is called a subclass, and it inherits all the properties and methods of its super class. Which, somewhat confusingly, is also called a base class. It can modify methods that it inherits, and it can add its own properties and methods, as well. Well, what are we waiting for? Let's create a new BusinessContact class from the existing Contact class. As you can see, all we had to do is use the less than character followed by the name of the existing class. Then we simply added two new properties, company for the company name, and fax for the fax number. Yeah, I know, fax machines are dinosaurs. But believe it or not, many companies still have them. But that was easy, now let's create our first business class instance. Clean up on aisle nine, let's see what we got here. Okay, that's the constructor of the Contact class. It's expecting inputs, and we didn't give any. Well, wait a minute, before we solve that problem, how did we get to the constructor of the Contact class when we were constructing a BusinessContact object? Well, a BusinessContact is a subclass of the super class Contact. And whenever MATLAB creates an instance of a subclass, it needs to create an instance of the super class first. Remember the subclass gets all the properties of the super class, and the way that happens is that the super class object becomes kind of a part of the subclass object. And when you try to create a subclass instance, MATLAB first calls the super class constructor, which in this case is Contact. And that Contact constructor has three input arguments. So we had better supply them or get ready to face a sea of red. But just like with a Contact class, it would be better if we had a constructor that also initialized the company name and the fax number at once. Let's do that. And let's test it. Hm, we just cannot seem to keep aisle nine clean. What's the problem now? Well, we just discussed the super class constructor will be called by MATLAB. But it expects three input arguments. In this case we've not told MATLAB what arguments it should use, so it uses none. But our Contact class constructor is not prepared to be call with zero arguments. There are two solutions. First, we should prepare the Contact constructor to be called with zero input arguments. That's actually a good practice independent of this particular issue at hand. So let's go back and modify the Contact constructor. In fact, let's make it able to accept any number of arguments from zero to three. And let's test it. And let's see whether we fixed our BusinessContact constructor issue. Well, that did it. By the way, these aren't really Bill Gates' phone numbers. I'm pretty sure Bill and I have an understanding that he doesn't give out my phone numbers and I don't give out his. The only reason he needs to have my phone number is because he might need to call me up every once in a while to get computer advice. And I'm happy to give it. So what did MATLAB do exactly here? We called the BusinessContact constructor with five arguments. The first thing MATLAB did was call the Contact constructor with zero arguments. Then we set all the properties of the new business class, its own, as well as the ones it inherited from Contact, one by one. I mentioned that there were two solutions to the problem we were having with creating a new BusinessContact instance. What's the second solution? Well, instead of relying on MATLAB to call the super class constructor, why don't we call it ourselves? In that case, we can call it the way we want to. For example, instead of manually setting the last name and the other inherited properties, we can simply call the super class constructor that already does that anyway. Here we got. The syntax is a bit unusual, as you can see. You have to use the at sign operator with the output object and the super class name to call the super class constructor. Then you can supply whatever arguments you want. Most important rule, as far as calling the super class constructor is concerned, is that it must be called before the object variable is used for anything else. Two final improvements to the business class await. Just as we did for the Contact constructor, we should prepare the BusinessContact constructor to be able to accept any number of arguments up to five. Let's do that. And our final tweak to the BusinessContact class is to add set access methods for the new properties. Well, that's the final tweak to the BusinessContact class, but now dad-blast-it, I've thought of a tweak that I should've made to the Contact class. And I should have thought of it before I defined the BusinessContact class, dad-blast-it! What I should've done is add a method for printing the name of the Contact in the command window. And the BusinessContact class could have inherited the dad-blasted thing. Well, better late than never, I'll go ahead and add it now. There it is and, by the way, this is what most ordinary methods look like. By ordinary, I mean that it's not a constructor, which creates a new object and has to have the same name as the class of the object. And it's not an access method, which accesses a property of the object that it's acting on, and whose name has to have a dot in it. For ordinary methods, there's no restrictions on the name. It's first argument automatically gets a copy of the object that it's acting on. And the body of the function is free to access any of the objects properties using the dot operator. Here we've got just one argument, and since it's the first one, it'll get the copy of the object that the method's acting on. And we've used the dot operator to access to properties, FirstName and LastName. And we print withfprintf just as we would with any normal non-method function, And you can call it with a dot operator using operands that are the name of the variable holding the contact object that you want it to act on, and the name of the method, like this. How would you look at that? Even though I created the object in the variable name person way before I added the print name method to the contact class, it's working just fine. This tells you that you can modify a class anytime you want to, and the modifications will ripple out to all its objects old or new. Let's try with person2, he was at anyway. Yeah, that guy. And what about that business contact object that we created, which we stored in the variable b. It's an instance of a subclass of contact. How about that? The ripples keeps spreading, not only to the objects of the class we changed, but to the objects of the subclass. So inheritance works no matter whether we declare a subclass before or after the change to the superclass. Do you see the significance of this ripple effect? The object stored in the variable b is an instance of the business contact class, which we did not change. But since it's a subclass of the superclass Contact, which we did change, the object in b inherits the new method as well as everything else it got when we created it. It's like a child inheriting an estate from a parent. If the estate grows, the child gets richer. So see, if Bill Gates were my child and inherited my estate and then my investments increased in value, and he would gain hundreds of thousands of dollars more. And you can imagine what that would mean. You know what? Nevermind, maybe that's not a great analogy. Let's just say that when you change a class, that change flows out to every object of the class and every object of every subclass for which it served as a superclass. This is a major advantage of inheritance because it maintains consistency without the need to pour through thousands of lines of code looking for places where changes need to be made by hand. And it's another great thing about object-oriented programming. And with the introduction of this great thing, we'll conclude our first lecture on object-oriented programming. And during this lecture we learned that object-oriented programming is data-centered. We learned that the data is contained in a new entity called an object. And that the type of an object is called a class and must be defined by the user. We've learned how to define those classes with the classdef keyword. And we learned that a class keeps its data in a section of the class headed by the keyword properties. Inside that section property names are listed, and those properties behave very similarly to the fields of strux. As for example being accessed via the dot operator. The most surprising and most important thing that we learned is that, in addition to data stored in the fields defined inside the property section, a class can contain functions defined inside a methods section. We learned that those functions are accessible to objects of that class and of its subclasses. And we learned how to define a subclass in terms of another class, which is called SuperClass. Perhaps the most important feature of object oriented programming that we learned about is inheritance, which is the ability of a subclass to receive properties and methods from its superclass. Including those added to the superclass after the subclass has been defined. Finally, we learned how to create three special kinds of methods, the constructor, which assists in the creation of new objects. The set access method which assists in setting values of properties of objects. And the get access method which assists in the retrieving of the values of the properties of objects. So we clearly learned a lot in this one lecture. But as I mentioned in the introduction, we are still only scratching the surface here. There are many rules that control inheritance, constructors, and access methods that we didn't cover. If you want to know more, check out the extensive MATLAB documentation on these issues. For example, if you Google MATLAB constructors, the first link takes you to this page. As you can see, it's quite detailed, and it explains all the rules that govern constructor behavior in MATLAB. Why did I choose this writing? Well, it's probably because I like MATLAB. [MUSIC] You are welcome. [MUSIC]