Java Tutorial Part 1
Java Tutorial Part 1
Java Tutorial Part 1
Java is a high-level programming language originally developed by Sun Microsystems and released in 1995. Java runs on a variety of platforms, such as Windows, Mac OS, and the various versions of UNIX. This tutorial gives a complete understanding on Java. This reference will take you through simple and practical approach while learning Java Programming language.
Prerequisites
Before you start doing practice with various types of examples given in this reference, I'm making an assumption that you are already aware about what is a computer program and what is a computer programming language.
Where It Is Used
According to Sun, 3 billion devices run Java. There are many devices where Java is currently used. Some of them are as follows: 1. Desktop Applications such as acrobat reader, media player, antivirus etc. 2. Web Applications such as irctc.co.in 3. Enterprise Applications such as banking applications. 4. Mobile 5. Embedded System 6. Smart Card 7. Robotics 8. Games etc.
Cont..
3) Enterprise Application An application that is distributed in nature, such as banking applications etc. It has the advantage of high level security, load balancing and clustering. In Java, EJB is used for creating enterprise applications. 4) Mobile Application An application that is created for mobile devices. Currently Android and Java ME are used for creating mobile applications.
Java programming language was originally developed by Sun Microsystems, which was initiated by James Gosling and released in 1995 as core component of Sun Microsystems Java platform (Java 1.0 [J2SE]). As of December 08 the latest release of the Java Standard Edition is 6 (J2SE). With the advancement of Java and its wide spread popularity, multiple configurations were built to suite various types of platforms. Ex: J2EE for Enterprise Applications, J2ME for Mobile Applications.
Java Overview
Features of Java
I. Simple 2. Object-oriented 3. Platform independent 4.Secured 5. Robust 6. Architecture neutral 7. Portable 8. Dynamic 9.Interpreted 10.High Performance 11. Multithreaded 12.Distributed
Features Of Java
Object Oriented : In java everything is an Object. Java can be easily extended since it is based on the Object model. Platform independent: Unlike many other programming languages including C and C++ when Java is compiled, it is not compiled into platform specific machine, rather into platform independent byte code. This byte code is distributed over the web and interpreted by virtual Machine (JVM) on whichever platform it is being run.
Simple :Java is designed to be easy to learn. If you understand the basic concept of OOP java would be easy to master. Secure : With Java's secure feature it enables to develop virus-free, tamper-free systems. Authentication techniques are based on publickey encryption. Architectural- neutral :Java compiler generates an architecture-neutral object file format which makes the compiled code to be executable on many processors, with the presence Java runtime system.
Portable :being architectural neutral and having no implementation dependent aspects of the specification makes Java portable. Compiler and Java is written in ANSI C with a clean portability boundary means We may carry the Java byte code to any platform. Robust : Robust simply means strong. Java uses strong memory management. There are lack of pointers that avoids security problem. There is automatic garbage collection in Java. There is exception handling and type checking mechanism in Java. All these points makes Java robust. Multi-threaded : With Java's multi-threaded feature it is possible to write programs that can do many tasks simultaneously. This design feature allows developers to construct smoothly running interactive applications.
Interpreted :Java byte code is translated on the fly to native machine instructions and is not stored anywhere. The development process is more rapid and analytical since the linking is an incremental and light weight process. High Performance: With the use of Just-In-Time compilers Java enables high performance. Distributed :Java is designed for the distributed environment of the internet. Dynamic : Java is considered to be more dynamic than C or C++ since it is designed to adapt to an evolving environment. Java programs can carry extensive amount of run-time information that can be used to verify and resolve accesses to objects on run-time.
Classloader: is the subsystem of JVM that is used to load class files. Bytecode Verifier: checks the code fragments for illegal code that can violate accesss right to objects. Interpreter: read bytecode stream then execute the instructions.
Questions
Can you save a java source file by other name than the class name? Can you have a empty java file? What if no one class have main function? How to print Hello World without main function? Can you have multiple classes in a java source file?
Objects
Let us now look deep into what are objects. If we consider the real-world we can find many objects around us, Cars, Dogs, Humans etc. All these objects have a state and behavior. An object is an instance of a class. The relationship is such that many objects can be created using one class. Each object has its own data but its underlying structure (i.e., the type of data it stores, its behaviors) are defined by the class.
Classes
A class--the basic building block of an objectoriented language such as Java A class is a blue print from which individual objects are created. A class specifies the design of an object. It states what data an object can hold and the way it can behave when using the data. Class is a template that describes the data and behavior associated with instances of that class.
Classes
The data associated with a class or object is stored in variables. The behavior associated with a class or object is implemented with methods.(Methods are similar to the functions or procedures in procedural languages such as C).
Class Example
public class Book { private String title; private String author; private String publisher; public Book(String bookTitle, String authorName, String publisherName) { title = bookTitle; author = authorName; publisher = publisherName; } //all getter and setter methods }
Object Example
An instance of this class will be a book object: Book firstBook = new Book(Complete Reference",ABC",XYZ"); Objects can be created by using new keyword in java. As mentioned previously a class provides the blueprints for objects. So basically an object is created from a class. In java the new key word is used to create new objects. There are three steps when creating an object from a class:
Declaration . A variable declaration with a variable name with an object type. Like Book firstBook Instantiation . The 'new' key word is used to create the object. Initialization . The 'new' keyword is followed by a call to a constructor. This call initializes the new object.
Local Variable
Local variable are variables defined inside methods, constructors or blocks. The variable will be declared and initialized within the method and the variable will be destroyed when the method has completed. Eg. Public void setTitle(String title){
this.title=title; }
Instance variables
Instance variables are variables within a class but outside any method. These variables are instantiated when the class is loaded. Instance variables can be accessed from inside any method, constructor or blocks of that particular class. Eg. private String title; private String author; private String publisher;
Class variables
Class variables are variables declared with in a class, outside any method, with the static keyword. Eg. private static int count=0;
A class can have any number of methods to access the value of various kind of methods. Like Book Class can have bookIssue() addBook() deleteBook() updateBook()
How To Run
Java Keywords
42
43
Primitive Datatypes
Data type byte short int long float double char boolean Byt Min Value es 1 2 4 8 4 8 2 -27 -215 -231 -263 0 Max Value 27 1 215 1 231 1 263 1 216 1 Literal Values 123 1234 12345, 086, 0x675 123456 1.0 123.86 a, \n true, false
44
Java Modifiers
Modifier
public private protected
Class
Class Variables
Methods
Method Variables
default
final abstract strictfp
transient
synchronized native volatile
static
47
Modifier Example
Naming convention
A naming convention is a rule to follow as you decide what to name your identifiers (e.g. class, package,variable, method, etc.), but it is not mandatory to follow that is why it is known as convention not rule. Advantage: By using standard Java naming conventions they make their code easier to read for themselves and for other programmers. Readability of Java code is important because it means less time is spent trying to figure out what the code does.
Class Name
should begin with uppercase letter and be a noun e.g.String,System,Thread etc. Interface Name should begin with uppercase letter and be an adjective (whereever possible), e.g.Runnable,ActionListener etc. Method Name should begin with lowercase letter and be a verb. e.g.main(),print{),println(), actionPerformed() etc. Variable Name should begin with lowercase letter e.g. firstName,orderNumber etc. Package Name should be in lowercase letter, e.g. java.lang.sql.util etc. Constant Name should be in uppercase letter, e.g.
Method Overloading
Method overloading means when two or more methods have the same name but a different signature. Signature of a method is nothing but a combination of its name and the sequence of its parameter types. Advantages of method overloading It allows you to use the same name for a group of methods that basically have the same purpose. Method overloading increases the readability of the program.
Method Overloading
Different ways to overload the method There are two ways to overload the method in Java 1. By changing number of arguments 2. By changing the data type Note: In Java, Methood Overloading is not possible by changing return type of the method.
Questions
Que) Why Method Overloaing is not possible by changing the return type of method? Que) Can we overload main() method?
Example
Example
Example
Constructor
Constructor is a special type of method that is used to initialize the state of an object/initialize a value to instance variable. Constructor is invoked at the time of object creation. It constructs the values i.e. data for the object that is why it is known as constructor. Constructor is just like the instance method but it does not have any explicit return type.
Types Of Constructor
There are two types of constructors: 1) default constructor (no-arg constructor) 2) parameterized constructor Remember Point:1)If you dont provide any constructor in your class compiler will provide default constructor. 2)moment add any constructor in class u will loose to get default constructor from compiler. 3)Your class should have default constructor in case of Inheritance 4)Same constructor can be call to other constructor using this and derived class constructor using super keyword
Questions
What If there is no constructor in a class, is compiler automatically creates a default constructor? What default constructor do. What the use of parametrize constructor What the difference between constructor and methods. Does constructor can have void return type? Does copy constructor is available in java. What the alternative of copy constructor in java? Can constructor perform other tasks instead of initialization?
Static
The static keyword is used in Java mainly for memory management. We may apply static keyword with variables, methods and blocks. The static keyword belongs to the class rather than instance of the class. The static can be: 1.variable (also known as class variable) 2.method (also known as class method) 3.block
Static Variable
If you declare any variable as static, it is known static variable It is a variable which belongs to the class and not to object instance. The static variable can be used to refer the common property of all objects (that is not unique for each object) e.g. company name of employees,college name of students etc. The static variable gets memory only once in class area at the time of class loading. It can be initialize at the time of Object creation.
Static Variable
Static variables are initialized only once , at the start of the execution . These variables will be initialized first, before the initialization of any instance variables. A single copy to be shared by all instances of the class A static variable can be accessed directly by the class name and doesnt need any object. Syntax : <class-name>.<variable-name>. Static variable can be final to make constant. Syntax: public static final double RATE_OF_INT=15.5;
Static Method
If you apply static keyword with any method, it is known as static method. A static method belongs to the class rather than object of a class. A static method can be invoked without the need for creating an instance of a class. static method can access static data member and can change the value of it. It is a method which belongs to the class and not to the object(instance) A static method can access only static data. It can not access non-static data (instance variables)
Static Method
A static method can call only other static methods and cant call a non-static method from it. A static method can be accessed directly by the class name and doesnt need any object but can be call by object. Syntax : <class-name>.<method-name> A static method cannot refer to this or super keywords in anyway. main method is static , since it must be accessible for an application to run , before any instantiation takes place.
Static Block
The static block, is a block of statement inside a Java class that will be executed when a class is first loaded in to the JVM class Test{ static { //Code goes here } } A static block helps to initialize the static data members, just like constructors help to initialize instance members
Questions
Que)Can we execute a program without main() method?
example
If member variable and local variable name conflict than this can be used to refer member variable. here is an example of this with member variable:
Here local variable interest and member variable interest conflict which is easily resolve by referring member variable as this.interest
this is a final variable in Java and you can not assign value to this. this will result in compilation
you can call methods of class by using this keyword as shown in below example.
this can be used to return object. this is a valid return value.here is an example of using as return value.
"this" keyword can not be used in static context i.e. inside static methods or static initializer block. if use this inside static context you will get compilation error as shown in below example:
this can also be passed as method parameters since it represent current object of class. Java This can be used to get the handle of the current class Class className = this.getClass(); Though this can also be done by, Class className = ABC.class; // here ABC refers to the class name and you need to know that!
Creating Strings:
The most direct way to create a string is to write: String greeting = "Hello world!";
String greeting = "Hello world!"; Whenever it encounters a string literal in your code, the compiler creates a String object with its value in this case, "Hello world!'. As like any other object, you can create String objects by using the new keyword and a constructor. The String class has eleven constructors that allow you to provide the initial value of the string using different sources
Note: The String class is immutable, so that once it is created a String object cannot be changed. If there is a necessity to make a lot of modifications to Strings of characters then you should use String Buffer & String Builder Classes. Cont.
String Length: Methods used to obtain information about an object are known as accessor methods. One accessor method that you can use with strings is the length() method, which returns the number of characters contained in the string object.
String palindrome = "Dot saw I was Tod"; int len = palindrome.length(); System.out.println( "String Length is : " + len ); o/p:- String Length is : 17
Concatenating Strings: The String class includes a method for concatenating two strings: 1) method concat 2) + operator
1) 2) 3)
char charAt(int index) Returns the character at the specified index. int compareTo(Object o) Compares this String to another Object. int compareTo(String anotherString) Compares two strings lexicographically. int compareToIgnoreCase(String str) Compares two strings lexicographically, ignoring case differences. String concat(String str) Concatenates the specified string to the end of this string. boolean contentEquals(StringBuffer sb) Returns true if and only if this String represents the same sequence of characters as the specified StringBuffer.
static String copyValueOf(char[] data) Returns a String that represents the character sequence in the array specified. static String copyValueOf(char[] data, int offset, int count) Returns a String that represents the character sequence in the array specified. boolean endsWith(String suffix) Tests if this string ends with the specified suffix. boolean equals(Object anObject) Compares this string to the specified object. boolean equalsIgnoreCase(String anotherString) Compares this String to another String, ignoring case considerations.
byte getBytes() Encodes this String into a sequence of bytes using the platform's default charset, storing the result into a new byte array. byte[] getBytes(String charsetName Encodes this String into a sequence of bytes using the named charset, storing the result into a new byte array. int hashCode() Returns a hash code for this string. int indexOf(int ch) Returns the index within this string of the first occurrence of the specified character.
int indexOf(int ch, int fromIndex) Returns the index within this string of the first occurrence of the specified character, starting the search at the specified index. int indexOf(String str) Returns the index within this string of the first occurrence of the specified substring. int indexOf(String str, int fromIndex) Returns the index within this string of the first occurrence of the specified substring, starting at the specified index. int lastIndexOf(int ch, int fromIndex) Returns the index within this string of the last occurrence of the specified character, searching backward starting at the specified index.
int lastIndexOf(int ch, int fromIndex) Returns the index within this string of the last occurrence of the specified character, searching backward starting at the specified index. int lastIndexOf(String str) Returns the index within this string of the rightmost occurrence of the specified substring. int lastIndexOf(String str, int fromIndex) Returns the index within this string of the last occurrence of the specified substring, searching backward starting at the specified index. int length() Returns the length of this string.
boolean matches(String regex) :-Tells whether or not this string matches the given regular expression. String replace(char oldChar, char newChar) :-Returns a new string resulting from replacing all occurrences of oldChar in this string with newChar. String replaceAll(String regex, String replacement Replaces each substring of this string that matches the given regular expression with the given replacement. String replaceFirst(String regex, String replacement) Replaces the first substring of this string that matches the given regular expression with the given replacement. String[] split(String regex) :-Splits this string around matches of the given regular expression.
boolean startsWith(String prefix) :-Tests if this string starts with the specified prefix. boolean startsWith(String prefix, int toffset) :-Tests if this string starts with the specified prefix beginning a specified index. String substring(int beginIndex) :-Returns a new string that is a substring of this string. String substring(int beginIndex, int endIndex) :-Returns a new string that is a substring of this string. char[] toCharArray() :-Converts this string to a new character array.
String toLowerCase() :-Converts all of the characters in this String to lower case using the rules of the default locale. String toString() :-This object (which is already a string!) is itself returned. String toUpperCase() :-Converts all of the characters in this String to upper case using the rules of the default locale. String trim() :-Returns a copy of the string, with leading and trailing whitespace omitted. static String valueOf([int+*float+*.+ x) :-Returns the string representation of the passed data type argument.
Inheritance
Inheritance can be defined as the process where one object acquires the properties of another. Inheritance is a mechanism in which one object acquires all the properties and behaviours of parent object. The idea behind inheritance is that you can create new classes that are built upon existing classes. When you inherit from an existing class, you reuse (or inherit) methods and fields. Inheritance represents the IS-A relationship. extends keyword is used to achieve inheritance.
Inheritance Example
Animal is the superclass of Mammal class. Animal is the superclass of Reptile class. Mammal and Reptile are subclasses of Animal class. Dog is the subclass of both Mammal and Animal classes.
IS-A Relationship
Mammal IS-A Animal Reptile IS-A Animal Dog IS-A Mammal Hence : Dog IS-A Animal as well
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 subclass, or an instance of a class that implements a particular interface. The instanceof operator is also known as type comparison operator because it compares the instance with type. It returns either true or false. If we apply the instanceof operator with any variable that have null value, it returns false.
Types of Inheritance
There exists basically three types of inheritance. Single Inheritance Multilevel inheritance Multiple inheritance Hierarchical inheritance In single inheritance, one class extends one class only. In multilevel inheritance, the ladder of single inheritance increases. In multiple inheritance, one class directly extends more than one class. In hierarchical inheritance one class is extended by more than one class.
Single Inheritance
Multilevel Inheritance
Multilevel Inheritance
Multiple Inheritance
In multiple inheritance, one class extends multiple classes. Java does not support multiple inheritance but C++ supports. The above program can be modified to illustrate multiple inheritance. The following program does not work. class Aves { } class Bird { } class Parrot extends Aves, Bird { } Note:-Java supports multiple inheritance partially through interfaces.
Hierarchical Inheritance
Disadvantages of Inheritance
Both classes (super and subclasses) are tightlycoupled. As they are tightly coupled (binded each other strongly with extends keyword), they cannot work independently of each other. Changing the code in super class method also affects the subclass functionality. If super class method is deleted, the code may not work as subclass may call the super class method with super keyword. Now subclass method behaves independently.-
Aggregation In Java
If a class have an entity reference, it is known as Aggregation. Aggregation represents HAS-A relationship Consider a situation, Employee object contains many informations such as id, name, emailld etc. It contains one more object named address, which contains its own informations such as city, state, country, zipcode etc. as given below.
Aggregation In Java
class Employee{ int id; String name; Address address;//Address is a class } In such case, Employee has an entity reference address, so relationship is Employee HAS-A address. Why use Aggregation? Ans:-For Code Reusability.
In the previous chapter, we talked about super classes and sub classes. If a class inherits a method from its super class, then there is a chance to override the method provided that it is not marked final. The benefit of overriding is: ability to define a behavior that's specific to the subclass type which means a subclass can implement a parent class method based on its requirement. In object-oriented terms, overriding means to override the functionality of an existing method.
Overriding
The argument list should be exactly 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 superclass. The access level cannot be more restrictive than the overridden method's access level. For example: if the superclass method is declared public then the overridding method in the sub class cannot be either private or protected. Instance methods can be overridden only if they are inherited by the subclass.
A method declared final cannot be overridden. A method declared static cannot be overridden but can be re-declared. If a method cannot be inherited, then it cannot be overridden. 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.
Questions
1) Can we override static method? No, static method cannot be overridden. It can be proved by runtime polymorphism so we will learn it later. 2) Why we cannot override static method? because static method is bound with class whereas instance method is bound with object. Static belongs to class area and instance belongs to heap area.
Method Overriding
Method overriding is used to provide the specific implementation of the method that is already provided by its super class. method overlaoding is performed Method overriding occurs in two within a class. classes that have IS-A relationship. In case of method overloading In case of method overriding parameter must be different. parameter must be same.
super keyword
The super is a reference variable that is used to refer immediate parent class object. Whenever you create the instance of subclass, an instance of parent class is created implicitely because it is referred by super reference variable. Usage of super Keyword:1. super is used to refer immediate parent class instance variable. 2. super() is used to invoke immediate parent class constructor. 3. super is used to invoke immediate parent class method.
Restricting Inheritance
Parent
Inherited capability
Child
120
Abstract Classes
When we define a class to be final, it cannot be extended. In certain situation, we want to properties of classes to be always extended and used. Such classes are called Abstract Classes. An Abstract class is a conceptual class. An Abstract class cannot be instantiated objects cannot be created. Abstract classes provides a common root for a group of classes, nicely tied together in a package:
123
Circle
Rectangle
125
Abstract Classes
public Circle extends Shape { protected double r; protected static final double PI =3.1415926535; public Circle() { r = 1.0; ) public double area() { return PI * r * r; } } public Rectangle extends Shape { protected double w, h; public Rectangle() { w = 0.0; h=0.0; } public double area() { return w * h; } }
127
128
Summary
If you do not want (properties of) your class to be extended or inherited by other classes, define it as a final class. Java supports this is through the keyword final. This is applied to classes. You can also apply the final to only methods if you do not want anyone to override them. If you want your class (properties/methods) to be extended by all those who want to use, then define it as an abstract class or define one or more of its methods as abstract methods. Java supports this is through the keyword abstract. This is applied to methods only. Subclasses should implement abstract methods; otherwise, they cannot be instantiated. 129
Interface
Since we have a good understanding of the extends keyword let us look into how the implements keyword is used to get the IS-A relationship. The implements keyword is used by classes by inherit from interfaces. Interfaces can never be extended by the classes. An interface in the Java programming language is an abstract type that is used to specify an interface that classes must implement.
Interface
Interface is a conceptual entity similar to a Abstract class. Can contain only constants (final variables) and abstract method (no implementation) - Different from Abstract classes. Use when a number of classes share a common interface. Each class should implement the interface.
Interface
An interface is basically a kind of classit contains methods and variables, but they have to be only abstract classes and final fields/variables. Therefore, it is the responsibility of the class that implements an interface to supply the code for methods. A class can implement any number of interfaces, but cannot extend more than one class at a time. Therefore, interfaces are considered as an informal way of realising multiple inheritance in Java.
Interface Example
<<Interface>> Speaker
speak()
Politician speak()
Priest speak()
Lecturer speak()
Interfaces Definition
Syntax (appears like abstract class):
interface InterfaceName { // Constant/Final Variable Declaration // Methods Declaration only method body }
Example:
interface Speaker { public void speak( ); }
Implementing Interfaces
Interfaces are used like super-classes who properties are inherited by classes. This is achieved by creating a class that implements the given interface as follows:
class ClassName implements InterfaceName [, InterfaceName2, ] { // Body of Class }
135
class Priest implements Speaker { public void speak(){ System.out.println(Religious Talks); } } class Lecturer implements Speaker { public void speak(){ System.out.println(Talks Object Oriented Design and Programming!); } 136 }
Extending Interfaces
Like classes, interfaces can also be extended. The new subinterface will inherit all the members of the superinterface in the manner similar to classes. This is achieved by using the keyword extends as follows: interface InterfaceName2 extends InterfaceName1 { // Body of InterfaceName2 }
137
This shows a class can extended another class while implementing one or more interfaces. It appears like a multiple inheritance (if we consider interfaces as special kind of classes with certain restrictions or special features). 138
Interface Cont..
Interfaces are declared using the interface keyword. Interface may only contain method signature and constant declarations (variable declarations that are declared to be both static and final). An interface may never contain method definitions. Interfaces cannot be instantiated, but rather are implemented. A class that implements an interface must implement all of the methods described in the interface, or be an abstract class.
Interface Cont..
Object references in Java may be specified to be of an interface type. One benefit of using interfaces is that they simulate multiple inheritance. All classes in Java must have exactly one base class because multiple inheritance of classes is not allowed. A Java class may implement n number of interface. Interface may extends n number of interface.
Interface Example
Interface Example
Comparable Interface
1. Provides an interface for comparing any two objects of same class.
2. General Form : public interface Comparable<T> public interface Comparable { { int compareTo(<T> other ); int compareTo(Object other ); } } Note : other parameter should be type casted to the class type implementing Comparable interface
3. Collections. sort method can sort objects of any class that implements comparable interface. 4. By implementing this interface , programmers can implement the logic for comparing two objects of same class for less than, greater than or equal to.
}
. }
Examples
class BOX implements Comparable { Unparametrized Comparable private double length; private double width; private double height; BOX(double l,double b,double h) { length=l;width=b;height=h; } public double getLength() { return length;} public double getWidth() { return width;} public double getHeight() { return height;} public double getArea() { return 2*(length*width + width*height+height*length); } public double getVolume() { return length*width*height; }
public int compareTo(Object other) { BOX b1 =(BOX) other; if(this.getVolume() > b1.getVolume()) return 1; if(this.getVolume() < b1.getVolume()) return -1; return 0; } public String toString() { return Length:+length+ Width :+width + Height :+height; } } // End of BOX class
import java.util.*; class ComparableTest { public static void main(String[] args) { BOX[] box = new BOX[5]; box[0] = new BOX(10,8,6); box[1] = new BOX(5,10,5); box[2] = new BOX(8,8,8); box[3] = new BOX(10,20,30); box[4] = new BOX(1,2,3); Arrays.sort(box); for(int i=0;i<box.length;i++) System.out.println(box[i]); } } // End of class
Import java.util.*; class ComparableTest { public static void main(String[] args) { ArrayList box = new ArrayList(); box.add( new BOX(10,8,6)); box.add( new BOX(5,10,5)); box.add( new BOX(8,8,8)); box.add( new BOX(10,20,30)); box.add( new BOX(1,2,3)); Collections.sort(box); Iterator itr = ar.iterator(); while(itr.hasNext()) { BOX b =(BOX) itr.next(); System.out.println(b); } } }// End of class
Problems With Comparable Interface Method int compareTo(Object obj) needs to be included in the base class itself. We can include only single ordering logic. Different order requires logic to be included and requires changes in the base class itself. Each type we need different order we need to change the code itself.
import java.util.*; class Student implements Comparable { private String name; private String idno; private int age; private String city; .. public int compareTo(Object other) { Student std = (Student) other; return this.name.compareTo(other.name); } public String toString() { Return Name:+name+Id No:+idno+Age:+age; } } // End of class
System.out.println(students[i]);
import java.util.*; class Student implements Comparable { private String name; private String idno; private int age; private String city; .. public int compareTo(Object other) { Student std = (Student) other; return this.idno.compareTo(other.idno); } public String toString() { Return Name:+name+Id No:+idno+Age:+age; } } // End of class
System.out.println(students[i]);
Comparator Interface
Allows two objects to compare explicitly. Syntax : public interface Comparator { Unparametrized Comparator int compare(Object O1, Object O2); } public interface Comparator<T> Parametrized Comparator { int compare(T O1, T O2); } Does not require change in the base class. We can define as many comparator classes for the base class. Each Comparator class implements Comparator interface and provides different logic for comparisons of objects. But as we are passing both parameters explicitly, we have to type cast both Object types to their base type before implementing the logic OR Use the second form
Student
class Student { private String name; private String idno;
studentbyname
Comparator
studentbyidno
studentbyage
..
class studentbyname implements comparator { public int compare(Object o1,Object o2) { Student s1 = (Student) o1; Student s2 = (Student) o2; return s1.getName().compareTo(s2.getName()); } } class studentbyidno implements comparator { public int compare(Object o1,Object o2) { Student s1 = (Student) o1; Student s2 = (Student) o2; return s1.getIdNo().compareTo(s2.getIdNo()); } }
class studentbyage implements comparator { public int compare(Object o1,Object o2) { Student s1 = (Student) o1; Student s2 = (Student) o2; if( s1.getAge() > s2.getAge() ) return 1; if( s1.getAge() < s2.getAge() ) return -1; return 0; } } class studentbynameidno implements comparator { public int compare(Object o1,Object o2) { Student s1 = (Student) o1; Student s2 = (Student) o2; if( s1.getName().compareTo(s2.getName()) == 0) return s1.getIdNo().compareTo(s2.getIdNo()); else return s1.getName().compareTo(s2.getName()); }}
class studentbynameage implements comparator { public int compare(Object o1,Object o2) { Student s1 = (Student) o1; Student s2 = (Student) o2; if( s1.getName().compareTo(s2.getName()) == 0) return s1.getAge() s2.getAge(); else return s1.getName().compareTo(s2.getName()); } }
Import java.util.*; class comparatorTest { public static void main(String args[]) { Student[] students = new Student[5]; Student*0+ = new Student(John,2000A1Ps234,23,Pilani); Student*1+ = new Student(Meera,2001A1Ps234,23,Pilani); Student*2+ = new Student(Kamal,2001A1Ps344,23,Pilani); Student*3+ = new Student(Ram,2000A2Ps644,23,Pilani); Student*4+ = new Student(Sham,2000A7Ps543,23,Pilani); // Sort By Name Comparator c1 = new studentbyname(); Arrays.sort(students,c1); for(int i=0;i<students.length;i++) System.out.println(students[i]);
// Sort by Name & Age c1 = new studentbynameage(); Arrays.sort(students,c1); for(int i=0;i<students.length;i++) System.out.println(students[i]); } // End of Main } // End of test class.
Exception in thread "main" java.lang.ClassCastException: import java.util.*; A class A at java.util.Arrays.mergeSort(Arrays.java:1156) { int a; at java.util.Arrays.sort(Arrays.java:1080) } at ctest.main(ctest.java:21) class ctest { public static void main(String args[]) { String[] names = {"OOP","BITS","PILANI"}; Ok As String class Arrays.sort(names); implements Comparable int[] data = { 10,-45,87,0,20,21 }; Arrays.sort(data); Ok As Integer class A[] arr = new A[5]; implements Comparable arr[0] = new A();
arr[1] = new A(); arr[2] = new A(); arr[3] = new A(); arr[4] = new A(); }}
Arrays.sort(arr);
Unparametrized Comparator
import java.util.*; class A implements Comparable { int a; public int compareTo(Object other) { class ctest { public static void main(String args[]) { String[] names = {"OOP","BITS","PILANI"};
A a1 = (A) other;
Arrays.sort(names);
if(this.a == a1.a ) return 0; if(this.a < a1.a ) return -1; return 1; } } Type cast Object type to Base Type Before use
Will Work
Arrays.sort(arr);
Will Work
Unparametrized Comparable
Parametrized Comparator
import java.util.*; class A implements Comparable<A> { int a; class ctest { public static void main(String args[]) { String[] names = {"OOP","BITS","PILANI"};
public int compareTo(A other) Arrays.sort(names); { // A a1 = (A) other; //No need of castint[] data = { 10,-45,87,0,20,21 }; Will Work Arrays.sort(data); if(this.a == other.a ) return 0; if(this.a < other.a ) return -1; Will Work A[] arr = new A[5]; return 1; arr[0] = new A(); } arr[1] = new A(); } arr[2] = new A(); arr[3] = new A(); Parametrized Comparable arr[4] = new A();
Arrays.sort(arr);
} }
Will Work
import java.util.*; class BOX implements Comparable<BOX> { private double l,b,h; // Overloaded Constructors BOX(double a) { l=b=h=a; } BOX(double l,double b,double h) { this.l=l; this.b=b; this.h=h; } // Acessor Methods public double getL() { return l; } public double getB() { return b; } public double getH() { return h; }
Cont.
// area() Volume() Methods double area() { return 2*(l*b+b*h+h*l); } double volume() { return l*b*h; } // isEquals() method boolean isEqual(BOX other) { if(this.area() == other.area()) return true; return false; /* OR if(area() == other.area()) return true return false; */ } static boolean isEquals(BOX b1, BOX b2) { if(b1.area() == b2.area()) return true; return false; }
// compareTo method public int compareTo(BOX other) { if(area() > other.area()) return 1; if(area() < other.area()) return -1; return 0; } public String toString() { String s1="length:"+l; String s2="width:"+b; String s3="area:"+h; String s4="Area:"+area(); String s5="Volume:"+volume(); return s1+s2+s3+s4+s5; } } // End of class BOX
class comparableTest10 { public static void main(String args[]) { ArrayList<BOX> boxes = new ArrayList<BOX>(); boxes.add(new BOX(10)); boxes.add(new BOX(20)); boxes.add(new BOX(10,6,8)); boxes.add(new BOX(4,6,10)); boxes.add(new BOX(10,12,14)); Iterator itr = boxes.iterator(); while(itr.hasNext()) System.out.println((BOX)itr.next());
Collections.sort(boxes);
Iterator itr1 = boxes.iterator(); while(itr1.hasNext()) System.out.println((BOX)itr1.next()); } }
Converting a Class To an Interface Type 1. Interface acts as a super class for the implementation classes. 2. A reference variable belonging to type interface can point to any of the object of the classes implementing the interface.
A a1 = new A();
X x1 = a1; A Class to interface type Conversion
Converting an Interface to a class Type X x1 = new A(); A a1 = (A) x1; X x1 = new B(); B b1 = (B) x1; << interface >>
X
A B C
Comparator Example
1. 2. 3. 4. 5. Supply comparators for BOX class so that BOX[] OR ArrayList<BOX> can be sorted by any of the following orders: Sort By Length Either in Ascending or descending order Sort By Width Either in Ascending or descending order Sort By Height Either in Ascending or descending order Sort By Area Either in Ascending or descending order Sort By Volume Either in Ascending or descending order
BOX is base class whose references stored either in Arrays or in Any Collection class such as ArrayList, Vector or LinkedList Needs to be sorted
Comparator<BOX>
Comparator Classes
SORTBOXBYLENGTH
SORTBOXBYWIDTH
SORTBOXBYHEIGHT
SORTBOXBYAREA
SORTBOXBYVOLUME
import java.util.*; class BOX { private double l,b,h; // Overloaded Constructors BOX(double a) { l=b=h=a; } BOX(double l,double b,double h) { this.l=l; this.b=b; this.h=h; } // Acessor Methods public double getL() { return l; } public double getB() { return b; } public double getH() { return h; }
// area() Volume() Methods double area() { return 2*(l*b+b*h+h*l); } double volume() { return l*b*h; } // isEquals() method boolean isEqual(BOX other) { if(this.area() == other.area()) return true; return false; /* OR if(area() == other.area()) return true return false; */ }
Cont ..
static boolean isEquals(BOX b1, BOX b2) { if(b1.area() == b2.area()) return true; return false; } public String toString() NOTE : { String s1="length:"+l; BOX class is base class String s2="width:"+b; whose references needs to String s3="area:"+h; be sorted. It does not String s4="Area:"+area(); String s5="Volume:"+volume(); implement either return s1+s2+s3+s4+s5; comparable or comparator } class } // End of class BOX
Cont ..
if(b1.getB() > b2.getB()) return 1*order; if(b1.getB() < b2.getB()) return -1*order;
return 0; } } // End of class
if(b1.getH() > b2.getH()) return 1*order; if(b1.getH() < b2.getH()) return -1*order;
return 0; } } // End of class
if(b1.area() > b2.area()) return 1*order; if(b1.area() < b2.area()) return -1*order;
return 0; } } // End of class
if(b1.volume() > b2.volume()) return 1*order; if(b1.volume() < b2.volume()) return -1*order; return 0;
} } // End of class
class comparatorTest { public static void main(String args[]) { boxes.add(new BOX(10)); boxes.add(new BOX(20)); boxes.add(new BOX(10,6,8)); boxes.add(new BOX(4,6,10)); boxes.add(new BOX(10,12,14));
Exercise 1
Suppose C is a class that implements interfaces I and J. Which of the following Requires a type cast? c = ? << interfaces>> i = ..? I J j = ..? c = i j = c i = j
C I J 1. 2. 3.
<< class>>
Exercise 2
Suppose C is a class that implements interfaces I and J. Which of the following will throw an Exception? c = new C() << interfaces>> I i J j C d = c; = (J) i; = (C) i;
I J
C 1. 2. 3.
<< class>>
Second
Exercise 3
Suppose the class Sandwich implements Editable interface. Which if the following statements are legal? Sandwich sub = new Sandwich(); OK Editable e = sub; OK sub = e Illegal sub = (Sandwich) e; OK
1. 2. 3. 4.
Polymorphism
Polymorphism is the ability of an object to take on many forms. The most common use of polymorphism in OOP occurs when a parent class reference is used to refer to a child class object. Any Java object that can pass more than one IS-A test is considered to be polymorphic. In Java, all Java objects are polymorphic since any object will pass the IS-A test for their own type and for the class Object.
Polymorphism
It is important to know that the only possible way to access an object is through a reference variable. A reference variable can be of only one type. Once declared, the type of a reference variable cannot be changed. The reference variable can be reassigned to other objects provided that it is not declared final. The type of the reference variable would determine the methods that it can invoke on the object.
Polymorphism
A reference variable can refer to any object of its declared type or any subtype of its declared type. A reference variable can be declared as a class or interface type. refer example from next slide.
Polymorphism
6. While Overriding a Method, the sub class should assign either same or higher access level than super class method.
EXAMPLE METHOD OVERRIDING class A { void show() { System.out.println("Hello This is show() in A"); }// End of show() Method B class overrides show() method from } // End of class A super class A class B extends A { void show() { System.out.println("Hello This is show() in B"); }// End of show() Method } // End of class B class override { public static void main(String args[]) Call to show() { of A class // super class reference variable // can point to sub class object A a1 = new A(); a1.show(); Call to show() a1 = new B(); of B class a1.show(); }
class A Overriding { void show(int a) NO { System.out.println("Hello This is show() in A"); } } class B extends A { void show() { System.out.println("Hello This is show() in B"); } }
OUTPUT Hello This is show() in A Hello This is show() in A Hello This is show() in B
Is this Method
class override1 { public static void main(String args[]) { /* A a1 = new B(); a1.show(); */ A a1 = new A(); a1.show(10); B b1 = new B(); b1.show(10); b1.show(); }
Dynamic Method Dispatch 1. Super class reference variable can refer to a sub class object. 2. Super class variable if refers to sub class object can call only overridden methods. 3. Call to an overridden method is decided by the type of object referred to. A a1 = new B(); a1.show(); // call to show() of B a1 = new C(); a1.show(); // call to show() of C a1 = new D(); a1.show(); // call to show() of D
class C extends A { void show() { System.out.println("Hello This is show() in C"); } } class D extends A { void show() { System.out.println("Hello This is show() in D"); } } CONTINUED..
class override2 { public static void main(String args[]) { Hello This is show() in A A a1 = new A(); Hello This is show() in B a1.show(); a1 = new B(); Hello This is show() in C a1.show(); Hello This is show() in D a1 = new C(); a1.show(); a1 = new D(); a1.show(); } }
6. While Overriding a Method, the sub class should assign either same or higher access level than super class method.
class override3 { public static void main(String args[]) { A a1 = new B(); B b1 = (B) a1; /* A a1 = new B(); C c1 = (C) a1; Exception in thread "main" java.lang.ClassCastException: B at override3.main(override3.java:39) */ } }
Examples Overriding
class A { void show() , . } class B extends A { void show() , . void show(int x) , void print() , } A a1 = new B(); a1.show() ; // Valid // a1.show(10); // Invalid //a1.print(); // Invalid
When a super class variable points to a sub class object, then it can only call overridden methods of the sub class.
class A { protected void show() { System.out.println("Hi"); } } class B extends A { void show() { System.out.println("Hi"); } }
D:\Java1>javac AB.java AB.java:10: show() in B cannot override show() in A; attempting to assign weaker access privileges; was protected void show() ^ 1 error
class A { private void show() { System.out.println("Hi"); } } class B extends A { int show() { System.out.println("Hi"); return 10; } }
NO
sample.java:12: show() in B cannot override show() in A; overridden method is static void show() ^ 1 error
Nested Classes
Java programming language allows you to define a class within another class Enclosing class OuterClass Class OR { ... Outer Class A nested class is a member class NestedClass { ... of } its enclosing class }
Nested Class 1.Nested has access to other members of the enclosing class,even if they are declared private 2. Can be private, public, protected or friendly access
Example 1 [Non-static Nested Class] class B class A { { int b; private int a; Outer Class Nested B(int b) A(int a) class with { { friendly int c = b+10; access this.a =a; this.b = c; } } void print() void show() { { System.out.println("a="+a) print(); ; System.out.println("b="+b); } Call to } print() of } // End of class B outer class } // End of class A
cont.
b1.show(); } }
To create an inner class instance for nonstatic classes you need an outer class reference. Inner class Reference Outer class Name
If class B is Private then it is not visible in main(). A.B b1 = a1.new B(100); is WRONG/INVALID
Example 2
class B { private int b; Instance Field of B B(int b) { this.b =b; } Outer Class As a void show() { int b=20; System.out.println("a="+a); System.out.println("b="+b); System.out.println("this.b="+this.b); System.out.println("Outer b="+A.this.b); } } // End of B inner class
class innerTest { public static void main(String args[]) { // Create an inner class B's instance // Call show() method // STEP 1 // Create an Outer Instance first
// inner class object instantiation thru anonymous outer // reference A.B b2 = new A(30).new B(-40); a=30 b2.show(); b=20 } this.b=-40 } Outer b=10
static class B { int b; B(int b) Static inner { class int c = b+10; this.b = c; } void show() { // print(); INVALID A a1 = new A(10); a1.print(); System.out.println("b="+b); } } // End of class B } // End of class A
Example cont.
class innertest10 { public static void main(String args[]) { A.B b1 = new A.B(100); b1.show(); Instance of static Inner } class }
Example 2 cont. static class B { private int a; protected static int b=100; B(int a) { this.a=a; } void show() { // A.this.show(); // Won't work show() is non-static in outer display(); // Will work as method is static in outer System.out.println("a="+a); // System.out.println("a="+A.this.a); // Won't work a is non-static in outer System.out.println("b="+b); // Will refer to its own b System.out.println("A'sb="+A.b); // will refer to outer class B
new A(40).show(); // This is how you can call non static methods of outer
} } // End of inner class B } // End of class A
Example 2 cont. class innerTest1 { public static void main(String args[]) { A.B b1 = new A.B(-30); D:\jdk1.3\bin>java innerTest1 b1.show(); } b=10 } a=-30 b=100
A'sb=10
a=40 b=10
class A { private int a; protected static int b=10; A(int a) { this.a=a; 1. } void show() 2. { class B {} 3. } } 4.
Class B is visible only in method show(). It can be used within this show() method only
Local inner classes can only use final variables from its enclosing method.
However inner classes can refer to its fields of enclosing class.
class A { private int a; protected static int b=10; A(int a) { this.a=a; } void show() { int x=10; class B { private int b; B(int b) { this.b=b; } void display() {
D:\jdk1.3\bin>javac innerTest2.java innerTest2.java:23: local variable x is accessed from within inner class; to be declared final System.out.println("x="+x); ^ 1 error
Reference for As a Reference for Bs b Reference is wrong / errorneous x is local variable inside the local method. Local classes can use only final fields from enclosing method
class innertest { public static void main(String args[]) { final int a1=10;
new A(20).show(); print(); }// End of main static void print() {
System.out.println("Hello" ); } }
class A { private int a; private int b; int c; A(int a) { this.a =a; b = a+20; c = a+40; } void show() { System.out.println("a1="+a1); System.out.println("a="+a); System.out.println("b="+b); System.out.println("c="+c); } } //End of A
OUTPUT
Cont
Syntax [ If extending a class] [variable_type_superclass =] new superclass_name() { // properties and methods } [;] Syntax [ If implementing an interface] [variable_type_reference =] new reference_name() { // properties and methods } [;]
A a1 = new A(20){ public void show() { super.show(); System.out.println("Hello"); } public void display() { System.out.println("Hi"); } }; a1.show(); // a1.display(); Calling show from inner class } }
interface X { int sum(int a,int b); int mul(int x,int y); } class innertest2 { public static void main(String args[]) { Anonymous inner class implementing an interface
X x1 = new X() { public int sum(int a,int b) { return a+b; } public int mul(int a,int b) { return a*b; } };
System.out.println(x1.sum(10,20)); System.out.println(x1.mul(10,20)); }// End of main }// End of innertest2
Wrapper Classes
Java uses primitive types, such as int, char, double to hold the basic data types supported by the language. Sometimes it is required to create an object representation of these primitive types. These are collection classes that deal only with such objects. One needs to wrap the primitive type in a class.
To satisfy this need, Java provides classes that correspond to each of the primitive types. Basically, these classes encapsulate, or wrap, the primitive types within a class. Thus, they are commonly referred to as type wrapper. Type wrapper are classes that encapsulate a primitive type within an object. The wrapper types are Byte, Short, Integer, Long, Character, Boolean, Double, Float. These classes offer a wide array of methods that allow to fully integrate the primitive types into Java's object hierarchy.
Wrapper Classes are based upon the well-known software engineering design pattern called the Wrapper pattern.
A design pattern is a template solution to a common problem. It describes the problem and identifies the recommended solution(s) to that problem. Because design patterns deal with common problems, they are often quite abstract!
The Solution:
We create another class that wraps the underlying class/type and provides an appropriate interface for the client. e.g. we create an Integer class that subclasses Object (as all classes do), allowing us to store wrapped ints in Vectors.
Boolean
Void
Number
String
Character
Byte
Short
Integer
Long
Float
Double
int i =integer.parselnt(str); Converts String str into primitive integer i long l = Long.parseLong(str); Converts String str into primitive long l Double d=Double.parseDouble(str); Converting String to primitive double Note: parselnt() and parseLong() methods throw a NumberFormatException if the value of the str does not represent an integer.
sets str to the String 33.34. Getting a wrapper class instance for a value:
e.g. Integer
obj = Integer.getInteger(12);
creates a new Integer object with value 12 and makes obj refer to that object.
Reading a Double
import java.io.*; class MyProgram { public static void main(String[] args) { BufferedReader in = new BufferedReader( new InputStreamReader(System.in)); String line = null; System.out.println("Input Something:" ); try { line = in.readLine(); } catch (IOException ie) { System.out.println("Exception caught: " + ie); } try { double value = Double.parseDouble(line); System.out.println("Value: " + value); } catch (NumberFormatException nfe) { System.out.println("You didn't enter a double number"); } } }
Sample values:
boolObj new Boolean(Boolean.TRUE); charObj = new Character('a'); byteObj = new Byte("100"); shortObj = new Short("32000"); intObj = new Integer(2000000); longObj = new Long(500000000000000000L); floatObj = new Float(1.42); doubleObj = new Double(1.42);
printWrapperInfo(); //method to print objects above
Byte Example
The Byte class encapsulates a byte value. It defines the constants MAX_VALUE and MIN_VALUE and provides these constructors: Byte(byte b) Byte(String str) Here, b is a byte value and str is the string equivalent of a byte value.
Byte Example
Short Example
The Short class encapsulates a short value. It defines the constants MAX_VALUE and MIN_VALUE and provides the following constructors: Short(short s) Short(String str)
Short Example
Integer Example
The Integer class encapsulates an integer value. This class provides following constructors: Integer(int i) Integer(String str) Here, i is a simple int value and str is a String object.
Integer Example
Character Example
The Character class encapsulates a char value. This class provides the following constructor. Character(char ch) Here, c is a char value. charValue() method returns the char value that is encapsulated by a Character object and has the following form: char charValue()
Character Example
Boolean Example
The Boolean class encapsulates a Boolean value. It defines FALSE and TRUE constants. This class provides following constructors: Boolean(Boolean b) Boolean(String str) Here, b is a Boolean value and str is the string equivalent of a Boolean value. The methods associated with Boolean Class are as follows: 1. Boolean booleanValue() 2. Boolean equals(Boolean b) 3. String toString(Boolean b)
Boolean Example
java2all
Clone Method
Recall that the = operator simply copies Object references. e.g., >> Student s1 = new Student(Smith, Jim, 3.13); >> Student s2 = s1; >> s1.setName(Sahil); >> System.out.println(s2.getName()); OP:- Sahil What if we want to actually make a copy of an Object? Most elegant way is to use the clone() method inherited from Object. Student s2 = (Student) s1.clone();
First, note that the clone method is protected in the Object class. This means that it is protected for subclasses as well. Hence, it cannot be called from within an Object of another class and package. To use the clone method, you must override in your subclass and upgrade visibility to public. Also, any class that uses clone must implement the Cloneable interface. This is a bit different from other interfaces that weve seen. There are no methods; rather, it is used just as a marker of your intent. The method that needs to be implemented is inherited from Object.
Deep Copies
For deep copies that recurse through the object ivs, you have to do some more work. super.clone() is first called to clone the first level of ivs. Returned cloned objects object fields are then accessed one by one and clone method is called for each. See DeepClone.java example
Finally, though no one really cares, Object does not support clone();
toString() method
The Object method
String toString();
is intended to return a readable textual representation of the object upon which it is called. This is great for debugging! Best way to think of this is using a print statement. If we execute:
System.out.println(someObject);
we would like to see some meaningful info about someObject, such as values of ivs, etc.
default toString()
By default toString() prints total garbage that no one is interested in
getClass().getName() + '@' + Integer.toHexString(hashCode())
and values (or some important subset). The intent is not to overformat. Typically used for debugging. Always override toString()!
equals() method
Recall that boolean == method compares when applied to object compares references. That is, two object are the same if the point to the same memory. Since java does not support operator overloading, you cannot change this operator. However, the equals method of the Object class gives you a chance to more meaningful compare objects of a given class.
equals subtleties
As with any method that you override, to do so properly you must obey contracts that go beyond interface matching. With equals, the extra conditions that must be met are discussed on the next slide:
equals contract
It is reflexive: for any reference value x, x.equals(x) should
return true. It is symmetric: for any reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true. It is transitive: for any reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true. It is consistent: for any reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the object is modified. For any non-null reference value x, x.equals(null) should return false.
hashcode() method
Java provides all objects with the ability to generate a hash code. By default, the hashing algorithm is typically based on an integer representation of the java address. This method is supported for use with java.util.Hashtable Will discuss Hashtable in detail during Collections discussion.
method must return the same integer, provided no information used in equals comparisons on the object is modified. If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result. It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hashtables.
finalize() method
Called as final step when Object is no longer used, just before garbage collection Object version does nothing Since java has automatic garbage collection, finalize() does not need to be overridden reclaim memory. Can be used to reclaim other resources close streams, database connections, threads. However, it is strongly recommended not to rely on this for scarce resources. Be explicit and create own dispose method.
Polymorphism
Polymorphism is the ability of an object to take on many forms. The most common use of polymorphism in OOP occurs when a parent class reference is used to refer to a child class object. Any Java object that can pass more than one IS-A test is considered to be polymorphic. In Java, all Java objects are polymorphic since any object will pass the IS-A test for their own type and for the class Object.
Polymorphism
It is important to know that the only possible way to access an object is through a reference variable. A reference variable can be of only one type. Once declared, the type of a reference variable cannot be changed. The reference variable can be reassigned to other objects provided that it is not declared final. The type of the reference variable would determine the methods that it can invoke on the object.
Polymorphism
A reference variable can refer to any object of its declared type or any subtype of its declared type. A reference variable can be declared as a class or interface type. refer example from next slide.
Polymorphism
6. While Overriding a Method, the sub class should assign either same or higher access level than super class method.
EXAMPLE METHOD OVERRIDING class A { void show() { System.out.println("Hello This is show() in A"); }// End of show() Method B class overrides show() method from } // End of class A super class A class B extends A { void show() { System.out.println("Hello This is show() in B"); }// End of show() Method } // End of class B class override { public static void main(String args[]) Call to show() { of A class // super class reference variable // can point to sub class object A a1 = new A(); a1.show(); Call to show() a1 = new B(); of B class a1.show(); }
class A Overriding { void show(int a) NO { System.out.println("Hello This is show() in A"); } } class B extends A { void show() { System.out.println("Hello This is show() in B"); } }
OUTPUT Hello This is show() in A Hello This is show() in A Hello This is show() in B
Is this Method
class override1 { public static void main(String args[]) { /* A a1 = new B(); a1.show(); */ A a1 = new A(); a1.show(10); B b1 = new B(); b1.show(10); b1.show(); }
Dynamic Method Dispatch 1. Super class reference variable can refer to a sub class object. 2. Super class variable if refers to sub class object can call only overridden methods. 3. Call to an overridden method is decided by the type of object referred to. A a1 = new B(); a1.show(); // call to show() of B a1 = new C(); a1.show(); // call to show() of C a1 = new D(); a1.show(); // call to show() of D
class C extends A { void show() { System.out.println("Hello This is show() in C"); } } class D extends A { void show() { System.out.println("Hello This is show() in D"); } } CONTINUED..
class override2 { public static void main(String args[]) { Hello This is show() in A A a1 = new A(); Hello This is show() in B a1.show(); a1 = new B(); Hello This is show() in C a1.show(); Hello This is show() in D a1 = new C(); a1.show(); a1 = new D(); a1.show(); } }
6. While Overriding a Method, the sub class should assign either same or higher access level than super class method.
class override3 { public static void main(String args[]) { A a1 = new B(); B b1 = (B) a1; /* A a1 = new B(); C c1 = (C) a1; Exception in thread "main" java.lang.ClassCastException: B at override3.main(override3.java:39) */ } }
Examples Overriding
class A { void show() , . } class B extends A { void show() , . void show(int x) , void print() , } A a1 = new B(); a1.show() ; // Valid // a1.show(10); // Invalid //a1.print(); // Invalid
When a super class variable points to a sub class object, then it can only call overridden methods of the sub class.
class A { protected void show() { System.out.println("Hi"); } } class B extends A { void show() { System.out.println("Hi"); } }
D:\Java1>javac AB.java AB.java:10: show() in B cannot override show() in A; attempting to assign weaker access privileges; was protected void show() ^ 1 error
class A { private void show() { System.out.println("Hi"); } } class B extends A { int show() { System.out.println("Hi"); return 10; } }
NO
sample.java:12: show() in B cannot override show() in A; overridden method is static void show() ^ 1 error
Nested Classes
Java programming language allows you to define a class within another class Enclosing class OuterClass Class OR { ... Outer Class A nested class is a member class NestedClass { ... of } its enclosing class }
Nested Class 1.Nested has access to other members of the enclosing class,even if they are declared private 2. Can be private, public, protected or friendly access
Example 1 [Non-static Nested Class] class B class A { { int b; private int a; Outer Class Nested B(int b) A(int a) class with { { friendly int c = b+10; access this.a =a; this.b = c; } } void print() void show() { { System.out.println("a="+a) print(); ; System.out.println("b="+b); } Call to } print() of } // End of class B outer class } // End of class A
cont.
b1.show(); } }
To create an inner class instance for nonstatic classes you need an outer class reference. Inner class Reference Outer class Name
If class B is Private then it is not visible in main(). A.B b1 = a1.new B(100); is WRONG/INVALID
Example 2
class B { private int b; Instance Field of B B(int b) { this.b =b; } Outer Class As a void show() { int b=20; System.out.println("a="+a); System.out.println("b="+b); System.out.println("this.b="+this.b); System.out.println("Outer b="+A.this.b); } } // End of B inner class
class innerTest { public static void main(String args[]) { // Create an inner class B's instance // Call show() method // STEP 1 // Create an Outer Instance first
// inner class object instantiation thru anonymous outer // reference A.B b2 = new A(30).new B(-40); a=30 b2.show(); b=20 } this.b=-40 } Outer b=10
static class B { int b; B(int b) Static inner { class int c = b+10; this.b = c; } void show() { // print(); INVALID A a1 = new A(10); a1.print(); System.out.println("b="+b); } } // End of class B } // End of class A
Example cont.
class innertest10 { public static void main(String args[]) { A.B b1 = new A.B(100); b1.show(); Instance of static Inner } class }
Example 2 cont. static class B { private int a; protected static int b=100; B(int a) { this.a=a; } void show() { // A.this.show(); // Won't work show() is non-static in outer display(); // Will work as method is static in outer System.out.println("a="+a); // System.out.println("a="+A.this.a); // Won't work a is non-static in outer System.out.println("b="+b); // Will refer to its own b System.out.println("A'sb="+A.b); // will refer to outer class B
new A(40).show(); // This is how you can call non static methods of outer
} } // End of inner class B } // End of class A
Example 2 cont. class innerTest1 { public static void main(String args[]) { A.B b1 = new A.B(-30); D:\jdk1.3\bin>java innerTest1 b1.show(); } b=10 } a=-30 b=100
A'sb=10
a=40 b=10
class A { private int a; protected static int b=10; A(int a) { this.a=a; 1. } void show() 2. { class B {} 3. } } 4.
Class B is visible only in method show(). It can be used within this show() method only
Local inner classes can only use final variables from its enclosing method.
However inner classes can refer to its fields of enclosing class.
class A { private int a; protected static int b=10; A(int a) { this.a=a; } void show() { int x=10; class B { private int b; B(int b) { this.b=b; } void display() {
D:\jdk1.3\bin>javac innerTest2.java innerTest2.java:23: local variable x is accessed from within inner class; to be declared final System.out.println("x="+x); ^ 1 error
Reference for As a Reference for Bs b Reference is wrong / errorneous x is local variable inside the local method. Local classes can use only final fields from enclosing method
class innertest { public static void main(String args[]) { final int a1=10;
new A(20).show(); print(); }// End of main static void print() {
System.out.println("Hello" ); } }
class A { private int a; private int b; int c; A(int a) { this.a =a; b = a+20; c = a+40; } void show() { System.out.println("a1="+a1); System.out.println("a="+a); System.out.println("b="+b); System.out.println("c="+c); } } //End of A
OUTPUT
Cont
Syntax [ If extending a class] [variable_type_superclass =] new superclass_name() { // properties and methods } [;] Syntax [ If implementing an interface] [variable_type_reference =] new reference_name() { // properties and methods } [;]
A a1 = new A(20){ public void show() { super.show(); System.out.println("Hello"); } public void display() { System.out.println("Hi"); } }; a1.show(); // a1.display(); Calling show from inner class } }
interface X { int sum(int a,int b); int mul(int x,int y); } class innertest2 { public static void main(String args[]) { Anonymous inner class implementing an interface
X x1 = new X() { public int sum(int a,int b) { return a+b; } public int mul(int a,int b) { return a*b; } };
System.out.println(x1.sum(10,20)); System.out.println(x1.mul(10,20)); }// End of main }// End of innertest2
Wrapper Classes
Java uses primitive types, such as int, char, double to hold the basic data types supported by the language. Sometimes it is required to create an object representation of these primitive types. These are collection classes that deal only with such objects. One needs to wrap the primitive type in a class.
To satisfy this need, Java provides classes that correspond to each of the primitive types. Basically, these classes encapsulate, or wrap, the primitive types within a class. Thus, they are commonly referred to as type wrapper. Type wrapper are classes that encapsulate a primitive type within an object. The wrapper types are Byte, Short, Integer, Long, Character, Boolean, Double, Float. These classes offer a wide array of methods that allow to fully integrate the primitive types into Java's object hierarchy.
Wrapper Classes are based upon the well-known software engineering design pattern called the Wrapper pattern.
A design pattern is a template solution to a common problem. It describes the problem and identifies the recommended solution(s) to that problem. Because design patterns deal with common problems, they are often quite abstract!
The Solution:
We create another class that wraps the underlying class/type and provides an appropriate interface for the client. e.g. we create an Integer class that subclasses Object (as all classes do), allowing us to store wrapped ints in Vectors.
Boolean
Void
Number
String
Character
Byte
Short
Integer
Long
Float
Double
int i =integer.parselnt(str); Converts String str into primitive integer i long l = Long.parseLong(str); Converts String str into primitive long l Double d=Double.parseDouble(str); Converting String to primitive double Note: parselnt() and parseLong() methods throw a NumberFormatException if the value of the str does not represent an integer.
sets str to the String 33.34. Getting a wrapper class instance for a value:
e.g. Integer
obj = Integer.getInteger(12);
creates a new Integer object with value 12 and makes obj refer to that object.
Reading a Double
import java.io.*; class MyProgram { public static void main(String[] args) { BufferedReader in = new BufferedReader( new InputStreamReader(System.in)); String line = null; System.out.println("Input Something:" ); try { line = in.readLine(); } catch (IOException ie) { System.out.println("Exception caught: " + ie); } try { double value = Double.parseDouble(line); System.out.println("Value: " + value); } catch (NumberFormatException nfe) { System.out.println("You didn't enter a double number"); } } }
Sample values:
boolObj new Boolean(Boolean.TRUE); charObj = new Character('a'); byteObj = new Byte("100"); shortObj = new Short("32000"); intObj = new Integer(2000000); longObj = new Long(500000000000000000L); floatObj = new Float(1.42); doubleObj = new Double(1.42);
printWrapperInfo(); //method to print objects above
Byte Example
The Byte class encapsulates a byte value. It defines the constants MAX_VALUE and MIN_VALUE and provides these constructors: Byte(byte b) Byte(String str) Here, b is a byte value and str is the string equivalent of a byte value.
Byte Example
Short Example
The Short class encapsulates a short value. It defines the constants MAX_VALUE and MIN_VALUE and provides the following constructors: Short(short s) Short(String str)
Short Example
Integer Example
The Integer class encapsulates an integer value. This class provides following constructors: Integer(int i) Integer(String str) Here, i is a simple int value and str is a String object.
Integer Example
Character Example
The Character class encapsulates a char value. This class provides the following constructor. Character(char ch) Here, c is a char value. charValue() method returns the char value that is encapsulated by a Character object and has the following form: char charValue()
Character Example
Boolean Example
The Boolean class encapsulates a Boolean value. It defines FALSE and TRUE constants. This class provides following constructors: Boolean(Boolean b) Boolean(String str) Here, b is a Boolean value and str is the string equivalent of a Boolean value. The methods associated with Boolean Class are as follows: 1. Boolean booleanValue() 2. Boolean equals(Boolean b) 3. String toString(Boolean b)
Boolean Example
java2all
Clone Method
Recall that the = operator simply copies Object references. e.g., >> Student s1 = new Student(Smith, Jim, 3.13); >> Student s2 = s1; >> s1.setName(Sahil); >> System.out.println(s2.getName()); OP:- Sahil What if we want to actually make a copy of an Object? Most elegant way is to use the clone() method inherited from Object. Student s2 = (Student) s1.clone();
First, note that the clone method is protected in the Object class. This means that it is protected for subclasses as well. Hence, it cannot be called from within an Object of another class and package. To use the clone method, you must override in your subclass and upgrade visibility to public. Also, any class that uses clone must implement the Cloneable interface. This is a bit different from other interfaces that weve seen. There are no methods; rather, it is used just as a marker of your intent. The method that needs to be implemented is inherited from Object.
Deep Copies
For deep copies that recurse through the object ivs, you have to do some more work. super.clone() is first called to clone the first level of ivs. Returned cloned objects object fields are then accessed one by one and clone method is called for each. See DeepClone.java example
Finally, though no one really cares, Object does not support clone();
toString() method
The Object method
String toString();
is intended to return a readable textual representation of the object upon which it is called. This is great for debugging! Best way to think of this is using a print statement. If we execute:
System.out.println(someObject);
we would like to see some meaningful info about someObject, such as values of ivs, etc.
default toString()
By default toString() prints total garbage that no one is interested in
getClass().getName() + '@' + Integer.toHexString(hashCode())
and values (or some important subset). The intent is not to overformat. Typically used for debugging. Always override toString()!
equals() method
Recall that boolean == method compares when applied to object compares references. That is, two object are the same if the point to the same memory. Since java does not support operator overloading, you cannot change this operator. However, the equals method of the Object class gives you a chance to more meaningful compare objects of a given class.
equals subtleties
As with any method that you override, to do so properly you must obey contracts that go beyond interface matching. With equals, the extra conditions that must be met are discussed on the next slide:
equals contract
It is reflexive: for any reference value x, x.equals(x) should
return true. It is symmetric: for any reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true. It is transitive: for any reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true. It is consistent: for any reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the object is modified. For any non-null reference value x, x.equals(null) should return false.
hashcode() method
Java provides all objects with the ability to generate a hash code. By default, the hashing algorithm is typically based on an integer representation of the java address. This method is supported for use with java.util.Hashtable Will discuss Hashtable in detail during Collections discussion.
once, the hashCode method must return the same integer, provided no information used in equals comparisons on the object is modified. If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result. It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hashtables.
finalize() method
Called as final step when Object is no longer used, just before garbage collection Object version does nothing Since java has automatic garbage collection, finalize() does not need to be overridden reclaim memory. Can be used to reclaim other resources close streams, database connections, threads. However, it is strongly recommended not to rely on this for scarce resources. Be explicit and create own dispose method.
Clone Method
Recall that the = operator simply copies Object references. e.g., >> Student s1 = new Student(Smith, Jim, 3.13); >> Student s2 = s1; >> s1.setName(Sahil); >> System.out.println(s2.getName()); OP:- Sahil What if we want to actually make a copy of an Object? Most elegant way is to use the clone() method inherited from Object. Student s2 = (Student) s1.clone();
First, note that the clone method is protected in the Object class. This means that it is protected for subclasses as well. Hence, it cannot be called from within an Object of another class and package. To use the clone method, you must override in your subclass and upgrade visibility to public. Also, any class that uses clone must implement the Cloneable interface. This is a bit different from other interfaces that weve seen. There are no methods; rather, it is used just as a marker of your intent. The method that needs to be implemented is inherited from Object.
Deep Copies
For deep copies that recurse through the object ivs, you have to do some more work. super.clone() is first called to clone the first level of ivs. Returned cloned objects object fields are then accessed one by one and clone method is called for each. See DeepClone.java example
Finally, though no one really cares, Object does not support clone();
toString() method
The Object method
String toString();
is intended to return a readable textual representation of the object upon which it is called. This is great for debugging! Best way to think of this is using a print statement. If we execute:
System.out.println(someObject);
we would like to see some meaningful info about someObject, such as values of ivs, etc.
default toString()
By default toString() prints total garbage that no one is interested in
getClass().getName() + '@' + Integer.toHexString(hashCode())
and values (or some important subset). The intent is not to overformat. Typically used for debugging. Always override toString()!
equals() method
Recall that boolean == method compares when applied to object compares references. That is, two object are the same if the point to the same memory. Since java does not support operator overloading, you cannot change this operator. However, the equals method of the Object class gives you a chance to more meaningful compare objects of a given class.
equals subtleties
As with any method that you override, to do so properly you must obey contracts that go beyond interface matching. With equals, the extra conditions that must be met are discussed on the next slide:
equals contract
It is reflexive: for any reference value x, x.equals(x) should
return true. It is symmetric: for any reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true. It is transitive: for any reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true. It is consistent: for any reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the object is modified. For any non-null reference value x, x.equals(null) should return false.
hashcode() method
Java provides all objects with the ability to generate a hash code. By default, the hashing algorithm is typically based on an integer representation of the java address. This method is supported for use with java.util.Hashtable Will discuss Hashtable in detail during Collections discussion.
once, the hashCode method must return the same integer, provided no information used in equals comparisons on the object is modified. If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result. It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hashtables.
finalize() method
Called as final step when Object is no longer used, just before garbage collection Object version does nothing Since java has automatic garbage collection, finalize() does not need to be overridden reclaim memory. Can be used to reclaim other resources close streams, database connections, threads. However, it is strongly recommended not to rely on this for scarce resources. Be explicit and create own dispose method.