0% found this document useful (0 votes)
2 views

Oop Using Java - Unit II

Uploaded by

anandhi.k
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

Oop Using Java - Unit II

Uploaded by

anandhi.k
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 37

Object Oriented

Programming using Java


Unit - II: A Closer look at Methods and Classes
Overloading Methods
● The methods are overloaded, when two or more methods within the same
class share the same name, as long as their parameter declarations are
different.
● Method overloading is one of the ways that Java supports Polymorphism
● Java uses the type and/or number of arguments as the guide to determine
which version of the overloaded method to call.
Overloading Methods - An Example
class OverloadDemo {
void test() { class Overload {
System.out.println("No parameters");
public static void main(String[] args) {
}
OverloadDemo ob = new OverloadDemo();
// Overload test for one integer parameter
double result;
void test(int a) {
System.out.println("a: " + a);
}
// call all versions of test()
// Overload test for two integer parameters ob.test();
void test(int a, int b) {
ob.test(10);
System.out.println("a and b: " + a + " " + b);
} ob.test(10, 20);
result = ob.test(123.25);
// Overload test for a double parameter and return a double value
double test(double a) { System.out.println("Result of ob.test(123.25): " +
System.out.println("double a: " + a); result);
return a * a;
} }
} }

Output:
Overloading Methods - Continued
● Java looks for a match between the arguments used to call an overloaded
method. however, match need not always be exact.
● In some cases, Java automatically type convert the overload resolution.
An example
// Automatic type conversions apply to overloading. class Overload2 {
class OverloadDemo { public static void main(String[] args) {
void test() { OverloadDemo ob = new OverloadDemo();
System.out.println("No parameters"); int i = 88;
}

// call all versions of test()


// Overload test for two integer parameters
ob.test();
void test(int a, int b) {
ob.test(10, 20);
System.out.println("a and b: " + a + " " + b);
} ob.test(i); // this will invoke
test(double)
// Overload test for a double parameter and return ob.test(123.2); // this will invoke
a double value test(double)
double test(double a) {
System.out.println("double a: " + a); }
return a * a; }
}
}
Output:
Overloading Constructors
/* Here, Box defines three constructors to initialize the dimensions of a box in various ways. */
class Box {
class OverloadCons {
double width ;
public static void main (String [] args ) {
double height ;
double depth ; // create boxes using the various constructors
Box mybox1 = new Box (10, 20, 15);
// constructor used when all dimensions specified Box mybox2 = new Box ();
Box (double w, double h, double d) { Box mycube = new Box (7);
width = w;
height = h;
double vol ;
depth = d;
}
// get volume of first box
// constructor used when no dimensions specified vol = mybox1 .volume ();
Box () { System .out .println ("Volume of mybox1 is " + vol );
width = -1; // use -1 to indicate
height = -1; // an uninitialized // get volume of second box
depth = -1; // box
vol = mybox2 .volume ();
}
System .out .println ("Volume of mybox2 is " + vol );

// constructor used when cube is created


Box (double len ) { // get volume of cube
width = height = depth = len ; vol = mycube .volume ();
} System .out .println ("Volume of mycube is " + vol );
}
// compute and return volume
}
double volume () {
return width * height * depth ;
}
}

