Discussion 6: Inheritance
Today’s discussion focuses on inheritance, a powerful concept in object-oriented programming. You’ll dive into the details of class inheritance by considering the perspective of a superclass from that of a subclass, allowing you to uniquely appreciate how classes interact. In the second half of the discussion, you’ll explore some additional Java features that can enhance your coding (and debugging) applications.
Learning Outcomes
- Explain the object-oriented principle of encapsulation and its benefits. Evaluate the appropriateness of encapsulation in provided code.
- Given a parent class, use inheritance to develop one or more child subclasses.
- Determine the correct visibility modifier (
public,protected, orprivate) for a given field or method and justify your choice. - Explain the concept of immutability and its relation to the
finalkeyword in Java. - Contrast the
==operator and theequals()method, and determine the appropriate one for a given scenario.
Exercise 1:
Reverse Engineering a Superclass
Imagine you're creating a music library app in Java, and while you're working, your IntelliJ crashes. When you open the IDE back up, you see that some of the code is missing. In particular, while you're able to fully recover your work in the
Playlist class, its only superclass, SongCollection, is missing. Luckily, you remember that there were three methods in SongCollection, one of which was abstract, and a constructor. Using the saved code in Playlist, and your knowledge about inheritance in Java, try to piece together the lost methods to fully recover your progress.
Playlist.java
Playlist.java
(a)
The first line of the
Playlist constructor must be a call to the superclass constructor. Why does Java require this?
(b)
Which fields and methods appear to be used in
For this code to compile, where must they be initialized?
Playlist without initialization?For this code to compile, where must they be initialized?
(c)
What visibility modifier must these methods and fields have? Specifically for fields, is this a potential concern? Explain why or why not.
Regardless of your conclusion, keep the implementation as is.
Regardless of your conclusion, keep the implementation as is.
(d)
Would your answer to the above change if the fields were
final?
(e)
Take a look at the method headers: some have an
@Override tag while others do not. What does this mean for methods in the superclass?
(f)
Recall that one of the methods in
Hint: think about which method should have "default" behavior for all types of
SongCollection was abstract. Since Playlist is not abstract, you know that one of the overridden methods must be abstract in the superclass. Which method would this be?Hint: think about which method should have "default" behavior for all types of
SongCollections.
Exercise 2:
Implementing the
SongCollection Superclass
Using your answers to the previous exercises, re-code the implementation of
SongCollection. You may ignore Javadoc comments. Some Song methods that you may find helpful are listed at the end of this handout.
SongCollection.java
Exercise 3:
Adding
toString() and equals() Methods
Having recovered the superclass, you can now continue coding in the subclass.
(a)
Implement a
toString() method in the Playlist class. This method should return a string in the following template: "Playlist {title}: Featuring {song title} by {artist name}", where the title and artist are for the first song in the playlist, and can be accessed with the Song methods getTitle() and getArtist().
(b)
Why does the above method include an
@Override tag, when there is no toString() method defined in the SongCollection superclass?
(c)
Implement an
equals() method in the Playlist class, as specified.
(d)
Why do we need to cast the
obj variable?
(e)
Explain why we should not use
== when comparing if two Playlists contain the same songs and length.
Exercise 4:
Dealing with Exceptions - Time Permitting
You now decide to add a "clean playlist" feature, which finds clean replacements for every explicit song in a playlist. Since this is a feature specific to playlists, you implement it in the
Playlist class, under the cleanPlaylist() method.
(a)
To extract the maximal surplus value from the consumer, you decide to make this a paid feature. Specifically, if this method is called from a user that doesn't have a premium subscription, it must throw a
PremiumFeatureException (which extends Exception). Assume that you've already implemented a method getPremiumStatus() in the superclass SongCollection that returns true if the user has premium, otherwise false. You may find the Song method clean() helpful.
(b)
You'd like to make a
However, this code will not compile. What are two ways of changing the above code so that it compiles successfully? Explain why both changes work.
main() method demo of the cleanPlaylist() feature, and you write the following code:
The Song Interface
Song.java