Chapter 9 Advanced Class Design Notes Flashcards
Advanced Class Design
Creating Abstract Classes
test
INTRODUCING ABSTRACT CLASSES
- An
abstract class
is a class that cannot be instantiated and may contain abstract methods. - An
abstract method
is a method that does not define an implementation when it is declared. - Both abstract classes and abstract methods are denoted with the abstract modifier.
abstract class Bird { public abstract String getName(); public void printName() { System.out.print(getName()); } } public class Stork extends Bird { public String getName() { return "Stork!"; } public static void main(String[] args) { new Stork().printName(); } }
In particular, the Stork class must now override the abstract getName() method.
For example, the following implementation does not compile because Stork does not override the required abstract getName() method:
public class Stork extends Bird {} // DOES NOT COMPILE
An abstract class is most commonly used when you want another class to inherit properties of a particular class, but you want the subclass to fill in some of the implementation details.
OVERRIDE VS. IMPLEMENT
- Oftentimes, when an abstract method is overridden in a subclass, it is referred to as implementing the method.
- It is described this way because the subclass is providing an implementation for a method that does not yet have one.
- While we tend to use the terms implement and override interchangeably for abstract methods, the term override is more accurate.
- When overriding an abstract method, all of the rules you learned about overriding methods in Chapter 8 are applicable.
An abstract class can be initialized, but only as part of the instantiation of a nonabstract subclass.
DEFINING ABSTRACT METHODS
- An abstract class may include nonabstract methods, in this case with the printName() method.
- In fact, an abstract class can include all of the same members as a nonabstract class, including variables, static and instance methods, and inner classes.
- As you will see in the next section, abstract classes can also include constructors.
- One of the most important features of an abstract class is that it is not actually required to include any abstract methods. For example, the following code compiles even though it doesn’t define any abstract methods:
public abstract class Llama { public void chew() {} }
- Although an abstract class doesn’t have to declare any abstract methods, an abstract method can only be defined in an abstract class (or an interface, as you will see shortly)
public class Egret { // DOES NOT COMPILE public abstract void peck(); }
- Like the final modifier, the abstract modifier can be placed before or after the access modifier in class and method declarations, as shown in this Tiger class:
abstract public class Tiger { abstract public int claw(); }
- There are some restrictions on the placement of the abstract modifier. The abstract modifier cannot be placed after the class keyword in a class declaration, nor after the return type in a method declaration. The following Jackal and howl() declarations do not compile for these reasons:
public class abstract Jackal { // DOES NOT COMPILE public int abstract howl(); // DOES NOT COMPILE }
> [!NOTE]
It is not possible to define an abstract method that has a body, or default implementation.
You can still define a method with a body—you just can’t mark it as abstract.
As long as you do not mark the method as final, the subclass has the option to override an inherited method.
cannot define body or default implementation for abstract method
Constructors in Abstract Classes
Even though abstract classes cannot be instantiated, they are still initialized through constructors by their subclasses. For example, does the following program compile?
abstract class Bear { abstract CharSequence chew(); public Bear() { System.out.println(chew()); // Does this compile? } } public class Panda extends Bear { String chew() { return "yummy!"; } public static void main(String[] args) { new Panda(); } }
Using the constructor rules you learned in Chapter 8, the compiler inserts a default no-argument constructor into the Panda class, which first calls super() in the Bear class. The Bear constructor is only called when the abstract class is being initialized through a subclass; therefore, there is an implementation of chew() at the time the constructor is called. This code compiles and prints yummy! at runtime.
For the exam, remember that abstract classes are initialized with constructors in the same way as nonabstract classes. For example, if an abstract class does not provide a constructor, the compiler will automatically insert a default no-argument constructor.
The primary difference between a constructor in an abstract class and a nonabstract class is that a constructor in abstract class can be called only when it is being initialized by a nonabstract subclass. This makes sense, as abstract classes cannot be instantiated.
Invalid Abstract Method Declarations
public abstract class Turtle { public abstract long eat() // DOES NOT COMPILE public abstract void swim() {}; // DOES NOT COMPILE public abstract int getAge() { // DOES NOT COMPILE return 10; } public void sleep; // DOES NOT COMPILE public void goInShell(); // DOES NOT COMPILE }
- The first method,
eat()
, does not compile because it is markedabstract
but does not end with as semicolon (;). - The next two methods,
swim()
andgetAge()
, do not compile because they are markedabstract
, but they provide an implementation block enclosed in braces ({}). - The next method,
sleep
, does not compile because it is missing parentheses, (), for method arguments. - The last method,
goInShell()
, does not compile because it is not markedabstract
and therefore must provide a body enclosed in braces. -
For the exam, remember that an
abstract
method declaration must end in a semicolon without any braces.
Invalid Modifiers
In this section, we review the abstract modifier and which modifiers it is not compatible with.
abstract and final Modifiers
- If you mark something
abstract
, you are intending for someone else to extend or implement it. - But, if you mark something
final
, you are preventing anyone from extending or implementing it. - These concepts are in direct conflict with each other.
Due to this incompatibility, Java does not permit a class or method to be marked both abstract
and final
. For example, the following code snippet will not compile:
public abstract final class Tortoise { // DOES NOT COMPILE public abstract final void walk(); // DOES NOT COMPILE }
The exam doesn’t tend to use final
modifiers on classes or methods often, so if you see them, make sure they aren’t used with the abstract
modifier.
abstract and private Modifiers
- A method cannot be marked as both
abstract
andprivate
. - This rule makes sense if you think about it.
- How would you define a subclass that implements a required method if the method is not inherited by the subclass?
- The answer is you can’t, which is why the compiler will complain if you try to do the following:
public abstract class Whale { private abstract void sing(); // DOES NOT COMPILE } public class HumpbackWhale extends Whale { private void sing() { System.out.println("Humpback whale is singing"); } }
- In this example, the abstract method sing() defined in the parent class Whale is not visible to the subclass HumpbackWhale.
- Even though HumpbackWhale does provide an implementation, it is not considered an override of the abstract method since the abstract method is not inherited.
- The compiler recognizes this in the parent class and reports an error as soon as private and abstract are applied to the same method.
If we changed the access modifier from private to protected
in the parent class Whale, would the code compile? Let’s take a look:
public abstract class Whale { protected abstract void sing(); } public class HumpbackWhale extends Whale { private void sing() { // DOES NOT COMPILE System.out.println("Humpback whale is singing"); } }
In this modified example, the code will still not compile, but for a completely different reason. If you remember the rules for overriding a method, the subclass cannot reduce the visibility of the parent method, sing(). Because the method is declared protected in the parent class, it must be marked as protected or public in the child class. Even with abstract methods, the rules for overriding methods must be followed.
test
> [!NOTE]
While it is not possible to declare a method abstract and private
,
it is possible (albeit redundant) to declare a method final and private
.
test
abstract and static Modifiers
- A static method cannot be overridden.
- It is defined as belonging to the class, not an instance of the class.
- If a static method cannot be overridden, then it follows that it also cannot be marked abstract since it can never be implemented. For example, the following class does not compile:
abstract class Hippopotamus { abstract static void swim(); // DOES NOT COMPILE }
For the exam, make sure you know which modifiers can and cannot be used with one another, especially for abstract classes and interfaces.
CREATING A CONCRETE CLASS
- An
abstract
class becomes usable when it is extended by a concrete subclass. - A concrete class is a nonabstract class.
- The first concrete subclass that extends an
abstract
class is required to implement all inherited abstract methods. - This includes implementing any inherited abstract methods from inherited interfaces, as we will see later in this chapter.
- When you see a concrete class extending an abstract class on the exam, check to make sure that it implements all of the required abstract methods.
REVIEWING ABSTRACT CLASS RULES
Abstract Class Definition Rules
1. Abstract classes cannot be instantiated.
2. All top-level types, including abstract classes, cannot be marked protected
or private
.
3. Abstract classes cannot be marked final
.
4. Abstract classes may include zero or more abstract and nonabstract methods.
5. An abstract class that extends another abstract class inherits all of its abstract methods.
6. The first concrete class that extends an abstract class must provide an implementation for all of the inherited abstract methods.
7. Abstract class constructors follow the same rules for initialization as regular constructors, except they can be called only as part of the initialization of a subclass.
Abstract Method Definition Rules
Abstract Method Definition Rules
1. Abstract methods can be defined only in abstract classes or interfaces.
2. Abstract methods cannot be declared private
or final
.
3. Abstract methods must not provide a method body/implementation in the abstract class in which they are declared.
4. Implementing an abstract method in a subclass follows the same rules for overriding a method, including covariant return types, exception declarations, etc.
Implementing Interfaces
- Although Java doesn’t allow multiple inheritance of state,
- it does allow a class to implement any number of
interfaces
. - An
interface
is an abstract data type are that declares a list ofabstract
methods that any class implementing the interface must provide. - An
interface
can also includeconstant variables
. - Both
abstract methods and constant variables
included with aninterface
are implicitly assumed to bepublic
.
INTERFACES AND NONABSTRACT METHODS
- For the 1Z0-815 exam, you only need to know about two members for
interfaces
:abstract methods
andconstant variables
. - With Java 8,
interfaces
were updated to includestatic
anddefault methods
. - A
default method
is one in which theinterface
method has a body and is not marked abstract. - It was added for backward compatibility, allowing an older class to use a new version of an interface that contains a new method, without having to modify the existing class.
- In Java 9, interfaces were updated to support
private
andprivate static methods
. - Both of these types were added for code reusability within an interface declaration and cannot be called outside the interface definition.
- When you study for the 1Z0-816 exam, you will need to know about other kinds of interface members.
- For the 1Z0-815 exam, you only need to know about abstract methods and constant variables.
DEFINING AN INTERFACE
public abstract interface CanBurrow { public abstract Float getSpeed(int age); public static final int MINIMUM_DEPTH = 2;
public
ordefault
(package-private) access modifier- Implicit modifier (
abstract
) interface
keyword- Interface name
- Implicit modifiers (
public abstract
) - Abstract interface method - Implicit modifiers (
public static final
) - Interface variable
One aspect of an interface declaration that differs from an abstract class is that it contains implicit modifiers. An implicit modifier is a modifier that the compiler automatically adds to a class, interface, method, or variable declaration.
public abstract interface WalksOnTwoLegs {}
- It compiles because interfaces are not required to define any methods.
- The abstract modifier in this example is optional for interfaces, with the compiler inserting it if it is not provided.
public class Biped { public static void main(String[] args) { var e = new WalksOnTwoLegs(); // DOES NOT COMPILE } } public final interface WalksOnEightLegs {} // DOES NOT COMPILE
- The first example doesn’t compile, as
WalksOnTwoLegs
is aninterface
and cannot be instantiated. - The second example, WalksOnEightLegs, doesn’t compile because interfaces cannot be marked as
final
for the same reason that abstract classes cannot be marked as final. In other words, marking an interface final implies no class could ever implement it.