Output:
Using Objects as Parameters
● We can pass objects to methods as params
class Test { class PassOb {
int a, b; public static void main(String args[]) {
Test ob1 = new Test(100, 22);
Test(int i, int j) { Test ob2 = new Test(100, 22);
a = i; Test ob3 = new Test(-1, -1);
b = j;
} System.out.println("ob1 == ob2: " +
ob1.equalTo(ob2));
// return true if o is equal to the invoking object System.out.println("ob1 == ob3: " +
boolean equalTo(Test o) { ob1.equalTo(ob3));
if (o.a == a && o.b == b) }
return true; }
else
return false;
}
}
Using Objects as Parameters
● the equalTo() method inside test compares two objects for equality and then
returns the result.
● it compares the invoking object with the one that is passed.
● if they contain the same values, then the method returns true. otherwise it
returns false.
● the parameter o in equalTo() specifies Test as its type.
Using Objects as Parameters
● We can construct a new object so that it is initially the same as some existing object.
● To do this, we must define a constructor that takes an object of its class as a parameter.
● Example: public class OverloadCons2 {
public static void main (String args []) {
// create boxes using the various constructors
Box mybox1 = new Box (10, 20, 15);
class Box { // constructor used when no Box mybox2 = new Box ();
Box mycube = new Box (7);
double width; dimensions specified
double height; Box() { Box myclone = new Box (mybox1 ); // create copy of mybox1

double depth;
width = -1; // use -1 to indicate double vol ;

height = -1; // an uninitialized // get volume of first box


// Notice this constructor. It takes an vol = mybox1 .volume ();
depth = -1; // box
object of type Box. System .out .println ("Volume of mybox1 is " + vol );

Box(Box ob) { // pass object to


}
// get volume of second box
constructor vol = mybox2 .volume ();
System .out .println ("Volume of mybox2 is " + vol );
width = ob.width; // constructor used when cube is
height = ob.height; created // get volume of cube
vol = mycube .volume ();
depth = ob.depth; Box(double len) { System .out .println ("Volume of mycube is " + vol );

} width = height = depth = len;


// get volume of clone
} vol = myclone .volume ();

// constructor used when all dimensions System .out .println ("Volume of myclone is " + vol );
}
specified }
// compute and return volume
Box(double w, double h, double d) {
double volume() {
width = w;
return width * height * depth;
height = h;
depth = d; }
} }
A closer look at Argument Passing
- there are two ways a computer language can pass arguments to a function
- call by value : the value of the argument is copied into the function parameter
- call by reference : the argument is a reference to an object in memory
- although java uses call by value, to pass all arguments, the precise effect differs
between whether a primitive type or a reference type is passed
- when a primitive type is passed, the value of the argument is copied into the function
parameter public class CallByValue {
public static void main(String args[]) {
class Test { Test ob = new Test();

// This method causes no change to the int a = 15, b = 20;


arguments used in the call.
System.out.println("a and b before call: " + a + " " + b);
void meth(int i, int j) {
i *= 2; ob.meth(a, b);

j /= 2; System.out.println("a and b after call: " + a + " " + b);


}
}
} }
A closer look at Argument Passing
● the operations that occur inside meth() have no effect on the values of a and b used in the call; their values here did not
change to 30 and 10.
● when you pass an object to a method, the situation changes dramatically, because objects are passed by what is effectively
call-by-reference.

