Reading Note for OCP Java SE7 I by Manning Publication, Chapter 6

Note: All tips that is written by book will has a sign near it.
All code example in this post comes from book.

Chapter 6: Working with Inheritance

Inheritance with classes

A class use the keyword extends to inherit another class. This class is called subclass, derived class, extended class or child class. The class that is being inherited is called super class, base class or parent class.

when a class inherites another class, it encloses within it an object of the inherited class. All members of the inherited class are available to its subclass.

A dervied class can inherite all non-private members in its base class.

  • A dervied class can inherite members with default access only when they are in same package.
  • proctected and public memebrs can be inherited from all subclasses.
1
2
3
4
5
6
7
8
class Employee{
String name;
}
class Programmer extends Employee{
void test(){
name = "Programmer";
}
}

A derived class can not inherit:

  • private members in base class.
  • if derived class and base class are in seperate package, default members in not available.
  • constructors of base class can not be inherited, buy can be called.

A derived class can hide or override its base class’s members. If there is any overridden for base class, only overriden methods or variables are available after that.

  • abstract class groups the common properties and behaviors of its derived classes, but it prevents itself from being instantiated.
  • abstract class foraces all derived class to implement individually a certain method, by creating a abstract method. A derived class should implement all abstract methods of its base class.

Use Interfaces

An interface can define only abstract methods and constants. All members of an interface are public by default. You can choose to hide or show public keyword. i.e. abstract methods in interface should be public void or public return_type.

Java allows a class to implment mutiple interface. For example, class test implments t1, t2. t1 and t2 are name of interface here.

A change in interface’s signature can lead the failure of all implemented classes.

The variables in interface are public, final, static by default. You can choose to hide or show these keywords. This means a variable in interface must be assigned a value, and you can not assign value again.

1
2
3
interface Test{
int t = 1; // If you make int t; here, code will not compile.
}

Interface can not write constractors.

Multiple inheritence is not allowed in Java to prevent a subclass trying to implement mutiple methods with same name from different base class.

A class can not inherit multiple classes, but it can implement multiple interfaces.

Reference variable and object types

When you assign an instance of an object to a reference variable, the type of the reference variable can be:

  • Its own type
  • Its corresponding type’s base class
  • Its corresponding type’s implemnted interfaces. In this case, the reference variable can not use members defined in its corrsponding class or super class. i.e. this reference varaible can only access whatever defined in interface.
  • Note: if the corresponding type’s base class implement a interface, this reference variable can not use methods defined in this interface.

The sequence defined above can not be reverse. For example, if a reference variable’s corresponding type is A, its base class is B and its interface is C. You can do C test = new B(); or B test = new A(); Buy you can not do A test = new B() or B test = new C();

Casting

casting is the process of forcefully making a variable behave as a variable of another type. If a class shares an IS-A or inheritance relationship with another class or interface, their variables can be cast to each other’s type.

Using example above, if a reference variable’s corresponding type is A, its base class is B and its interface is C. We can set (A)C.method_name = new String/int/etc/ (B)C.method_name=.... this method must have same return type as the type on right. Inherence sequence must be the same as above.

Use this and super to access objects and constructors

this reference always points to an object’s own instance. Any object can use this reference to refer to its own instance.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Employee{
String name;
Emloyee(String name){
this.name = name;
// this is used here to differ instance variable and local variable
}
Employee(){
name = "test";
}
Employee(String name, String address){
this(name);
//this is used to call a constructor that only accepts name
this.address = address;
}
Employee2(String name){
this();
/*
Call a contructor that does not accept parameters.
Must be the first statement in this method
*/
if(name!=null){this.name = name;}
}
}

super refers to the parent or base class of a class or constructors of the base class in a derived class.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Employee{
String name;
Employee(String name){
this.name = name;
}
}
class Programmer extends Employee{
String name;
String progLanguage;
void setNames(){
//Assign value to base class variable and current class variable
this.name = "Programmer";
super.name = "Employee";
}
Programmer(String name, String progLanguage){
super(name);
this.progLanguage = progLanguage;
/*
super(name) calls the constructor in base class,
which only accepts name as parameter.
super(name) must be the first statement in this derived class constructor.
If this is not alled, a super() will be added by java compiler automatically.
*/
}
}

Since static methods belongs to a class instead of object of a class, you can not use this or super in a static method.

Polymorphism

Ploymorphism comes when a class inherits another class and both the base and derived class define methods with the same method signature(the same method name and method parameters).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
abstract class Employee{
public abstract void startProjectWork(); //Employee does not know how to start a project
}
class Progrmmer extends Employee{
public void startProjectWork(){
System.out.println("coding");
}
}
class QA extends Employee{
public void startProjectWork(){
System.out.println("testing");
}
}

Rules to remember when defining overridden methods:

  • overridden methods are defined by classes and interfaces that share inheritance relationships.
  • The name of the overridden method must be the same in both base and derived classes.
  • The argument list passed to the overridden method must be the same in both base and derived classes.
  • The return type of an overriding method in the derived class can be the same, or a subclass of the return type of the overriden method in the base class. When the overridding method returns a subclass of the return type of this method, it is known as a convariant return type.
  • An overriden method defined in the base class can be an abstract method or a non-abstract method.
  • access modifiers for an overriding method can be the same or less restrictive than the method being overridden, but they can not be more restrictive.

polymorphism works only with overridden method. It can not work with overloaded method with different number/type of parameters. Overriden methods is judged by JRE at run time, while JRE judging overloaded methods as different methods.

instance variable is binding at compile time. methods are binding at run time. This means the behavior of instance variable depends on its reference variable type, and the behavipr of methods depends on the type of object when it is called.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//Assume class Programmer extends class Employee
class test{
pulic static void main(String... args){
Emplyee emp = new Employee();
//Note Employee is reference type here
Employee programmer = new Programmer();
System.out.println(emp.name); //employee
//employee. Becuase its reference type is Employee
System.out.println(programmer.name);
emp.printName(); //employee
programmer.printName(); //programmer. Because Programmer is its object type when this line is called.
}
}

Since the methods in interface are always public and abstract, the overriden methods for interface also must be public. Polymorphism applies to the class that implements the interface.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
interface Employee{
void work();
}
class Programmer implements Employee{
public void work(){
System.out.println("programming");
}
}
class QA implements Employee{
public void work(){
System.out.println("testing");
}
}

If Programmer and QA class above extends a class Worker which does not implement Employee interface, following will be a problem:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class test{
public static void main(String[] args){
Worker pro = new Programmer();
Worker qa = new QA();
pro.work();
qa.work();
/*
Code above will not compile.
Worker does not touch the interface.
If Worker also implements Employee interface, code above will compile.
*/
}
}