Unit 2
Unit 2
INHERITANCE BASICS
Unit-2
UNIT – II
A Closer Look at Methods and Classes:
Controlling Access to Class Members, Pass Objects to Methods,
How Arguments are passed, Returning Objects, Method
Overloading, Overloading Constructors, Recursion, Understanding
Static, Introducing Nested and Inner Classes, Varargs: Variable-
Length Arguments. Inheritance
Inheritance Basics
Member Access and Inheritance, Constructors and Inheritance,
Using super to Call Superclass constructors, Using super to Access
Superclass Members, Creating a Multilevel Hierarchy, When are
Constructors Executed, Superclass References and Subclass
Objects, Method Overriding, Overridden Methods support
polymorphism, Why Overridden Methods, Using Abstract Classes,
Using final, The Object Class.
Controlling Access to Class Members
Private
It can be accessed only by other methods defined by its
class
Public
Can be freely accessed by the code defined outside the
class
Default
Java’s access modifiers
Public
Private
Protected
Default (if nothing specified assumes but same as
public)
public int i;
private double j;
private int myMethod(int a, char b) { //...
Example
/* This program demonstrates the difference between public and private. */
class Test {
int a; // default access
public int b; // public access
private int c; // private access
// methods to access c
void setc(int i) { // set c's value
c = i;
}
int getc()
{ // get c's value
return c;
}
}
Example
class AccessTest {
public static void main(String args[]) {
Test ob = new Test();
// These are OK, a and b may be accessed directly
ob.a = 10;
ob.b = 20;
// This is not OK and will cause an error
// ob.c = 100; // Error!
// You must access c through its methods
ob.setc(100); // OK
System.out.println("a, b, and c: " + ob.a + " " +
ob.b + " " + ob.getc());
}
}
Using Objects as Parameters
class Test {
int a, b;
Test(int i, int j) { class PassOb {
a = i; public static void main(String args[]) {
b = j; Test ob1 = new Test(100, 22);
} Test ob2 = new Test(100, 22);
boolean equalTo(Test o) { Test ob3 = new Test(-1, -1);
if(o.a == a && o.b == b) System.out.println("ob1 == ob2: " +
return true; ob1.equalTo(ob2));
else System.out.println("ob1 == ob3: " +
return false; ob1.equalTo(ob3));
} }
} }
Output:
ob1 == ob2: true
ob1 == ob3: false
A Closer Look at Argument Passing
How Arguments are Passed
Output:
before call: 15 20
after call: 30 10
Returning the Objects
A method can return any type of data
Include the class object then its called the returning
the class object
class Test {
int a;
Test(int i) {
a = i;
}
Test incrByTen() {
Test temp = new Test(a+10);
return temp;
}
}
Example
class RetOb {
public static void main(String args[]) {
Test ob1 = new Test(2);
Test ob2;
ob2 = ob1.incrByTen();
System.out.println("ob1.a: " + ob1.a);
System.out.println("ob2.a: " + ob2.a);
ob2 = ob2.incrByTen();
System.out.println("ob2.a after second increase: “ + ob2.a);
}
}
Factorial of 3 is 6
Factorial of 4 is 24
Factorial of 5 is 120
Understanding static
When a member is declared static, it can be
accessed before any objects of its class are
created, and without reference to any object.
Instance variables declared as static are global
variables.
When objects of its class are declared, no copy of
a static variable is made.
Instead, all instances of the class share the same
static variable.
Methods declared as static have several
restrictions:
They can only directly call other static methods.
They can only directly access static data.
They cannot refer to this or super in any way.
Example
// Demonstrate static variables, methods, and blocks.
class UseStatic {
static int a = 3;
static int b;
static void meth(int x) {
System.out.println("x = " + x);
System.out.println("a = " + a);
System.out.println("b = " + b);
}
static {
System.out.println("Static block initialized.");
b = a * 4;
} output of the program:
public static void main(String args[]) { Static block initialized.
meth(42); x = 42
} a=3
} b = 12
Outside of the class in which they are defined, static
methods and variables can be used independently of
any object.
For example, if you wish to call a static method from
outside its class, you can do so using the following
general form:
classname.method( )
A static variable can be accessed in the same way—by
use of the dot operator on the name of the class.
This is how Java implements a controlled version of
global methods and global variables.
Example
class StaticDemo {
static int a = 42;
static int b = 99;
static void callme() {
System.out.println("a = " + a);
}
}
class StaticByName {
public static void main(String args[]) {
StaticDemo.callme();
System.out.println("b = " + StaticDemo.b);
}
}
a = 42
b = 99
Recall
Static Method
Directly call only static methods
Directly access only static data
class NestedClasssDemo {
public static void main(String args[]) {
Int x={3,2,1,5,6,9,7,8};
Outer outob=new Outer(x);
Outob.analyze();
}
}
Output
minimum-:1
Maximim:9
Average:5
Varargs: Variable-Length Arguments
Beginning with JDK 5, Java has included a feature that
simplifies the creation of methods that need to take a
variable number of arguments. This feature is called
varargs
it is short for variable-length arguments.
A method that takes a variable number of arguments is
called a variable-arity method, or simply a varargs
method.
A variable-length argument is specified by three
periods (…). For example, here is how vaTest( ) is
written using a vararg:
static void vaTest(int ... v) {
Example-1
// Demonstrate variable-length arguments.
class VarArgs {
static void vaTest(int ... v) {
System.out.print("Number of args: " + v.length +
" Contents: ");
for(int i=0;i<v.length;i++)
System.out.print(“arg”+i+”:” + v[i]);
System.out.println();
}
public static void main(String args[])
{
vaTest(10); // 1 arg
vaTest(1, 2, 3); // 3 args
vaTest(); // no args
}
}
Example-2
// Demonstrate variable-length arguments.
class VarArgs {
static void vaTest(String msg,int ... v) {
System.out.print("Number of args: " + v.length +
" Contents: ");
for(int i=0;i<v.length;i++)
System.out.print(“arg”+i+”:” + v[i]);
System.out.println();
}
public static void main(String args[])
{
vaTest(“one”,10); // 1 arg
vaTest(“Three”,1, 2, 3); // 3 args
vaTest(“no arguments”); // no args
}
}
Points
The varargs parameter must be at last
Overloading varargs can be done
Varargs and Ambiguity
int doIt(int a, int b, double c, int ... vals, boolean stopFlag) { // Error!
Example
class VarArgs4 {
static void vaTest(int ... v) {
System.out.print("vaTest(int ...): " +
"Number of args: " + v.length +
" Contents: ");
for(int x : v)
System.out.print(x + " ");
System.out.println();
}
static void vaTest(boolean ... v) { public static void main(String args[])
System.out.print("vaTest(boolean ...) " + {
"Number of args: " + v.length + vaTest(1, 2, 3); // OK
" Contents: ");
vaTest(true, false, false); // OK
for(boolean x : v)
vaTest(); // Error: Ambiguous!
System.out.print(x + " ");
}
System.out.println();
} }
Inheritance Basics
Inheritance
Inheritance in Java is a mechanism in which one
object acquires all the properties and behaviours of
parent object.
The idea behind inheritance in Java is that you can
create new classes that are built upon existing
classes.
Reuse methods and fields of the parent class.
Inheritance represents the IS-A relationship which is
also known as a parent-child relationship.
Terms used in Inheritance
Class: A class is a group of objects which have common
properties. It is a template or blueprint from which objects are
created.
Sub Class/Child Class: Subclass is a class which inherits the other
class. It is also called a derived class, extended class, or child
class.
Super Class/Parent Class: Superclass is the class from where a
subclass inherits the features. It is also called a base class or a
parent class.
Reusability: As the name specifies, reusability is a mechanism
which facilitates you to reuse the fields and methods of the
existing class when you create a new class.
class Subclass-name extends Superclass-name
{
//methods and fields
}
Example
class A { class SimpleInheritance {
int i, j; public static void main(String args []) {
void showij() { A superOb = new A();
System.out.println("i and j: " + i + " " + j); B subOb = new B();
} superOb.i = 10; superOb.j = 20;
} System.out.println("Contents of superOb: ");
superOb.showij();
class B extends A { System.out.println();
int k; subOb.i = 7; subOb.j = 8;
void showk() { subOb.k = 9;
System.out.println("k: " + k); System.out.println("Contents of subOb: ");
} subOb.showij(); subOb.showk();
void sum() { System.out.println();
System.out.println("i+j+k: " + (i+j+k)); System.out.println("Sum of i, j and k in
} subOb:");
} subOb.sum();
}
}
Contents of superOb:
i and j: 10 20
Contents of subOb:
i and j: 7 8
k: 9
Sum of i, j and k in subOb:
i+j+k: 24
Example – Inheritance
Class TwoDShape{
double w;
double h;
void showdim(){
System.out.println(“Width and Heigth are” +w + “and”+h);
}
}
class B extends A {
int i;
System.out.println(“T2 information”);
t2.showstyle(); t2.showdim(); t2.showColor();
System.out.println(“Area is ”+t2.area());
}
}
Point to be recalled
class Animal{
String color="white";
}
class Dog extends Animal{
Point to be recalled
String color="black";
void printColor(){
System.out.println(color);//prints color of Dog class
System.out.println(super.color);//prints color of Animal class
}
}
class TestSuper1{
public static void main(String args[]){
Dog d=new Dog();
d.printColor();
}}
class Animal{
void eat(){System.out.println("eating...");}
}
class Dog extends Animal{
void eat(){System.out.println("eating bread...");}
void bark(){System.out.println("barking...");}
void work(){
super.eat();
bark();
}
}
class TestSuper2{
public static void main(String args[]){
Dog d=new Dog();
d.work();
}}
class Animal{
Animal(){System.out.println("animal is created");}
}
class Dog extends Animal{
Dog(){
super();
System.out.println("dog is created");
}
}
class TestSuper3{
public static void main(String args[]){
Dog d=new Dog();
}}
A reference of one class type cannot normally refer
to object of another class type.
In Java strict type enforcement
A reference variable of a super class can be assigned
a reference object of any subclass derived from that
super class
Or A superclass reference can refer to a subclass
object
Example -1
Class X{ Class X{
Int a; Int a;
X(int i){a=i;} X(int i){a=i;}
Class Y{ Class Y extends X{
Int a; Int a;
Y(int i){a=i;} Y(int i,int j){
Class Incomp{ super(i);
public static void main(String a=i;}
args[]){ Class SupSubRef{
X x=new X(10); public static void main(String args[]){
X x2; X x=new X(10);
Y y=new Y(5); X x2;
x2=x; Y y=new Y(5,6);
X2=y; x2=x;
} X2=y;
}
Example -2
Class TwoDShape{
Private double w;
Private double h;
TwoDshape(TwoDShape ob){
w=ob.w;h=ob.h;}
double getwidth(){ return w};
double getheigth(){ return h};
void setwidth(double w1){w=w1};
void setheigth(double h1){h=h1};
void showdim(){
System.out.println(“Width and Heigth are” +w + “and”+h);
}
}
Class Triangle extends TwoDShape{ Class Shape{
String style; {
Public static void main(String args[]){
Triangle(Triangle ob){
Triangle t1=new Triangle(“Outlined”,8,12);
Super(ob);
style=ob.style; Triangle t2=new Triangle(t1);
} System.out.println(“T1”);
double area(){ t1.showstyle(); t1.showdim();
return getwidth()* getheigth()/2; System.out.println(“Area”+t1.area());
} System.out.println(“T2”);
void showstyle{ t2.showstyle(); t2.showdim();
System.out.println(“Triangle System.out.println(“Area”+t2.area());
}
is”+style);}
}
}
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.
Example
class A class B extends A
{ {
int i, j; A(int a, int b) int k;
{ B(int a, int b, int c)
i = a; j = b; {
} super(a, b); k = c;
void show() { }
System.out.println("i and j: " + i + " void show() {
" + j); System.out.println("k: " + k); }
} } }
class Override
{
public static void main(String args[])
{
B subOb = new B(1, 2, 3);
subOb.show(); Output:
} } k: 3
void show()
{
super.show(); // this calls A's show()
System.out.println("k: " + k);
}
Dynamic Method Dispatch
Dynamic Method Dispatch is the mechanism by which a
call to an overridden method is resolved at run time,
rather than compile time.
Dynamic method dispatch is important because this is
how Java implements run-time polymorphism.
Java uses this fact to resolve calls to overridden
methods at run time.
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.
Example
class A { class Dispatch {
void callme() { public static void main(String args[]) {
System.out.println("Inside A's callme method"); A a = new A(); // object of type A
} B b = new B(); // object of type B
} C c = new C(); // object of type C
class B extends A { A r; // obtain a reference of type A
void callme() { r = a; // r refers to an A object
System.out.println("Inside B's callme method"); r.callme(); // calls A's version of callme
} r = b; // r refers to a B object
} r.callme(); // calls B's version of callme
class C extends A { r = c; // r refers to a C object
void callme() { r.callme(); // calls C's version of callme
System.out.println("Inside C's callme method"); }
} }
}
Inside A's callme method
Had it been determined by the type of the reference
variable, r, you would see three calls to A’s callme( ) Inside B's callme method
method. Inside C's callme method
Why Overridden Methods?
Polymorphism is essential to object-oriented
programming for one reason: it allows a general
class to specify methods that will be common to all
of its derivatives, while allowing subclasses to
define the specific implementation of some or all of
those methods.
Overridden methods are another way that Java
implements the “one interface, multiple methods”
aspect of polymorphism.
Successfully applying polymorphism is
understanding that the super classes and subclasses
form a hierarchy which moves from lesser to greater
specialization.
Combining inheritance with overridden methods, a
superclass can define the general form of the
methods that will be used by all of its subclasses.
Dynamic, run-time polymorphism is one of the most
powerful mechanisms that object oriented design
brings to bear on code reuse and robustness.
Using Abstract Classes
Situations in which you will want to define a superclass that
declares the structure of a given abstraction without
providing a complete implementation of every method.
Sometimes you will want to create a superclass that only
defines a generalized form that will be shared by all of its
subclasses, leaving it to each subclass to fill in the details
A method which does not contain any definition in the
superclass is termed as abstract method.
Such a method declaration should be preceded by the
keyword abstract.
Methods are sometimes referred to as subclasser
responsibility because they have no implementation
specified in the superclass.
abstract type name(parameter-list);
The Abstract modifier can be used for normal
methods
It cannot be applied for static or to constructors
A class that contains one or more abstract method
must be declared as abstract by preceding class
declaration with abstract modifier.
Abstract classes can not be instantiated, that is one
cannot create an object of abstract class. Whereas,
a reference can be created for an abstract class.
Example-1
abstract class A class B extends A
{ {
abstract void callme(); void callme()
void callmetoo() {
{ System.out.println("B's implementation of
System.out.println("This is a concrete callme.");
method."); }
} }
}
class AbstractDemo {
public static void main(String args[])
{
B b = new B();
b.callme();
b.callmetoo();
}
}
Example -2
class Triangle extends Shape
abstract class Shape
{
{
int b, h;
final double PI= 3.1416;
Triangle(int x, int y) //constructor
abstract double area();
{
}
b=x; h=y;
}
Output:
Area of Triangle is:6.0
Area of Rectangle is:30.0
Area of Circle is:12.5664
Recall Points
Using Final