Вы находитесь на странице: 1из 61

3.1.

Purpose of Inheritance with a Problem Scenario


Consider a scenario where an organization has to track the details of its employees. There can be

two types of employees Regular and Contract. All the employees will have some common

attributes like EmployeeId, Name, Designation, ContactNumber. The Regular Employees will have

Monthly Basic whereas Contract Employees will have Hourly Rate and Number of Hours worked in a

month. How is the organization going to model its classes in this case?

There are two approaches one is to declare all the common attributes and methods in both

Regular and Contract Employees classes. This results in duplicating the common attributes and

methods in both the classes.

The second approach is to have a class Employee with common attributes & methods. Reuse/Inherit

the common attributes and methods in Regular and Contract Employee classes by

extending/inheriting the Employee class. The specific attributes and methods can be declared only in

the respective classes. Mentioning all the common members in a super class is called

generalization, writing the specific functionality in sub classes is called specialization

The second approach has the advantages of re-usability and readability. Also if any attribute/method

applicable to both Regular and Contract employees has to be added in future, the changes can be

done just in the Employee class.

Inheritance

Inheritance is the process of acquiring the properties of one class by another. It allows us to build

hierarchies of classes/interfaces. It is also called IS-A relationship between classes/interfaces

involved in the hierarchy.

The idea of inheritance is simple but powerful: When you want to create a new class and there is

already a class that includes some of the code that you want, you can derive your new class from

the existing class. In doing this, you can reuse the fields and methods of the existing class without

having to write (and debug!) them yourself.


A subclass inherits all the members (fields, methods, and nested classes) from its superclass.

Constructors are not members, so they are not inherited by subclasses, but the constructor of the

superclass can be invoked from the subclass.

Except java.lang.Object, which has no superclass, every class has one and only one direct

superclass (single inheritance). In the absence of any other explicit superclass, every class is

implicitly a subclass of Object.

In the scenario mentioned in the above section, the classes Regular Employee and Contract

Employee are inheriting/extending the class Employee. The inherited class Employee is called

Super class or Base class or Parent class or Generic class whereas the inheriting class i.e. Regular

Employee or Contract Employee is called Sub class or Child class or Specific class.

Inheritance can be achieved by extending the functionality of a class or implementing the

functionality of an interface.

In an inheritance hierarchy, the classes/interfaces at the top of the hierarchy will be more generic

and the classes at the bottom of the hierarchy will be more specialized. The subclasses can

specialize themselves in the following ways:

By re-declaring the attributes present in super class (called Field Hiding)

By adding new attributes

By re-defining the instance methods present in super class (called Method Overriding)

By re-defining the static methods present in super class (called Method hiding)

By adding new methods


Relating real world scenario using technical Concepts

For the Organization scenario mentioned above, the class Employee will be as follows:

Both Regular and Contract employees have the properties mentioned in Employee above and

additionally some specific properties. In this case, we will reuse them by extending the Employee

class.

Now the class RegularEmployee will have the attribute basic as well as the attributes inherited from

Employee i.e. empId, empName, designation. The method display () is also inherited from Employee

class. Similar is the case with ContractEmployee.

Let us consider the following code snippet where we try to create Regular and Contract employees:
Look at lines 4 and 5 where we are trying to create the object of RegularEmployee. In line 4, object

re which is the reference variable of RegularEmployee class is referring to the object of

RegularEmployee (which is the common way we created an object so far).

In line 5, the reference variable of Employee class is referring to the object of RegularEmployee.

This is valid as RegularEmployee class inherits Employee class i.e. every RegularEmployee IS-A

Employee by the process of inheritance.

Similarly every ContractEmployee IS-A Employee (line 7).

When we are creating a sub class object, the order of invocation of constructor is that the super

class constructor will be invoked first followed by subclass constructor. This can be checked by

putting constructor in the above classes

Inheritance and Access Modifiers:

A subclass inherits all of the public and protected members of its parent, irrespective of the package

the subclass is in. If the subclass is in the same package as its parent, it also inherits the default

members of the parent. We can use the inherited members as it is, replace them, hide them, or

supplement them with new members:

The inherited fields can be used directly, just like any other fields.

You can declare a field in the subclass with the same name as the one in the superclass,
thus hiding it (not recommended). We can access the super class variables by using the super
keyword.

You can declare new fields in the subclass that are not in the superclass.
The inherited methods can be used directly as they are.

You can write a new instance method in the subclass that has the same signature as the one
in the superclass, thus overriding it.

You can write a new instance method in the subclass that has same name but different
signature from the one in superclass, thus overloading it.

You can write a new static method in the subclass that has the same signature as the one in
the superclass, thus hiding it. This also called method hiding.

You can declare new methods in the subclass that are not in the superclass. You can write a
subclass constructor that invokes the constructor of the superclass, either implicitly or by using
the keyword super.