class Test { public class PassObjRef {

int a, b; public static void main(String args[]) {


Test ob = new Test(15, 20);

Test(int i, int j) {
a = i; System.out.println("ob.a and ob.b before

b = j; call: " + ob.a + " " + ob.b);

}
ob.meth(ob);

// pass an object
void meth(Test o) { System.out.println("ob.a and ob.b after
call: " + ob.a + " " + ob.b);
o.a *= 2;
o.b /= 2; }

} }

}
Returning Objects
● a method can return any type of data, including class types that you create.
● Example:
public class RetOb {
public static void main(String args[]) {
Test ob1 = new Test(2);
Test ob2;
// Returning an object
class Test {
ob2 = ob1.incrByTen();
int a;

System.out.println("ob1.a: " + ob1.a);


Test(int i) {
System.out.println("ob2.a: " + ob2.a);
a = i;
}
ob2 = ob2.incrByTen();

Test incrByTen() {
System.out.println("ob2.a after second
Test temp = new Test(a + 10);
increase: " + ob2.a);
return temp;
}
}
}
}
Recursion
● Java supports Recursion
● Recursion is a process of defining something in terms of itself.
● Recursion is the attribute that allows a method to call itself.
● A method that calls itself is said to be recursive.

public class Recursion {


// A simple example of recursion.
public static void main(String args[]) {
class Factorial {
Factorial f = new Factorial();
// This is a recursive function.
int fact(int n) {
System.out.println("Factorial of 3 is " +
int result;
f.fact(3));
System.out.println("Factorial of 4 is " +
if (n == 1)
f.fact(4));
return 1;
System.out.println("Factorial of 5 is " +
result = fact(n - 1) * n;
f.fact(5));
return result;
}
}
}
}
Another example of Recursion

public class Recursion2 {


class RecTest { public static void main(String args[]) {
int values[]; RecTest ob = new RecTest(10);

RecTest(int i) { int i;
values = new int[i];
} for (i = 0; i < 10; i++)
ob.values[i] = i;
// display array -- recursively
void printArray(int i) { ob.printArray(10);
if (i == 0) }
return; }
else
printArray(i - 1);
System.out.println("[" + (i - 1) + "] " +
values[i - 1]);
}
}
Introducing Access Control
● encapsulation links data with the code that manipulates it.
● encapsulation provides another important attribute: access control
● through encapsulation, you can control what parts of a program can access the
members of a class.
● by controlling access, you can prevent misuse.
● for example: allowing access to data only through a well-defined set of methods,
you can prevent the misuse of that data.
● thus, when correctly implemented, a class creates a “black box” which may be used,
but the inner workings of which are not open to tampering.
● how a member can be accessed is determined by the access modifier attached to
its declaration.
● some aspects of access control are related mostly to inheritance or packages.
● A package is essentially a collection of classes.
Java’s access modifiers
● public, private, protected
● java also defines default access level.
● protected applies only when inheritance is involved.
● when a member of a class is modified by public, then that member can be
accessed by any other code.
● when a member of a class is specified as private, then that member can only
be accessed by other members of its class.
Introducing Access Control
public class AccessTest {
public static void main(String args[]) {
Test ob = new Test();
/* This program demonstrates the
difference between public and private. */
// These are OK, a and b may be accessed
class Test {
directly
int a; // default access
ob.a = 10;
public int b; // public access
ob.b = 20;
private int c; // private access

// This is not OK and will cause an error


// methods to access c
// ob.c = 100; // Error!
void setc(int i) { // set c's value
c = i;
// You must access c through its methods
}
ob.setc(100); // OK
System.out.println("a, b, and c: " + ob.a
int getc() { // get c's value
+ " " + ob.b + " " + ob.getc());
return c;
}
}
}
}
class TestStack {
public static void main (String args []) {
Stack mystack1 = new Stack ();
Stack mystack2 = new Stack ();

Access Control - Stack Example


// push some numbers onto the stack
for (int i = 0; i < 10; i++)
mystack1 .push (i);
for (int i = 10; i < 20; i++)
mystack2 .push (i);

// pop those numbers off the stack


System .out .println ("Stack in mystack1:" );
// This class defines an integer stack
// Push an item onto the stack for (int i = 0; i < 10; i++)
System .out .println (mystack1 .pop ());
that can hold 10 values.
void push(int item) {
System .out .println ("Stack in mystack2:" );
class Stack {
if (tos == 9) for (int i = 0; i < 10; i++)
System .out .println (mystack2 .pop ());
/*
System.out.println("Stack is full.");
* Now, both stck and tos are private. // these statements are not legal
else // mystack1.tos = -2;

This means // mystack2.stck[3] = 100;


stck[++tos] = item; }

* that they cannot be accidentally or }


}
maliciously
* altered in a way that would be harmful
// Pop an item from the stack
to the stack.
int pop() {
*/
if (tos < 0) {
private int stck[] = new int[10];
System.out.println("Stack underflow.");
private int tos;
return 0;
} else
// Initialize top-of-stack
return stck[tos--];
Stack() {
}
tos = -1;
}
}
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.
● you can declare both methods and variables to be static.
● instance variables declared as static are essentially 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.
Static Methods
● 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.
● if you need to do computation in order to initialize your static variables, you
can declare a static block that gets executed exactly once, when the class is
first loaded.
static {
public class UseStatic { System.out.println("Static block
static int a = 3; initialized.");
static int b; b = a * 4;
}
static void meth(int x) {
System.out.println("x = " + x); public static void main(String args[]) {
System.out.println("a = " + a); meth(42);
System.out.println("b = " + b); }
} }
Understanding Static
● Example: Inside main(), the static method callme() and the static variable b are accessed through their class name
StaticDemo

public class StaticDemo {


static int a = 42;
static int b = 99;

static void callme() {


System.out.println("a = " + a);
}

public static void main(String args[]) {


callme();
System.out.println("b = " + b);
}
}
Introducing final
● a field can be declared as final. doing so prevents its contents from being
modified, making it, essentially, a constant.
● this means that you must intiailize a final field when it is declared.
○ first, you can give it a value when it is declared
○ second, you can assign it a value within a constructor
Arrays Revisited
● Arrays are implemented as objects
● because of this, there is a special array attribute that you will want to take
advantage of.
● the size of an array - that is, the number of elements that an array can hold -
is found in its length instance variable.

public class Length {


public static void main(String args[]) {
int a1[] = new int[10];
int a2[] = { 3, 5, 7, 1, 8, 99, 44, -10 };
int a3[] = { 4, 3, 2, 1 };

System.out.println("length of a1 is " + a1.length);


System.out.println("length of a2 is " + a2.length);
System.out.println("length of a3 is " + a3.length);
}
}
Improved stack class that uses the length array member
// Improved Stack class that uses the
public class TestStack2 {
length array member.
// Pop an item from the stack public static void main(String args[]) {
class Stack { Stack mystack1 = new Stack(5);
int pop() {
private int stck[]; Stack mystack2 = new Stack(8);
if (tos < 0) {
private int tos; // push some numbers onto the stack
System.out.println("Stack underflow.");
for (int i = 0; i < 5; i++)
return 0;
mystack1.push(i);
// allocate and initialize stack
} else for (int i = 0; i < 8; i++)
Stack(int size) { mystack2.push(i);
return stck[tos--];
stck = new int[size];
} // pop those numbers off the stack
tos = -1;
} System.out.println("Stack in mystack1:");
} for (int i = 0; i < 5; i++)
System.out.println(mystack1.pop());

// Push an item onto the stack System.out.println("Stack in mystack2:");


void push(int item) { for (int i = 0; i < 8; i++)
System.out.println(mystack2.pop());
if (tos == stck.length - 1) // use length
}
member }

System.out.println("Stack is full.");
else
stck[++tos] = item;
}
Introducing Nested and Inner Classes
● it is possible to define a class within another class; such classes are known as
nested classes.
● the scope of a nested class is bounded by the scope of its enclosing class
● thus, if class B is defined within class A, then B does not exist independently
of A.
● A nested class has access to the members, including private members, of the
class in which it is nested. however, the enclosing class does not have access
to the members of the nested class.
● a nested class that is directly declared within its enclosing class scope is a
member of its enclosing class.
Nested Classes - Types
● there are two types of nested classes
○ static
○ non-static
● a static nested class is one that has the static modifier applied.
● because it is static, it must access the non-static members of its enclosing class
through an object.
● that is, it cannot refer to non-static members of its enclosing class directly.
● because of this restriction, static nested classes are seldom used.
● the most important type of nested class is the inner class.
● an inner class is a non-static nested class.
● it has access to all of the variables and methods of its outer class and may refer to
them directly in the same way that other non-static members of the outer class do.
Nested Classes - Example

// Demonstrate an inner class.


class Outer { public class InnerClassDemo {

int outer_x = 100; public static void main(String args[]) {


Outer outer = new Outer();

void test() { outer.test();


Inner inner = new Inner(); }

inner.display(); }

// this is an inner class


class Inner {
void display() {
System.out.println("display: outer_x = "
+ outer_x);
}
}
}
Exploring the String class
● Java defines peer classes of String, called StringBuffer and StringBuilder,
which allow strings to be altered, so all of the normal string manipulations are
still available in Java.
public class StringDemo {
public static void main(String args[]) {
String strOb1 = "First String";
String strOb2 = "Second String";
String strOb3 = strOb1 + " and " +
strOb2;

System.out.println(strOb1);
System.out.println(strOb2);
System.out.println(strOb3);
}
}
String class
public class StringDemo2 {
public static void main(String args[]) {
String strOb1 = "First String";
String strOb2 = "Second String";
String strOb3 = strOb1;

System.out.println("Length of strOb1: " + strOb1.length());

System.out.println("Char at index 3 in strOb1: " + strOb1.charAt(3));

if (strOb1.equals(strOb2)) {
System.out.println("strOb1 == strOb2");
} else {
System.out.println("strOb1 != strOb2");
}

if (strOb1.equals(strOb3)) {
System.out.println("strOb1 == strOb3");
} else {
System.out.println("strOb1 != strOb3");
}
}
}
String Class

public class StringDemo3 {


public static void main(String args[]) {
String str[] = { "one", "two", "three" };

for (int i = 0; i < str.length; i++) {


System.out.println("str[" + i + "]: " +
str[i]);
}
}
}
Using command-line arguments

public class CommandLine {


public static void main(String args[]) {
for (int i = 0; i < args.length; i++) {
System.out.println("args[" + i + "]: " +
args[i]);
}
}
}
Varargs: Variable-Length Arguments

public class PassArray {


static void vaTest(int v[]) {
System.out.print("Number of args: " + v.length + " Contents: ");

for (int x : v) {
System.out.print(x + " ");
}

System.out.println();
}

public static void main(String args[]) {


int n1[] = { 10 };
int n2[] = { 1, 2, 3 };
int n3[] = {};

vaTest(n1);
vaTest(n2);
vaTest(n3);
}
}
Demonstrate - Variable length arguments

public class VarArgs {


static void vaTest(int... v) {
System.out.println("Number of args: " + v.length);
System.out.println("Contents: ");

for (int i = 0; i < v.length; i++) {


System.out.println(" arg " + i + ": " + v[i]);
}

System.out.println();
}

public static void main(String args[]) {


vaTest(10);
vaTest(1, 2, 3);
vaTest();
}
}
Varargs continued
public class VarArgs2 {

// Here, msg is a normal parameter and v is a


// varargs parameter.
static void vaTest(String msg, int... v) {
System.out.println(msg + v.length);
System.out.println("Contents: ");

for (int i = 0; i < v.length; i++) {


System.out.println(" arg " + i + ": " + v[i]);
}

System.out.println();
}

public static void main(String args[]) {


vaTest("One vararg: ", 10);
vaTest("Three varargs: ", 1, 2, 3);
vaTest("No varargs: ");
}
}
public static void main(String args[]) {

Overloading Vararg Methods vaTest(1, 2, 3);


vaTest("Testing: ", 10, 20);
vaTest(true, false, false);
}
}

static void vaTest (boolean ... v) {


System .out .println ("vaTest(boolean...): " + "Number of args: " + v.length + " Contents: " );
public class VarArg3 {
static void vaTest(int... v) { for (boolean x : v) {
System .out .print (x + " " );

System.out.println("vaTest(int...): " + }

"Number of args: " + v.length + " System .out .println ();

Contents: "); }

static void vaTest (String msg , int ... v) {


System .out .println ("vaTest(String, int...): " + msg + v.length + " Contents: " );
for (int x : v) {
for (int x : v) {
System.out.print(x + " "); System .out .print (x + " " );
}
}
System .out .println ();

}
System.out.println();

}
Varargs and Ambiguity

// Varargs, overloading, and ambiguity.


// This program contains an error and
static void vaTest(boolean... v) { public static void main(String args[]) {
will not compile!
vaTest(1, 2, 3); // OK
System.out.println("vaTest(boolean ...):
" + "Number of args: " + v.length + " vaTest(true, false, false); // OK
public class VarArgs4 {
static void vaTest(int... v) { Contents: ");
vaTest(); // Error: Ambiguous!
System.out.println("vaTest(int ...): " +
}
"Number of args: " + v.length + " for (boolean x : v) {
}
Contents: "); System.out.print(x + " ");
}

for (int x : v) {
System.out.print(x + " "); System.out.println();

} }

System.out.println();
}
End of Unit II: A Closer look at Methods and Classes

You might also like