Unit-3: Topics
Unit-3: Topics
Unit-3
Topics:
Inheritance –Types of Inheritance, using the extends keyword, Method overloading, super
keyword, final keyword, abstract class.
Interfaces, Packages: Interface, extending interface, Interface Vs Abstract class, Creating
package, using the package, access protection.
Exceptions and Assertions: Exception Handling techniques, User defined Exception,
exception encapsulation and enrichment, Assertions.
Definition of Inheritance
Inheritance is the process by which one class acquires the properties of another class. This is
important because it supports the concept of hierarchical classification. The class that is
inherited is called superclass. The class that is inheriting the properties is called subclass.
Therefore the subclass is the specialized version of the superclass. The subclass inherits all
the instance variable and methods, and adds its own code.
The properties from superclass to the subclass are inherited using the "extends" keyword.
The following program creates a superclass called A and a subclass called B. Notice how the
keyword extends is used to create a subclass of A.
// A simple example of inheritance. SimpleInheritance.java
// Create a superclass.
class A
{
int i, j;
void showij()
{
System.out.println("i and j: " + i + " " + j);
}
}
// Create a subclass by extending class A.
class B extends A {
int k;
void showk()
{
System.out.println("k: " + k);
}
void sum()
{
System.out.println("i+j+k: " + (i+j+k));
}
Unit 3: Inheritance , Interfaces, Packages, Exceptions and Assertions
}
class SimpleInheritance
{
public static void main(String args[])
{ // subclass object creation, which acquires all the properties of the superclass
B b = new B();
/* The subclass has access to all public members of its superclass. */
b.i = 7;
b.j = 8;
b.k = 9;
System.out.println("Contents of b: ");
b.showij();
b.showk();
System.out.println("Sum of i, j and k in b:");
b.sum();
}
}
Output:
Contents of b:
i and j: 7 8
k: 9
Sum of i, j and k in b:
i+j+k: 24
/* In a class hierarchy, private members remain private to their class. This program contains
an error and will not compile. */
// Create a superclass.
class A
{
int i; // public by default
private int j; // private to A
void setij(int x, int y)
{
i = x;
j = y;
}
}
// A's j is not accessible here.
class B extends A
Unit 3: Inheritance , Interfaces, Packages, Exceptions and Assertions
int total;
void sum()
{
total = i + j; // ERROR, j is not accessible here
}
}
class Access
{
public static void main(String args[])
{
B b = new B(); // creating the object b
b.setij(10, 12);
b.sum(); // Error, private members are not accessed
System.out.println("Total is " + subOb.total);
}
}
Note:
This program will not compile because the reference to j inside the sum( ) method of B
causes an access violation. Since j is declared as private, it is only accessible by other
members of its own class. Subclasses have no access to it.
class Box
{
double width,height,depth;
}
class Boxweight extends Box
{
double weight;
Boxweight(double x, double y, double z, double z)
{
width=x; height=y; depth=z; weight=a;
}
void volume()
{
System.out.println("The volume is :"+(width*height*depth));
}
}
//main class
Unit 3: Inheritance , Interfaces, Packages, Exceptions and Assertions
class BoxDemo
{
//creating superclass object
public static void main(String args[])
{
Box b=new Box();
//creating the subclass object
Boxweight bw=new Boxweight(2,3,4,5);
bw.volume();
//assigning the subclass object to the superclass object
b=bw; // b has been created with its own data, in which weight is not a member
System.out.println ("The weight is :"+b.weight);
// here it raises error, super class does not contain the volume() method
}
}
The uses of the "super" keyword
There are two uses of the super keyword.
i. super keyword is used to call the superclass constructor
ii. super keyword is used to access the members of the superclass.
A subclass can call the constructor of the superclass by the using the super keyword in the
following form:
super(arg_list);
Here, the arg_list, is the list of the arguments in the superclass constructor. This must be the
first statement inside the subclass constructor. For example,
// BoxWeight now uses super to initialize its Box attributes.
class Box
{
double width,height,depth;
//superclass constructor
Box(double x, double y, double z)
{
width=x;height=y;depth=z;
}
class BoxWeight extends Box
{
double weight; // weight of box
// initialize width, height, and depth using super()
BoxWeight(double w, double h, double d, double m)
{
super(w, h, d); // call superclass constructor
weight = m;
}}
Unit 3: Inheritance , Interfaces, Packages, Exceptions and Assertions
The second form of super acts somewhat like this, except that it always refers to the
superclass of the subclass in which it is used. This usage has the following general form:
super.member;
Up to this point, we have been using simple class hierarchies that consist of only a superclass
and a subclass. However, you can build hierarchies that contain as many layers of inheritance
as you like. As mentioned, it is perfectly acceptable to use a subclass as a superclass of
another. For example, given three classes called A, B, and C, C can be a subclass of B, which
is a subclass of A. When this type of situation occurs, each subclass inherits all of the traits
Unit 3: Inheritance , Interfaces, Packages, Exceptions and Assertions
found in all of its superclasses. In this case, C inherits all aspects of B and A. To see how a
multilevel hierarchy can be useful, consider the following program.
Example program
class A
{
void methodA()
{
System.out.println("This is the method of A");
} Multi Level Inheritance
}
//class b extends the super class A
class B extends A class A{
{ methodA()
void methodB() }
{
System.out.println("This is the method of B");
}
class B{
}
methodB()
}
//class C extends the super class B
class C extends B
{
void methodC() class C{
{ methodC()
System.out.println("This is the method of C"); }
}
}
class Hierachy
{
public static void main(String args[])
{
C cobj=new C();
c.methodA();
c.methodB();
c.methodC();
}
}
Method Overriding
In a class hierarchy, when a method in a subclass has the same name and type signature as a
method in its superclass, then the method in the subclass is said to override the method in the
superclass. When an overridden method is called from within a subclass, it will always refer
to the version of that method defined by the subclass. The version of the method defined by
the superclass will be hidden. Consider the following example:
Unit 3: Inheritance , Interfaces, Packages, Exceptions and Assertions
class A
{
void disp()
{
System.out.println("This is the class A method");
}
}
// extending the superclass properties
class B extends A
{
void disp()
{
System.out.println("This is the class B method");
}
}
// main class
class OverRide
{
public static void main(String args[])
{
B b=new B();
b.disp(); // super class method is hidden, subclass method is invoked
}
}
output:
Let’s begin by restating an important principle: a superclass reference variable can refer to a
subclass object. Java uses this fact to resolve calls to overridden methods at run time. Here is
how. When an overridden method is called through a superclass reference, Java determines
which version of that method to execute based upon the type of the object being referred to at
the time the call occurs. Thus, this determination is made at run time.
Here is an example that illustrates dynamic method dispatch:
class B extends A
{
// override callme()
void callme()
{
System.out.println("Inside B's callme method");
}
}
class C extends A
{
// override callme()
void callme()
{
System.out.println("Inside C's callme method");
}
}
class Dispatch
{
public static void main(String args[])
{
A a = new A(); // object of type A
B b = new B(); // object of type B
C c = new C(); // object of type C
A r; // obtain a reference of type A
r = a; // r refers to an A object
r.callme(); // calls A's version of callme
r = b; // r refers to a B object
r.callme(); // calls B's version of callme
r = c; // r refers to a C object
r.callme(); // calls C's version of callme
}
}
The output from the program is shown here:
To declare a class abstract, you simply use the abstract keyword in front of the class
keyword at the beginning of the class declaration. There can be no objects of an abstract
class. That is, an abstract class cannot be directly instantiated with the new operator. Such
objects would be useless, because an abstract class is not fully defined.
The final keyword can be used to create constants. The general form of the statement is as
follow:
final type variable_name=value;
where type can be any primitive data type, and variable_name can be any valid identifier. For
example,
final int speed=120;
While method overriding is one of Java’s most powerful features, there will be times when
you will want to prevent it from occurring. To disallow a method from being overridden,
specify final as a modifier at the start of its declaration. Methods declared as final cannot be
overridden. The following fragment illustrates final:
class A
{
final void meth()
{
System.out.println("This is a final method.");
}
}
class B extends A
{
void meth()
{ // ERROR! Can't override.
System.out.println("Illegal!");
}
}
Because meth( ) is declared as final, it cannot be overridden in B. If you attempt to do so, a
compile-time error will result. Methods declared as final can sometimes provide a
performance enhancement: The compiler is free to inline calls to them because it “knows”
they will not be overridden by a subclass. When a small final method is called, often the Java
compiler can copy the bytecode for the subroutine directly inline with the compiled code of
the calling method, thus eliminating the costly overhead associated with a method call.
Inlining is only an option with final methods. Normally, Java resolves calls to methods
dynamically, at run time. This is called late binding. However, since final methods cannot be
overridden, a call to one can be resolved at compile time. This is called early binding.
Unit 3: Inheritance , Interfaces, Packages, Exceptions and Assertions
final class A
{
// ...
}
// The following class is illegal.
class B extends A
{
// ERROR! Can't subclass A
// ...
}
As the comments imply, it is illegal for B to inherit A since A is declared as final.
One of the main feature of the Object Oriented Programming language is the ability to reuse the
code that is already created. One way for achieving this is by extending the classes and
implementing the interfaces. Java provides a mechanism to partition the classes into smaller chunks.
This mechanism is the Package. The Package is container of classes. The class is the container of the
data and code. The package also addresses the problem of name space collision that occurs when
we use same name for multiple classes. Java provides convenient way to keep the same name for
classes as long as their subdirectories are different.
Benefits of packages:
1. The classes in the packages can be easily reused.
2. In the packages, classes are unique compared with other classes in the other packages.
3. Packages provide a way to hide classes thus prevent classes from accessing by other
programs.
4. Packages also provide way to separate "design" from "coding".
Categories of Packages
The Java Packages are categorized into two categories (i) Java API Packages (ii) User Defined
Packages.
1. Java API Packages –Java API provides large number of classes grouped into different
packages according to the functionality. Most of the time we use the package available with Java
API.
Unit 3: Inheritance , Interfaces, Packages, Exceptions and Assertions
java
ii. import statement –this is used when we want to use a class or many classes in many
places in our program. Example: (1) import java.util.*;
(2) import java.util.StringTokenizer;
Naming Conventions
Packages can be named using the Java Standard naming rules. Packages begin with "lower
case" letters. It is easy for the user to distinguish it from the class names. All the class Name by
convention begin with "upper case" letters. Example:
double d= java.lang.Math.sqrt(3);
Unit 3: Inheritance , Interfaces, Packages, Exceptions and Assertions
Here, "java.lang" is the package, and "Math" is the class name, and "sqrt()" is the method name.
2. User Define Packages
To create a package is quite easy: simply include a package command in the first line of the
source file. A class specified in that file belongs to that package. The package statement defines a
name space in which classes are stored. If you omit the package statement, the class names are put
in the default package, which has no name.
The general form of the package statement will be as followed: package pkg;
Here, "pkg" is the package name. Example: package MyPackage;
Java Uses file system directories to store packages. For example, the " .class" files for any
classes you declare to be part of the "MyPackage" must be store in the "MyPackage" directory. The
directory name "MyPackage" is different from "mypackage".
Notes: 1. The case for the package name is significant.
2. The directory name must match with package name.
We can create hierarchy of packages. To do so, simply separate package name from the
above one with it by use of the dot (.) operator. The general form of multileveled package statement
is shown here: package pkg1.pkg2.pkg3;
Example: package iicse.asection.java
Open a notepad or text editor, write the above code and save it as "Balance.java" in the
folder name "Mypackage. Here, the package name and subdirectory(folder) name must be same.
This subdirectory(Folder) must be part of your main current directory (current Folder) in which you
write the main class PackTest1.java. That means the "PackTest1.java" source file and "MyPackage"
will be in the same directory (Folder). The "Balance.java" file must be compiled to generate the
".class" file in the same directory(folder), which will be accessed in another program by importing
the package.
PackTest1.java
Output
Unit 3: Inheritance , Interfaces, Packages, Exceptions and Assertions
The Subdirectory "MyPackage" and the "PackTest 1"are in the same folder
- "private" members are accessed by only other members of its class. A private member is
unaffected by its membership in a package.
- A member specified as "protected" is accessed within its package and to all subclasses.
A.java
package p1;
public class A
{
// body of the class
}
Here, the package p1 contains one public class by the name A. Suppose if we want to add another
class B to this package. This can be done as follows:
4. Compile "B.java" file by switching to the subdirectory. This will create "B.class" file and place
it in the directory p1.
Now the package p1 will contain both A.class and B.class files
Introduction to Interfaces
Java supports the concept of Inheritance, that is acquiring the properties from one class to
other class. The class that acquire properties is called "subclass", and the class from which it acquire
is called "superclass". Here, one class can acquire properties from other class using the following
statement:
class A extends B
{
---------
---------
}
But, Java does not allow to acquire properties from more than one class, which we call it as
"multiple inheritance". We know that large number of real-life applications require the use of
multiple inheritance. Java provides an alternative approach known as "interface" to support the
concept of multiple inheritance.
Defining Interface
An interface is basically a kind of class. Like classes, interfaces contain the methods and
variables but with major difference. The difference is that interface define only abstract methods
and final fields. This means that interface do not specify any code to implement these methods and
data fields contain only constants. Therefore, it is the responsibility of the class that implements an
interface to define the code for these methods.
The syntax of defining an interface is very similar to that of class. The general form of an
interface will be as follows:
interface Interface_Name
{
variable declaration;
method declaration;
}
Here, interface is the keyword and the Interface_Name is any valid name for interface. The variables
are declared as follows:
static final type variable_name=value;
Note: All variable are declared as constants. Methods declaration will contain only a list of methods
without any body statement. For example:
Here is an example of an interface definition that contain two variable and one method
interface Area
{
static final double pi=3.14;
static final String name="Java";
Unit 3: Inheritance , Interfaces, Packages, Exceptions and Assertions
void display();
}
Interfaces are used as "superclasses" whose properties are inherited by the classes. It is
therefore necessary to create a class that inherits the given interface. This is done as follows:
Here, Class_Name class, implements the interface "Interface_Name". A more general form
of implementation may look like this:
This shows that a class can extend another class while implementing interfaces. When a class
implements more than one interface they are separated by a comma.
{
public static void main(String args[])
{
Rectangle rec= new Rectangle();
Circle c=new Circle();
Area area;
area=rec; //reference double
a=area.compute(10,20); System.out.println("The
area of the rectangle is "+a);
area=c;
a=area.compute(10,5);
System.out.println("The area of the Circle is "+a);
}
}
OutPut:
Like classes interfaces also can be extended. That is, an interface can be subinterfaced from
other interface. The new subinterface will inherit all the members from the superinterface in the
manner similar to the subclass. This is achieved using the keyword extends as shown here:
interface Const
{
static final int code=501;
static final String branch="CSE";
}
interface Item extends Const
{
void display();
Unit 3: Inheritance , Interfaces, Packages, Exceptions and Assertions
}
class Menu implements Item
{
public void display()
{
System.out.println("The Branch code is "+code+" and the Branch is "+branch);
}
}
class MenuTest{
public static void main(String args[])
{
Menu m=new Menu(); // this contains the interfaces Item and Const
m.display();
}
}
Output:
Introduction to Exception
Syntax:
try
{
// block of code to monitor for errors
}
catch (ExceptionType1 exOb)
{
// exception handler for ExceptionType1
}
catch (ExceptionType2 exOb)
{
// exception handler for ExceptionType2
}
// ...
finally
{
// block of code to be executed after try block ends
}
Exception Types
All exception types are subclasses of the built-in class Throwable. Thus, Throwable
is at the top of the exception class hierarchy. Immediately below (Fig 2) Throwable are two
subclasses that partition exceptions into two distinct branches. One branch is headed by
Exception. This class is used for exceptional conditions that user programs should catch.
This is also the class that you will subclass to create your own custom exception types. There
is an important subclass of Exception, called RuntimeException. Exceptions of this type are
automatically defined for the programs that you write and include things such as division by
zero and invalid array indexing.
Unit 3: Inheritance , Interfaces, Packages, Exceptions and Assertions
The other branch is topped by Error, which defines exceptions that are not expected
to be caught under normal circumstances by your program. Exceptions of type Error are
used by the Java run-time system to indicate errors having to do with the run-time
environment, itself. Stack overflow is an example of such an error. This chapter will not be
dealing with exceptions of type Error, because these are typically created in response to
catastrophic failures that cannot usually be handled by your program.
Throwable class
Exception class
Error
Uncaught Exceptions:
Before you learn how to handle exceptions in your program, it is useful to see what happens
when you don’t handle them. This small program includes an expression that intentionally
causes a divide-by-zero error:
class Exc0
{
public static void main(String args[])
{
int d = 0;
Unit 3: Inheritance , Interfaces, Packages, Exceptions and Assertions
int a = 42 / d;
}
}
When the Java run-time system detects the attempt to divide by zero, it constructs a
new exception object and then throws this exception. This causes the execution of Exc0 to
stop, because once an exception has been thrown, it must be caught by an exception handler
and dealt with immediately.
In the above program we have not provided any exception handler, in this context the
exception is caught by the default handler. The default handler displays string describing
the exception.
Here is the exception generated when this example is executed:
java.lang.ArithmeticException: / by zero
at Exc0.main(Exc0.java:4)
Notice how the class name, Exc0; the method name, main; the filename, Exc0.java; and the
line number, 4, are all included in the simple stack trace. Also, notice that the type of
exception thrown is a subclass of Exception called ArithmeticException, which more
specifically describes what type of error happened.
To guard against and handle a run-time error, simply enclose the code that you want to
monitor inside a try block. Immediately following the try block, include a catch clause that
specifies the exception type that you wish to catch. To illustrate how easily this can be done,
the following program includes a try block and a catch clause that processes the
ArithmeticException generated by the division-by-zero error:
Exc2.java
class Exc2
{
public static void main(String args[])
{
int d, a;
try {
// monitor a block of code.
d = 0;
a = 42 / d;
System.out.println("This will not be printed.");
Unit 3: Inheritance , Interfaces, Packages, Exceptions and Assertions
}
catch (ArithmeticException e)
{ // catch divide-by-zero error
System.out.println("Division by zero.");
}
System.out.println("After catch statement.");
}
}
Note: println() statement inside the "try" will never execute, because once the exception is
raised the control is transferred to the "catch" block. Here is catch is not called, hence it will
not return the control back to the "try" block. The "try" and "catch" will form like a unit. A
catch statement cannot handle the exception thrown by another "try" block.
catch(ArithmeticException e)
{
System.out.println("Divide by 0: " + e);
}
catch(ArrayIndexOutOfBoundsException e)
{
System.out.println("Array index oob: " + e);
}
System.out.println("After try/catch blocks.");
}
}
The try statement can be nested. That is, a try statement can be inside the block of another
try. Each time a try statement is entered, the context of that exception is pushed on the stack.
If an inner try statement does not have a catch handler for a particular exception, the stack is
unwound and the next try statement’s catch handlers are inspected for a match. This
continues until one of the catch statements succeeds, or until all of the nested try statements
are exhausted. If no catch statement matches, then the Java run-time system will handle the
exception.
throw:
So far, you have only been catching exceptions that are thrown by the Java run-time system
implicitly. However, it is possible for your program to throw an exception explicitly, using
the throw statement. The general form of throw is shown here:
throw ThrowableInstance;
throws:
If a method is capable of causing an exception that it does not handle, it must specify this
behavior so that callers of the method can guard themselves against that exception. You do
this by including a throws clause in the method’s declaration. A throws clause lists the types
of exceptions that a method might throw. This is necessary for all exceptions, except those of
type Error or RuntimeException, or any of their subclasses. All other exceptions that a
method can throw must be declared in the throws clause. If they are not, a compile-time error
will result.
This is the general form of a method declaration that includes a throws clause:
Here, exception-list is a comma-separated list of the exceptions that a method can throw.
Example Program:
ThrowsDemo.java
import java.io.*;
class ThrowsDemo
{
public static char prompt(String str) throws IOException, ArithmeticException
{
//called method throws two exceptions
System.out.println(str+":");
int x=20,y=0;
int z=x/y;
return (char) System.in.read();
}
Unit 3: Inheritance , Interfaces, Packages, Exceptions and Assertions
finally:
The finally block is always is executed. It is always used to perform house keeping
operations such as releasing the resources, closing the files that already opened etc,. That
means the statement that put inside the finally block are executed compulsorily. It is always
followed by the try-catch statements.
Syntax:
try
{
// statements
}
catch(Exception e) {
//Handlers
}
finally
{
//statements
}
Exception encapsulation and enrichment
Unit 3: Inheritance , Interfaces, Packages, Exceptions and Assertions
The process of wrapping the caught exception in a different exception is called "Exception
Encapsulation". The Throwable super class has added one parameter in its constructor for the
wrapped exception and a "getCause()" method to return the wrapped exception. Wrapping is
also used to hide the details of implementation.
Syntax:
try
{
throw new ArithmeticException();
}
catch(AritmeticExceptions ae)
{
//wrapping exception
throw new ExcepDemo("Testing User Exception",ae);
}
Disadvantages of wrapping:
It leads to the long Stack traces.
It is a difficult task to figure out where the exception is
Solution:
The possible solution is Exception enrichment. Here we don’t wrap exception but we add
some information to the already thrown exception and rethrow it.
Example program:
testException();
}
catch(Exception e)
{
System.out.println(e);
}
}
}
Assertions:
Assertions are added after java 1.4 to always createreliable programs that are Correct and
robust programs. The assertions are boolean expressions.Conditions such as positve number
or negative number are examples.
Syntax:
assert expression1;
or
assert expression1:expression2;
Where assert is the keyword. Expression 1 is the boolean expression, expression2 is the
string that describes the Exceptions.
Note: assertions must be explicitly enabled. The –ea option is used to enable the exception
and –da is used to disable the exception.
AI.java
class AI
{
static void check(int i)
{
assert i>0:" I must be positive:";
System.out.prinln("Your I value if fine");
}
pulbic static void main(String args[])
{
check(Integer.parseInt(args[0]);
}
}