Easy-to-follow video tutorials help you learn software, creative, and business skills.Become a member
In previous videos, I showed examples of creating inheritance patterns with concrete superclasses and with interfaces. There is another option in Java called an abstract class. Abstract classes combine the best of the other two options. Like concrete superclasses, they can have fully implemented methods that they can share with their subclasses, but like interfaces, they typically aren't instantiated directly, so they can create a better programming contract. I'm starting in a version of the Olive Press application that has a concrete superclass named Olive. To change it to an abstract class I'll add the keyword abstract after the public access modifier, but before the keyword class. Nothing has changed so far in the functionality of this application. I'll save and run the application, and show that it still runs. But the reason there are no functional changes yet is because I'm not trying to instantiate the Olive class directly. Going back to the Main class, I'll show that I am instantiating the subclasses: Kalamata, Ligurian, and Kalamata again. Watch what happens when I try to instantiate Olive directly. I will move the cursor down to the end of the Main method, and I will add a line of code that declares a new variable. I will set the data type as Olive, and I will name it olive2, and I will instantiate it with new Olive, the constructor method. When I save my changes, I get the error message, Cannot instantiate the type Olive. So when you declare a class as abstract, you can't instantiate it directly, except under certain conditions. I am just going to comment-out this code for the moment, I will come back to it later. The point of using an abstract class as a superclass is that you can create a contract that says all of this abstract classes' subclasses promise to implement some sort of functionality. Here is an example, I will go back to the Olive class and show that it has a method called getOrigin(), which returns a string of Greece. Now because this class is abstract, it can have this concrete implementation, but the reality is that not all olives come from Greece. Some have an origin of Greece, some of Italy, and some of other countries. So I might make the decision that I'm going to implement this method in each of the subclasses; not in the superclass. But I want to make sure that all of the subclasses implement it. So I will change this method to an abstract method. The syntax is just like the class itself, you place the word abstract after the access modifier, and in this case, before the return type. And then, you use the same kind of syntax you would in an interface. I will delete the implementation and add the semicolon at the end of the declaration. I'm now saying that this method must be implemented in all classes that extend this class. Watch what happens when I save my changes. I get errors. The classes Kalamata and Ligurian are extending the abstract class and they must implement all abstract methods. So let's go to each of these classes and fix the problem. I will go to Kalamata, I will place the cursor below all of the other methods but within the class declaration. I will right-click, and choose Source > Override/Implement Methods. This is a trick that most good Java editors will be able to do for you. It will look at the superclass and say, here are the methods that you have not implemented yet. And then it will generate the stub for the method for you. I'll click OK, and I get the new method getOrigin(). The Override directive above the method can be retained if you like. It is optional, but it is a good way of noting that you are implementing a method that was declared in the superclass. I will delete the TODO comment and I will replace the value null with a string of Greece. I will save those changes and now I will go to Ligurian, and I will do the same thing. I will once again make a little bit of space, right-click in the open space, and choose Source > Override/ Implement Methods, once again getOrigin() is checked, and I will click OK. Then I will delete the TODO comment and replace null with Italy, again as a string. I'll save my changes, and all of the errors go away. Now to prove this works correctly, I will go back to Main.java. At the bottom of this code I'm already declaring a variable named olive1, data-typed as Kalamata. I am going to change that so that the data type is the superclass of Olive, and because Olives is a collection of olive objects, I can remove the casting syntax. Then I will copy and paste that code, both the declaration and the output of the getOrigin() method. And I will change the second set to olive2, the name of the variable is olive2. I will change index that I am looking for from 0 to 1, and I will change the string. I will save the changes and run the application, and now I am told that Olive 1 is from Greece, and Olive 2 is from Italy. The magic of this inheritance architecture is that at the top level, I am only designating the type once, when I instantiate each object. But later when I call the method getOrigin(), I know that that method will be there because of the contract created by the abstract class, and I called the correct method because it is implemented as a concrete method in the appropriate subclass. Finally, let's go back to the declaration where I tried to instantiate the superclass directly. I mentioned that you typically don't instantiate abstract classes directly, it is possible to do it though, as long as you satisfy the contract. I will remove this comment, and I am going to recode this. I will backspace over the semicolon and the parenthesis, and then press Control+Space, and I will choose Olive as the constructor method. Notice the notation Anonymous Inner Type. I will double-click to select, and take a look at what Eclipse generates. It allows me to instantiate the Olive class directly, but only if I implement the abstract method getOrigin(). So I am satisfying the contract again, but in a different way. Instead of an explicit subclass, in its own class file, now I am creating a subclass inline as something called an anonymous inner type. I am not actually going to do this in the application, so I will select that code, and then comment it out, save my changes, and run the application one last time. So that is a look at how you can use abstract classes in your inheritance architecture. Again, they combine the best features of interfaces and of concrete superclasses. They support a better programming contract then the concrete superclasses, but have a lot more flexibility and power than interfaces.
Get unlimited access to all courses for just $25/month.Become a member
82 Video lessons · 101382 Viewers
61 Video lessons · 88140 Viewers
71 Video lessons · 71971 Viewers
56 Video lessons · 103796 Viewers
Access exercise files from a button right under the course name.
Search within course videos and transcripts, and jump right to the results.
Remove icons showing you already watched videos if you want to start over.
Make the video wide, narrow, full-screen, or pop the player out of the page into its own window.
Click on text in the transcript to jump to that spot in the video. As the video plays, the relevant spot in the transcript will be highlighted.
Your file was successfully uploaded.