A subclass does not inherit the private members of its parent class. However, if the
superclass has public or protected methods for accessing its private fields, these can also be
used by the subclass.

A nested class has access to all the private members of its enclosing classboth fields and
methods. Therefore, a public or protected nested class inherited by a subclass has indirect
access to all of the private members of the superclass.

The final methods or variables used in superclass will be inherited. The final variables can be
hidden. The final methods cannot be overridden but they can be overloaded in sub class.

The default members of a class cannot be inherited outside the package. Hence the scope
of default members of a class is only within the package.

The protected members of a class can be inherited outside the package, but they cannot be
accessed to non-sub classes outside the package. Hence the scope of protected members is
all classes within the same package & subclasses outside the package.

The public members of a classes can be accessed to all classes outside the package
irrespective of whether the class is inherited or not. The scope is to all classes both inside and
outside the package.

3.2. Types of Inheritance

Depending on the number of classes/interfaces involved in the inheritance, inheritance can be

classified as:
Single inheritance (Single level inheritance)

1. One class can extend another class (or)

2. One interface can extend another interface (or)

3. One class can implement an interface.

Here A is the parent class and B is the child class.

Multiple inheritance

1. One class can extend multiple classes (not supported in Java)

2. One class can implement multiple interface

3. One class can extend one class and implement one/more interfaces

4. One interface can extend multiple interfaces

Multilevel inheritance

1. One class can extend a class which in turn extends a class or implements an interface

2. One class can implement an interface which in turn extends one or more interfaces
3. One interface can extend another interface which in turn extends one or more interfaces

Hierarchical Inheritance

1. One class is extended by multiple classes

2. One interface is extended by multiple interfaces

3. One interface is implemented by multiple classes

Hybrid Inheritance

1. If an inheritance hierarchy contains more than one type of inheritance mentioned above, it is
called Hybrid inheritance
Java supports Single, Multilevel, Hierarchical and Hybrid inheritance by using classes.

Java supports all types of inheritance by using interfaces.

Note: Java doesn't support multiple inheritance by using classes, we will discuss more about this

later.

Why Java doesn't support multiple inheritance using classes:

Consider the below scenario where class D is extending two classes B and C where as both B and

C are extending class A.


Assume that classes B and C are overriding a method defined in class A, by providing their own

implementation. Now D inherits from both B and C doing multiple inheritance. D should inherit that

overridden method, which overridden method will be inherited? Will it be from B or C? We have an

ambiguity here.

This is the reason why java doesn't support multiple inheritance using classes.

Consider the above scenario for the case where A, B and C are interfaces and D is a class

implementing B and C. As interface doesn't have any implementation, even if both B and C are

having the same methods, D has to provide implementation for only one method and it has to be

implemented in D class. Hence there is no ambiguity. This is the reason why java supports multiple

inheritance using interfaces.

Super Keyword

Super keyword is used to access the variables/methods of the object of super class. This can be

done by using the super keyword followed by '.' operator followed by the respective variable or

method. This form of super is used when the variable/method used in super class is re-declared in

sub class (i.e. Variable is hidden or method is overridden in sub class).

Super keyword is also used to refer to the constructor of super class from the constructor of sub

class. Ex: super ();

Whenever we try to create the object of sub class, the constructor of sub class will internally invoke

the empty constructor of base class. If we want to invoke a parameterized constructor of base class,

we need to use super () method and give the respective parameters to this method.

Let us go through the following example for usage of super.


The output of above program when line 1 is executed would be:

Employee Constructor

Regular Employee Constructor


The output of above program when line 2 is executed would be:

In RegularEmployee display method

In Employee display method

When RegularEmployee class is compiled, an extra line super() will be added by default as it

extends the Employee class. Hence in line 1, first the constructor of Employee will be invoked

followed by the constructor of RegularEmployee. Always the order of invocation of constructors is

from base class to subclass.

In RegularEmployee class, the display() method is re-declared (overridden). When we try to invoke

the display method on RegularEmployee object, always the display method in RegularEmployee

would be invoked. If we try to invoke the display method of Employee, we need to use

super.display() in RegularEmployee class. The output for line 2 clarifies this concept.

super() is used to invoke the base class(immediate parent class) constructor whereas this()
is used to invoke the constructor of same class.

Similar to this() should be the first statement inside the constructor, super() should also be
the first statement inside the sub class constructor. Hence super() and this() both cannot be
used in the same constructor.

If a constructor does not explicitly invoke a superclass constructor, the Java compiler
automatically inserts a call to the no-argument constructor of the superclass. If the super class
does not have a no-argument constructor, we will get a compile-time error in case if there is a
parameterized constructor in the super class. Object class has such a no-argument constructor,
so if Object is the only superclass, then there is no problem.

If a subclass constructor invokes a constructor of its superclass, either explicitly or implicitly,


there will be a whole chain of constructors called, all the way back to the constructor of
java.lang.Object class. This is called constructor chaining.

