Chapter 8 Class Design Notes Flashcards
Inheritance
Inheritance
is the process by which a subclass
automatically includes any public
or protected
members
of the class, including primitives
, objects
, or methods
, defined in the parent class
.
When one class inherits from a parent class, all public
and protected members
are automatically available as part of the child class.
Package-private members
are available if the child class is in the same package
as the parent class.
private members
are restricted to the class they are defined in and are never available via inheritance
. This doesn’t mean the parent class doesn’t have private members that can hold data or modify an object; it just means the child class has no direct reference to them.
- Subclass includes any
public
orprotected members
defined in the parent class Package-private members
are available if the child class is in thesame package
as the parent class.private members
are restricted to the class they are defined in and arenever available via inheritance
.
inheritance is transitive
If child class X inherits from parent class Y, which in turn inherits from a parent class Z, then class X would be considered a subclass, or descendant, of class Z. By comparison, X is a direct descendant only of class Y, and Y is a direct descendant only of class Z.
SINGLE VS. MULTIPLE INHERITANCE
Java supports single inheritance, by which a class may inherit from only one direct parent class. Java also supports multiple levels of inheritance, by which one class may extend another class, which in turn extends another class. You can have any number of levels of inheritance, allowing each descendant to gain access to its ancestor’s members.
Java does allow one exception to the single inheritance rule that you’ll see in Chapter 9—a class may implement multiple interfaces.
- Java support single inheritance
- Java also support multiple levels of inheritance.
- A class may implement multiple interfaces
How to prevent a class from being extended?
It is possible in Java to prevent a class from being extended by marking the class with the final
modifier.
If you try to define a class that inherits from a final class, then the class will fail to compile.
INHERITING OBJECT
- In Java, all classes inherit from a single class:
java.lang.Object, or Object
for short. - The key is that when Java sees you define a class that doesn’t extend another class, it automatically adds the syntax
extends java.lang.Object to the class definition.
- Object is alway no top of the inhert tree.
Defining and extending a class
public abstract class ElephantSeal extends Seal { // Methods and Variables defined here }
public
ordefault (package-private)
access modifierabstract
orfinal
keyword (optional)class
keyword (required)- Class name (required)
extends
parent class (optional)
EXTENDING A CLASS
public class Animal { private int age; protected String name; public int getAge() { return age; } public void setAge(int newAge) { age = newAge; } } public class Lion extends Animal { public void setProperties(int age, String n) { setAge(age); name = n; } public void roar() { System.out.print(name + ", age " + getAge() + ", says: Roar!"); } public static void main(String[] args) { var lion = new Lion(); lion.setProperties(3, "kion"); lion.roar(); } }
the Lion program prints the following: kion, age 3, says: Roar!
Cannot access private variable
public class Lion extends Animal { ... public void roar() { System.out.print("Lions age: "+age); // DOES NOT COMPILE } ... }
APPLYING CLASS ACCESS MODIFIERS
Top-level class
can only have public
or default (package-private)
access modifier
> [!NOTE:]
An inner class is a class defined inside of another class and is the opposite of a top-level class. In addition to public and package-private access, inner classes can also have protected and private access. We will discuss inner classes in Chapter 9.
As you might recall, a Java file can have many top-level classes but at most one public top-level class. In fact, it may have no public class at all. There’s also no requirement that the single public class be the first class in the file. One benefit of using the package-private access is that you can define many classes within the same Java file.
Inner class
can havepublic, protected, default (package-private) and private
access modifier.- java file can have many
top-level
classes but at most onepublic top-level class
. - One benefit of using the
package-private
access is that you can define many classes within the same java file.
> [!NOTE:]
For simplicity, any time you see multiple public classes or interfaces defined in the same code sample in this book, assume each class is defined in its own Java file.
test
ACCESSING THE THIS
REFERENCE
- The
this
reference refers to the current instance of the class and can be used to access any member of the class, including inherited members. - It can be used in any
instance method, constructor, and instance initializer block
. - It cannot be used when there is no implicit instance of the class, such as in a
static method or static initializer block
.
What do you think the following program prints?
public class Flamingo { private String color; public void setColor(String color) { color = color; } public static void main(String... unused) { Flamingo f = new Flamingo(); f.setColor("PINK"); System.out.println(f.color); } }
Output:
null
The assignment completes successfully within the method, but the value of the instance variable color is never modified and is null when printed in the main() method.
public void setColor(String color) { this.color = color; }
The this
reference refers to the current instance of the class and can be used to access any member of the class, including inherited members. It can be used in any instance method, constructor, and instance initializer block. It cannot be used when there is no implicit instance of the class, such as in a static method or static initializer block.
1: public class Duck { 2: private String color; 3: private int height; 4: private int length; 5: 6: public void setData(int length, int theHeight) { 7: length = this.length; // Backwards – no good! 8: height = theHeight; // Fine because a different name 9: this.color = "white"; // Fine, but this. not necessary 10: } 11: 12: public static void main(String[] args) { 13: Duck b = new Duck(); 14: b.setData(1,2); 15: System.out.print(b.length + " " + b.height + " " + b.color); 16: } }
This code compiles and prints the following:0 2 white
How do we reference the version in the parent class instead of the current class?
To achieve this, you can use the super
reference or keyword.
ex:
class Mammal { String type = "mammal"; } public class Bat extends Mammal { String type = "bat"; public String getType() { return super.type + ":" + this.type; } public static void main(String... zoo) { System.out.print(new Bat().getType()); } }
The program prints mammal:bat
What does the following program output?
1: class Insect { 2: protected int numberOfLegs = 4; 3: String label = "buggy"; 4: } 5: 6: public class Beetle extends Insect { 7: protected int numberOfLegs = 6; 8: short age = 3; 9: public void printData() { 10: System.out.print(this.label); 11: System.out.print(super.label); 12: System.out.print(this.age); 13: System.out.print(super.age); 14: System.out.print(numberOfLegs); 15: } 16: public static void main(String []n) { 17: new Beetle().printData(); 18: } 19: }
That was a trick question—this program code would not compile!
line 13 does not complie.
while this
includes current and inherited members, super
only includes inherited members.
Constructors Rules
- a constructor is a special method that
matches the name of the class
and hasno return type
. - Like method parameters, constructor
parameters
can be any valid class, array, or primitive type, including generics,but may not include var
. - A class can have multiple constructors, so long as each
constructor has a unique signature.
(constructor parameters must be distinct
.) - During compilation, java generate default no-argument constructor if a class is declared without any constructors.
- default constructor has an empty parameter list and an empty body.
Can you tell why these two are not valid constructors for the Bunny class?
public class Bunny { public bunny() { } // DOES NOT COMPILE public void Bunny() { } }
The first one doesn’t match the class name because Java is case sensitive.
The second method is a perfectly good method but is not a constructor because it has a return type.
The following does not compile:
class Bonobo { public Bonobo(var food) { // DOES NOT COMPILE } }
Like method parameters, constructor parameters can be any valid class, array, or primitive type, including generics, but may not include var
.
Constructor Overloading
A class can have multiple constructors, so long as each constructor has a unique signature
. In this case, that means the constructor parameters must be distinct. Like methods with the same name but different signatures,
declaring multiple constructors with different signatures is referred to as constructor overloading.
ex:
public class Turtle { private String name; public Turtle() { name = "John Doe"; } public Turtle(int age) {} public Turtle(long age) {} public Turtle(String newName, String... favoriteFoods) { name = newName; } }
DEFAULT CONSTRUCTOR
Every class in Java has a constructor
whether you code one or not. If you don’t include any constructors in the class, Java will create one for you without any parameters. This Java-created constructor is called the default constructor and is added anytime a class is declared without any constructors. We often refer to it as the default no-argument constructor for clarity.
It is only in the compiled file with the .class extension that it makes an appearance.
> [!NOTE:]
Having only private constructors in a class tells the compiler not to provide a default no-argument constructor.
It also prevents other classes from instantiating the class.
This is useful when a class has only static methods
or the developer wants to have full control of all calls to create new instances of the class.
Remember, static methods in the class, including a main() method, may access private members, including private constructors.
test
CALLING OVERLOADED CONSTRUCTORS WITH THIS()
public class Hamster { private String color; private int weight; public Hamster(int weight) { // First constructor this.weight = weight; color = "brown"; } public Hamster(int weight, String color) { // Second constructor this.weight = weight; this.color = color; } }
Constructors can be called only by writing new
before the name of the constructor.
Cannot call constructor like normal method.
public Hamster(int weight) { Hamster(weight, "brown"); // DOES NOT COMPILE }
When this()
is used with parentheses, Java calls another constructor on the same instance of the class.
public Hamster(int weight) { this(weight, "brown"); }
this() rule
Calling this() has one special rule you need to know. If you choose to call it, the this()
call must be the first statement in the constructor
. The side effect of this is that there can be only one call to this() in any constructor.
ex:
3: public Hamster(int weight) { 4: System.out.println("in constructor"); 5: // Set weight and default color 6: this(weight, "brown"); // DOES NOT COMPILE 7: }
Consider the following definition of the Gopher class:
public class Gopher { public Gopher(int dugHoles) { this(5); // DOES NOT COMPILE } }
The compiler is capable of detecting that this constructor is calling itself infinitely
.
Since this code can never terminate, the compiler stops and reports this as an error
.