instanceOf Operator

The instanceof operator compares an object to a specified type. You can use it to test if an object is

an instance of a class, an instance of a superclass, or an instance of a class that implements a

particular interface. All objects are by default instance of java.lang.Object as every class implicitly

extends java.lang.object. Null is not an instance of any class or interface.


The following program, InstanceofDemo, defines a parent class (named Parent), a simple interface

(named MyInterface), and a child class (named Child) that inherits from the parent and implements

the interface.

Output:

obj1 instanceof Parent: true

obj1 instanceof Child: false

obj1 instanceof MyInterface: false

obj2 instanceof Parent: true

obj2 instanceof Child: true

obj2 instanceof MyInterface: true

obj1 instanceof Object: true

Pros & Cons

Pros

Inheritance gives us a way to reuse the existing code and also to specialize the behavior
depending on need.

It is easier to add new subclasses using inheritance because inheritance comes with
polymorphism. If you have a bit of code that relies only on a superclass interface, that code can
work with a new subclass without change.
Inheritance's single invocation of an inherited superclass method implementation gives more
code readable, good performance most often compared to explicit method-invocation
forwarding (or delegation) approach of composition.

Cons

With inheritance, you get the image of the superclass in your subclass object image as soon
as the subclass is created, and it remains part of the subclass object throughout the lifetime of
the subclass.

In an inheritance relationship, superclasses are often said to be "fragile," because one little
change to a superclass can ripple out and require changes in many other places in the
application's code.

Inheritance is also sometimes said to provide "weak encapsulation," because if we have


code that directly uses a subclass, that code can be broken by changes to a superclass. One of
the ways to look at inheritance is that it allows subclass code to reuse superclass code. For
example, if subclass doesn't override a method defined in its superclass, the sub class is in a
sense reusing super class implementation of the method.

Syntax

Inheritance can be done in Java by using extends and implements keywords

The extends keyword is used to inherit:

a) a class by another class and

b) an interface by another interface

Let us consider the class Employee :

class Employee {

int empId;

String empName;

String designation;

There are two types of employees Regular and Contract. Both the type of employees are having

the properties mentioned in the above Employee class and additionally some specific properties. In

this case, instead of declaring these common properties, we will reuse them by extending the
Employee class i.e.

class RegularEmployee extends Employee {

int basic;

class ContractEmployee extends Employee {

int hourlyRate;

double numHours;

Note: A class can extend only one another class in Java.

Similarly an interface can inherit another interface by using extends keyword:

interface I1 {

void display();

interface I2 extends I1{

void add();

Note: An interface can extend any number of interfaces in Java.

The implements keyword is used to inherit an interface by a class

class c1 implements I1{

public void display(){

// Code here

Note: 1) A class can implement any number of interfaces in Java.

2) An interface cannot extend or implement a class

Following table summarizes the usage of extends and implements keywords:


3.3. Polymorphism
Polymorphism

Polymorphism means existence in multiple forms. In the context of Object oriented programming

languages Polymorphism means - Subclasses of a class can define their own unique behaviors

and yet share some of the same functionality of the parent class. Let us refer again to the example

of Employee class example where the classes RegularEmployee and ContractEmployee are

inheriting the Employee class.

Both Regular and Contract employees have the properties mentioned in the above Employee class

and additionally some specific properties. In this case, we will reuse them by extending the

Employee class and then redefine the display method.


Now the class RegularEmployee will have the attribute basic as well as the attributes inherited from

Employee i.e. empId, empName, designation. The method display() present in Employee class is

redefined in RegularEmployee. Similar is the case with ContractEmployee.


Let us consider the above code snippet where we try to invoke display method on Regular and

Contract employees:

Look at lines 6, 8 and 10 where we are invoking the display method on the objects of Employee,

RegularEmployee and ContractEmployee classes respectively. The output will be as follows:

For e.display(),

EmpId:111 EmpName:ABC Designation:Developer

For re1.display(),

Displaying RegularEmployee Details

EmpId:222 EmpName:XYZ Designation:Developer

Basic:1000

For re2.display(),

Displaying ContractEmployee Details

EmpId:333 EmpName:MNO Designation:Developer

HourlyRate:100NumHours:200.0

When we redefine a method in a sub class and whenever we invoke this method on subclass object,

the version of the method in subclass will be invoked. If the method is not redefined, the version of

the method in base class will be invoked. Thus same method call will exhibit different behaviors

depending on whether it is redefined in subclass or not.

Method Overloading
Method overloading is the concept of having different methods having same name but different

parameters. The parameters can differ in:

1. Number of parameters

2. Type of parameters

3. Order of parameters

Suppose that you have a class that can use calligraphy to draw various types of data (strings,

integers, and so on) and that contains a method for drawing each data type. It is cumbersome to use

a new name for each methodfor example, drawString, drawInteger, drawFloat, and so on. In the

Java programming language, you can use the same name for all the drawing methods but pass a

different argument list to each method. Thus, the data drawing class might declare four methods

named draw, each of which has a different parameter list.

Overloaded methods are differentiated by the number, type and order of the arguments passed into

the method. In the code sample above

1st, 2nd and 3rd methods are differentiated by the type of arguments
4th method is distinguished from 1st, 2nd and 3rd by the number of arguments

4th and 5th methods are distinguished by the order of arguments.

You cannot declare more than one method with the same name and the same number, type and

order of arguments, because the compiler cannot distinguish them.

The compiler does not consider return type when differentiating methods, so you cannot declare two

methods with the same signature even if they have a different return type.

Following are the rules for method overloading:

The overloaded methods should have same name

The argument list should differ in number of parameters or type of parameters or order of
parameters.

The return type is of no significance in overloading.

The access specifier is of no significance in overloading.

Static methods can be overloaded.

Final methods can be overloaded.

Abstract methods can be overloaded.

The exceptions thrown by the methods are of no significance.

Constructors can be overloaded

Method overloading can be done both within the same class as well as in an inheritance hierarchy.

The same rules as mentioned above will be applicable to inheritance hierarchy as well, except that

constructors cannot be overloaded across classes.

Note: Overloaded methods should be used sparingly, as they can make code much less readable.

Overloading is also called as compile time polymorphism

Method Overriding
Method overriding is the process where a method defined in super class is redefined in sub class.

The signature of the method in subclass should be same as the signature of the method in super

class.

Following are the rules for method overriding:

The name of the method in super class and sub class is same.

The argument list of the method in sub class should exactly be the same as that of the
overridden method.

The return type should be the same or a subtype of the return type declared in the original
overridden method in the super class. This subtype is called a co-variant return type.

The access level cannot be more restrictive than the overridden method's access level. For
example: if the super class method is declared public then the overriding method in the sub
class cannot be either private or protected. However the access level can be less restrictive
than the overridden method's access level.

Instance methods can be overridden only if they are inherited by the subclass.

A method declared final cannot be overridden, but it can be overloaded.

A method declared static cannot be overridden but can be re-declared. This is called method
hiding.

A method declared abstract can be overridden.

A method declared private in super class cannot be inherited and hence cannot be
overridden. We can declare a method with same signature in sub class, however it is not a
overriding. It is as if we added a new method in sub class.

A subclass within the same package as the instance's superclass can override any
superclass method that is not declared private or final.

A subclass in a different package can only override the non-final methods declared public or
protected.

An overriding method can throw any unchecked exceptions, regardless of whether the
overridden method throws exceptions or not. However the overridden method should not throw
checked exceptions that are new or broader than the ones declared by the overridding method.
The overriding method can throw narrower or fewer exceptions than the overridden method.
Constructors cannot be overridden

Following table summarizes the use of access specifiers with respect to method overriding

Method Hiding

If a subclass defines a static method with the same signature as a static method in the superclass,

then the method in the subclass hides the one in the superclass. The distinction between hiding a

static method and overriding an instance method has important implications:

The version of the overridden instance method that gets invoked is the one in the subclass .The

version of the hidden static method that gets invoked depends on whether it is invoked from the

superclass or the subclass.

Consider an example that contains two classes. The first is Animal, which contains one instance

method and one static method:

The second class, a subclass of Animal is called Cat


The Cat class overrides the instance method in Animal and hides the static method in Animal. The

main method in this class creates an instance of Cat and invokes testClassMethod() on the class

and testInstanceMethod() on the instance.

The output from this program is as follows:

The static method in Animal

The instance method in Cat

As mentioned, the version of the hidden static method that gets invoked is the one in the superclass,

and the version of the overridden instance method that gets invoked is the one in the subclass.

The following table summarizes what happens when you define a method with the same signature

as a method in a superclass.
v

3.4. Types of Polymorphism


Depending on the time (Compilation or Execution of a program) at which the resolution of a method

call will be decided, Polymorphism can be classified as:

Static Polymorphism and

Dynamic Polymorphism

If the method binding between method call and method definition happens at compile time, it is

called Static Polymorphism. It is also called Compile time polymorphism or static binding or early

binding.

If the method binding between method call and method definition happens at runtime, it is called

Dynamic Polymorphism. It is also called Run time binding or dynamic binding. Here Java compiler

does not understand which method is called at compilation time. Only JVM decides which method is

called at run-time this is called dynamic method dispatch

Java supports Static Polymorphism using Method Overloading, Method hiding using static, private

methods. For final methods also, Static Polymorphism is used as they cannot be overridden in sub

class.
Java supports Dynamic Polymorphism with method overriding using instance methods.

Example for Static Polymorphism:

In the above example the binding of method to et.sort(c) would be done at compilation time based

on the argument(s) to the sort method. Hence this is a compile time polymorphism. The output of

above program is Inside Collection sort method

Example for Dynamic Polymorphism:


In the above example the super class Vehicle's reference is referring to the object of sub class Car.

When we invoke the start method, at compile time the compiler will check whether the method is

present in the class of the reference variable i.e. Vehicle class. But this doesn't bind the method call

to the actual method definition as the Super Class reference type can refer to Sub class object.

At the time of execution, the JVM will check to which object the reference is referring to and

accordingly it will invoke the respective method version. In the above example, the Vehicle reference

is referring to Car object and hence the start() method defined in Car class will be invoked. This

concept of binding the method definition at run time based on the object to which the reference

variable is referring to is called Dynamic Method dispatch. The output of above program is "Inside

start method of Car"

Upcasting and Downcasting

Upcasting is changing type by moving up the inheritance hierarchy. This is always safe, because it's

always true that a SubType IS-A SuperType (for example, it's always true that a ContractEmployee

IS A Employee). Therefore, an explicit cast is NOT needed when upcasting.

Downcasting is changing type by moving down the inheritance hierarchy. This is NOT always safe,

because it's NOT always true that a SuperType IS-A SubType (for example, it's NOT always true that

a Employee IS A ContractEmployee). Therefore, an explicit cast IS required when downcasting.

As you know, all objects have a type. The thing to keep in mind is the true runtime type of the object.

This is the type of object that was created with "new." Once an object is created, its true runtime type

never changes.

But references (stored in variables) also have types. A variable referencing an object can be the

same type as that object, or it can be any supertype of that object. For example, a variable that is

type "Car" can reference an object that is simply a Car. Or it can reference an object that is a more
specific type (a subtype) of Car. For example, a Car variable might reference an instance of

"Volkswagen," which IS-A Car.

The compiler only knows the types of references. It doesn't know the true runtime type of an object.

So when you say...

SuperType sup = new SubType();

that's fine. Because "new SubType()" returns a reference of type SubType. The compiler knows it's

always true that a SubType IS-A SuperType (a Volkswagen is always a Car). So it's okay to assign

that reference to a variable of type SuperType. (This is called an "assignment conversion.")

On the other hand, a Car is NOT always a Volkswagen.

SubType sub = new SuperType();

will fail to compile, because "new SuperType()" returns a reference of type SuperType, and the

compiler knows that a SuperType is NOT a Subtype.

But suppose the SuperType reference on the right side did, in fact, point to an instance of SubType.

For example...

SubType sub = sup; //using the sup we assigned above

To assure the compiler that this assignment is valid, the programmer must insert an explicit cast to

downcast the SuperType reference (sup) to type SubType...

SubType sub = (SubType)sup;

With the explicit cast, the compiler will trust the programmer in saying that the object referenced by

sup is, in fact, a SubType object. In this example, there is no problem at runtime, because the true

runtime type of the object referenced by "sup" is SubType.

But if it turns out that the downcast is not correct, then the program will fail at runtime with a

ClassCastException. This is what's happening with...

SubType sub = (SubType) new SuperType();


"new SuperType()" creates an object with a true runtime type of SuperType, and returns a reference

that also has the type SuperType. However, an explicit cast tells the compiler to downcast that

reference to SubType, so it compiles. However, at runtime, the program fails because the true type

of the object is NOT SubType.

@override Annotation

@Override annotation informs the compiler that the element is meant to override an element

declared in a superclass.

// mark method as a superclass method that has been overridden

@Override

int overriddenMethod() { }

While it is not required to use this annotation when overriding a method, it helps to prevent errors. If

a method marked with @Override , when misspelling a method name or not giving the correct order

of methods as it is in superclass , the compiler generates an error.

Pros & Cons

Pros:

Objects belonging to different types to respond to method, field, or property calls of the same

name, each one according to an appropriate type-specific behavior.

Cons:

Overloaded methods should be used sparingly, as they can make code much less readable.

3.5. Interface, Abstract class and Final Class


Interface

An interface is a collection of abstract methods. A class implements an interface, thereby inheriting

the abstract methods of the interface. In java interface is nothing but the collection of methods with

empty implementations and constants variables (variables with static and final declarations). All the

methods in an interface are "public and abstract" by default. Since interfaces are abstract in nature
they cannot be directly instantiated. To define the methods of an interface the keyword "implements"

is used.

An interface is not a class. Writing an interface is similar to writing a class, but they are two different

concepts. A class describes the attributes and behaviors of an object. An interface contains

behaviors that a class implements. Unless the class that implements the interface is abstract, all the

methods of the interface need to be defined in the class.

Example:-

Output:-
Rules to be followed while using Interface:-

If a class wants to make use an interface it should make use of it using keyword implements.

A class can make use of any number of interfaces by separating the interface names with
comma (,).

If an interface is implemented by a class that class should override/implement all the


methods in that Interface.

An interface can be used by any number of classes.

An interface can extend other interfaces.

An interface can have variables but they should be final.

An interface can have static and final variables then the class can make use of them with the
help of interface name.

An Interface is similar to a class in the following ways

An interface can contain any number of methods.

An interface is written in a file with a .java extension, with the name of the interface matching
the name of the file.

The byte code of an interface appears in a .class file.

Interfaces appear in packages, and their corresponding byte code file must be in a directory
structure that matches the package name.

An Interface is different from a class in several ways, including

We cannot instantiate an interface.

An interface does not contain any constructors.

All of the methods in an interface are abstract.


An interface cannot contain instance fields. The only fields that can appear in an interface
must be declared both static and final.

An interface is not extended by a class; it is implemented by a class.

An interface can extend multiple interfaces.

Rules to implement Interfaces are:-

A class can implement more than one interface at a time.

A class can extend only one class, but implement many interfaces.

An interface can extend another interface, similarly to the way that a class can extend
another class.

Extending Interfaces:-

The extends keyword is used to extend an interface, and the child interface inherits the methods of

the parent interface.

Example:-

Here Cloneable is the predefined interface available in java.lang package.

Extending Multiple Interfaces:-

A Java class can only extend one parent class. Multiple inheritance is not allowed. Interfaces are not

classes, however, and an interface can extend more than one parent interface. The extends keyword

is used once, and the parent interfaces are declared in a comma-separated list.

Example:-
Here Cloneable is the predefined interface available in java.lang package. And Serializable interface

is also available in java.io package. These two interfaces are called Marker or Tagged interfaces

they doesn't have any methods and variables.

Abstract class

An abstract class is a class that is declared abstract. It may or may not include abstract methods.

Abstract classes cannot be instantiated, but they can be sub classed. An abstract method is a

method that is declared without an implementation (without braces, and followed by a semicolon). If

a class includes abstract methods, then the class itself must be declared abstract. When an abstract

class is sub classed, the subclass usually provides implementations for all of the abstract methods in

its parent class. However, if it does not, then the subclass must also be declared abstract. An

abstract class can have data member, abstract method, method body, constructor and even main()

method. If there is any abstract method in a class, that class must be abstract. If you are extending

any abstract class that has abstract method, you must either provide the implementation of the

method or make this class abstract.

Example:-
Final class

The final keyword in java is used to restrict the user. The final keyword can be used in many context.

Final can be:

1. Variable

2. Method

3. Class

Final Variable:-
If you make any variable as final, We cannot change the value of final variable(It will be

constant).There is a final variable speed limit, we are going to change the value of this variable, but

It can't be changed because final variable once assigned a value can never be changed.

Example:

Final method:-

If we make any method as final, you cannot override it.

Example:-
Final Class:-

If we make any class as final, you cannot extend it.


3.6. Class Relationships
In any application each object will have its own role/responsibility along with its characteristics. No

object can ever exist isolated and complete a task/functionality of the application. To achieve a goal
or functionality, the object has to depend on other objects for further help. This thus creates a

relationship between the objects. Depending on the type of dependency between objects, we have

different kinds of relationship between objects. The same is represented as relationship between

classes.

Before we jump to the actual topic with technical details, let us try to understand the term

relationship with the help of what we see around us in this real physical world.

Relating with Real World Scenario

Each and every day we see lots of objects around us and we see all of them interacting with each

other, to perform an action or to complete a goal. Even we take help of different objects to complete

our job.

Let us take a small example for understanding the above statement. Let us consider the working of a

school. What do we see in a school?

School

Class Rooms

Principal

Teachers, Head Masters

Clerk

Students

Text Books or Study Material

Writing Instruments (such as boards, chalk, markers, pen, note books etc)

Display instruments (such as boards, TV screen, projector etc.)

For each of the entries mentioned above we have one or more physical entities (we will call them as

objects) belonging to that corresponding category. So each entry mentioned above in the list

represents a class of objects. So we have One principal object from the Principal class, multiple
teacher objects from the Teacher class, multiple pen objects, pencil objects from the Writing

instruments class and the list goes on.

NOTE: Whenever the term object/objects is being used in any real world example, it refers to both

living being and non-living object (treated equally).

We all know the main goal of a school is to impart learning. With this in mind we have the next

question, can any of the objects complete this task/goal without the help of the other objects? The

answer for this is definitely NO. A principal takes help of headmasters, teachers for knowledge

transfer. The teachers take help of the writing and display instruments, study material to explain the

subject. The principal is required for managing the school and the last but not the least, the students

are also an essential part of the school. The teachers transfer the knowledge to the students.

With this example, we have understood that each object is dependent on another to perform one or

the other task. Now let us try to derive a few relationships among objects from this scenario.

School contains the class rooms

School has principal, head master, teachers, students

Principal, Head Master, Teacher, Clerk are all different specialized types of Staff members in
the school.

Teachers teach a particular subject by referring to the corresponding text books or study
material.

Teachers use the different writing or display instruments (that are given to them) for
conducting classes. Students also use different writing instruments for taking notes.
Now let us give a name to each of the type of relationship we have identified in the above list

1. Composition

2. Aggregation

3. Inheritance

4. Association

5. Dependency

Let us explain each of the relationship in a few words:

1. Composition: One entity contains another entity. The later entity cannot exist if the former one

does not exist.

2. Aggregation: Similar to composition, but both the contained and containing entities can exist

independently.

3. Inheritance: One entity is similar to another entity but has some extra special characteristics or

roles/responsibilities. (Parent child relationship)

4. Association: An entity takes help of another entity to complete a task.

5. Dependency: An entity is dependent on another entity to complete a task.


NOTE: Both composition and aggregation represent HAS-A relationship and inheritance represents

IS-A relationship between two classes.

NOTE: Dependency and association relationships might be confusing and look ambiguous here.

While discussing the details, the difference can be seen.

The next section describes the above identified relationships in detail, along with technical details of

it.

3.7. Class Relationship Types - Composition, Aggregation


With the help of a school example we have identified different relationships that can exist between

classes. Whenever we say a class is related to another class, then we would see an interaction

between the objects of both the classes.

Except for inheritance relationship there is no special coding that needs to be done to establish the

relationship between different classes. Whenever we say any relationship exists between two

classes A and B, we can see a reference to an object of the later class and also attributes or a

methods of the later class being used in the former class.

With this understanding let us proceed further with technical details.

1. Composition

Let us discuss about the first relationship COMPOSITION

The word itself says, one object composes of other objects. Hence the composed objects do not

have any existence, if they are taken out separately.

Composition relationship exists between two classes, say A and B, when any of the objects of the

class B cannot exist if an object of the class A does not exist. In the above Example School contains

Class Rooms. A class room cannot exist (or in other terms has no value) if school does not exist.

Hence this relationship is termed as composition. On the similar lines, we can take another example

for composition is the relationship between school and its address.


Let us see how the composition relationship looks in a Java code.

Try It Yourself

Create a class School. It has different attributes such as name, type, rating etc.

Create a class ClassRoom. It has different attributes room number, capacity etc.

As School contains some class room .Class room does not have any significance without a school

The following is the code snippet. The complete example can be found in the zip file.
Observation: If we observe the code,

The objects of ClassRoom do not exist if the object School is garbage collected.

We would not be able to retrieve the objects of ClassRoom if the object of School is removed
from memory.

Another point to note here is that the class room objects created by the School class only, so
that when object of school is removed from memory automatically others are also garbage
collected.

Here the class room does not have /should not have getter/setter methods.

UML Representation

2. Aggregation

The next relationship that we would explore is AGGREGATION.

The term aggregation says an object contains other objects.

Aggregation is similar to composition. It also denotes a HAS-A relationship. The only difference

between aggregation and Composition is in an aggregation relationship both the contained and

containing objects can exist independent of the other, whereas in composition, the contained object

has no existence/importance if the containing object does not exist.


Let us see how aggregation is implemented in Java.

Try It Yourself

Take the same School class taken above. Create Teacher class. This class has attributes like

employee id, name, subject (assuming a teacher teaches only one subject), experience etc.

The school contains teachers and principal, so we have a list of teachers as an attribute and a

principal as another attribute. Here the teachers or the principal can exist even if the school does not

exist. Hence here we have the aggregation relationship here.

The following is the code snippet. The complete example can be found in the zip file.
Observation: If we observe the code,

The school object is created separately and the teacher objects are created separately
(outside the School class). Whereas in composition the ClassRoom were created inside the
School class only

Later the school object is assigned the list of teacher objects through the setter methods.

Hence, even if the school object is deleted from the memory, the teachers/principal object
can still be accessed.

The getter/setter methods are available for the teacher/principal objects in the school class.

UML Representation
3.8. Class Relationship Types - Association, Dependency
and Inheritance

3. Association

Till now we have discussed about aggregation and composition. Both are similar to each other with a

little difference. If there is an aggregation or composition relationship between two classes, then we

can say there is an association present between two different classes. The aggregation or

composition is also known as whole-part association or HAS-A association. But this is not the only

way one class is associated with another.

A class can be associated with another class, if a given object, in its life time knows about the

existence of another object and uses its attributes/methods for performing a task, then both the

objects are known to be associated with each other and hence the corresponding classes have an

association (relationship) between them.

In association, even if one class has a reference to the object of another class, and also uses its

attributes or methods for performing certain tasks, it does not take ownership of the objects of the

other class. To put in other words, the relationship cannot be logically described as a HAS-A

relationship. It can be just described as uses/takes help or such kind of relationship.


NOTE: The association can be uni-directional or bi-directional. Also it can be one-one, one-many,

many-one or many-many.

NOTE: If an association can be described as whole-part relationship then it becomes an

aggregation. If the whole-part relationship is strong such that part cannot exist without the whole,

then the relationship becomes composition.

Try It Yourself

Take the same teacher class as in the above example.

The teacher uses some study material for teaching a particular subject. The study material is used

by the teacher, for the entire lifetime.

Create a class StudyMaterial with attributes like, author, title, etc.

Create an attribute in Teacher class that references object of StudyMaterial. This reference can be

used accordingly in methods whenever required.


Observation: If we observe the code then syntactically there is no difference between association

and aggregation. The difference is only conceptual or logical.

UML Representation
4. Dependency

When a class is associated with another we can say a dependency relationship exists between two

classes. Logically both the association and dependency relationships are similar. The difference is

only how we code and how strong the relationship is. Association is stronger when compared to the

dependency relationship. Association can also be called as a stronger dependency.

The association relationship is valid for the complete lifetime of an object, whereas the dependency

relationship is valid only for a limited period of time. To elaborate the previous statement, when we

say association relationship exists between class A and B then, a reference variable for object of

class B is found as an attribute in class A. Whereas, when we say class A and B have a dependency

relationship, then reference variable for object of class B is found either as a local variable, or as an

input parameter to some method of class A.


Let us see the sample code.

Try It Yourself

Take the same Teacher class as in the above examples.

Create a class WhiteBoardMarker with attribute color.

An object of WhiteBoardMarker is required by the teacher only when there is a need to write on the

board. Hence the object of WhiteBoardMarker is passed as input parameter to method

writeOnBoard present in the Teacher class. The association between a teacher and a

WhiteBoardMarker object is not present for the entire lifetime of the teacher. Hence this relationship

is called dependency.
Observation: In the code above observe that

The reference to WhiteBoardMarker is supplied to the teacher during run time.

There is no long term association of the teacher with the marker object. The teacher object uses the

marker object only for a shorter duration.

In contrast to this observe the sample code for association, the teacher object has long term

association with the study material object.

Refer the below code snippet to observe the difference.


UML Representation

5. Inheritance

The last relationship that we are going to discuss here is the inheritance relationship. This kind of

relationship exists between two classes when one class is a specialized type of another. In a school

we have the teachers, headmasters, principal, clerk etc. All of them can be generalized as school

staff. As school staff they have some common attributes such as employee id, name salary and

some common tasks, such as signing staff attendance register etc. Again each of them have their

additional characteristics and their own specialized task such as the teacher teaches, the

headmaster conducts review, the clerk maintains the attendance registers etc.
Inheritance provides a lot of re-usability. The inheritance feature in Java is used to establish the IS-A

relationship.

Let us see sample code in Java.

Try It Yourself

Create a class Staff with attributes employee id and name. These are the common attributes for all

the staff members of the school. Write a method signRegister. This represents the responsibility of

signing the staff attendance register which is a common responsibility for all the staff members.

Create a class Teacher and extend it from Staff. Employee id and name are inherited from the staff

class. The attributes experience, subject, study material etc are specific only to this class. Similarly

the teach method is specific to the Teacher class and signRegister method is inherited from the Staff

class.
Create a new class Clerk and extend it from Staff. Similar to the class Teacher, Clerk also inherits

the attributes and methods from Staff class and has its own specialized method maintainRegister for

maintaining the register.


Observation: In the code above observe that

The Clerk and the Teacher inherit the Staff class and hence inherit the methods and attributes of the

Staff class.

The extends keyword shows the inheritance relationship between Clerk Staff and Teacher Staff.

The Clerk has the extra responsibility of managing the attendance registers. This is done with the

help of maintainRegister method in the Clerk class.

Whereas the Teacher has the additional responsibility of teaching. This is accomplished with the

writeOnBoard method in the Teacher class.

UML Representation
3.9. Relationships - Summary

To summarize the relationships which we have discussed till now can be categorized as follows:

1) Any kind of relationship between two classes can be termed as Dependency relationship.

2) If the identified dependency is strong enough, such that one class has an attribute which refers to

the other class, then the relationship will be termed as Association.

3) If the identified association represents a logical whole-part relationship or in other words HAS-A

relationship, then the relationship will be called as Aggregation.

4) If the whole-part relationship is strong enough such that, the object representing the part cannot

exist without the existence of the object representing the whole then the relationship will be called as

Composition. This is also a HAS-A relationship

5) If one class is a specialized form of another class then the relationship between the two would be

termed as Inheritance. Inheritance is a IS-A relationship

6) Dependency is the weakest relationship and the composition is the strongest

7) The above discussion can be represented in the form of a diagram as below:

Notes: Relationship realization can be achieved using interface .We will see the details in the

upcoming chapters

Test your knowledge by taking this Sample Quiz.

Вам также может понравиться