Unit 5 1
Unit 5 1
classes become more general and probably more abstract. At some point, the
ancestor class becomes so general that you think of it more as a basis for other
classes than as a class with specific instances you want to use. Consider, for
example, an extension of our Employee class hierarchy. An employee is a person,
and so is a student. Let us extend our class hierarchy to include classes Person and
Student
Why bother with so high a level of abstraction? There are some attributes that make
sense for every person, such as name. Both students and employees have names,
and introducing a common superclass lets us factor out the getName method to a
higher level in the inheritance hierarchy.
Now let’s add another method, getDescription, whose purpose is to return a brief
description of the person, such as
It is easy to implement this method for the Employee and Student classes. But what
information can you provide in the Person class? The Person class knows nothing
about the person except the name. Of course, you could implement
Person.getDescription() to return an empty string. But there is a better way. If you
use the abstract keyword, you do not need to implement the method at all.
public abstract String getDescription();
// no implementation required
For added clarity, a class with one or more abstract methods must itself be declared
abstract.
abstract class Person
{...
public abstract String getDescription();
}
In addition to abstract methods, abstract classes can have fields and concrete
methods. For example, the Person class stores the name of the person and has a
concrete method that returns it.
abstract class Person
{
private String name;
public Person(String n)
{
name = n;
}
public abstract String getDescription();
public String getName()
{
return name;
}
}
Abstract methods act as placeholders for methods that are implemented in the
subclasses. When you extend an abstract class, you have two choices. You can
leave some or all of the abstract methods undefined; then you must tag the subclass
as abstract as well. Or you can define all methods, and the subclass is no longer
abstract.
For example, we will define a Student class that extends the abstract Person class
and implements the getDescription method. None of the methods of the Student
class are abstract, so it does not need to be declared as an abstract class.
A class can even be declared as abstract even though it has no abstract methods.
Abstract classes cannot be instantiated. That is, if a class is declared as abstract, no
objects of that class can be created. For example, the expression
Here p is a variable of the abstract type Person that refers to an instance of the non
abstract subclass Student.
Let us define a concrete subclass Student that extends the abstract class
Person:
class Student extends Person
{
private String major;
public Student(String n, String m)
{
super(n);
major = m;
}
public String getDescription()
{
return "a student majoring in " + major;
}
}
The Student class defines the getDescription method. Therefore, all methods in
the Student class are concrete, and the class is no longer an abstract
class.
package abstractClasses;
public Person(String n)
{
name = n;
}
package abstractClasses;
import java.util.Date;
import java.util.GregorianCalendar;
package abstractClasses;
Abstraction is a process of hiding the implementation details and showing only functionality to the user.
Another way, it shows only essential things to the user and hides the internal details, for example, sending SMS
where you type the text and send the message. You don't know the internal processing about the message
delivery.
A class which is declared as abstract is known as an abstract class. It can have abstract and non-abstract
methods. It needs to be extended and its method implemented. It cannot be instantiated.
Points to Remember
A method which is declared as abstract and does not have implementation is known as an abstract method.
In this example, Bike is an abstract class that contains only one abstract method run. Its implementation is
provided by the Honda class.
Interface in Java
An interface in Java is a blueprint of a class. It has static constants and abstract methods.
The interface in Java is a mechanism to achieve abstraction. There can be only abstract
methods in the Java interface, not method body. It is used to achieve abstraction and multiple
inheritance in Java.
In other words, you can say that interfaces can have abstract methods and variables. It cannot
have a method body.
Why use Java interface?
There are mainly three reasons to use interface. They are given below.
The abstract class can also be used to provide some implementation of the interface. In such
case, the end user may not be forced to override all the methods of the interface.
interface A{
void a();
void b();
void c();
void d();
class M extends B{
class Test5{
A a=new M();
a.a();
a.b();
a.c();
a.d();
Output:I am a
I am b
I am c
I am d
Encapsulation in Java
Encapsulation in Java is a process of wrapping code and data together into a single unit, for example, a
capsule which is mixed of several medicines.
We can create a fully encapsulated class in Java by making all the data members of the class private. Now we can use
setter and getter methods to set and get the data in it.
Encapsulation is defined as the wrapping up of data under a single unit. It is the mechanism that binds together
code and the data it manipulates. Another way to think about encapsulation is, that it is a protective shield that
prevents the data from being accessed by the code outside this shield.
Technically in encapsulation, the variables or data of a class is hidden from any other class and can be
accessed only through any member function of its own class in which it is declared.
As in encapsulation, the data in a class is hidden from other classes using the data hiding concept which
is achieved by making the members or methods of a class private, and the class is exposed to the end-
user or the world without providing any details behind implementation using the abstraction concept, so
it is also known as a combination of data-hiding and abstraction.
Encapsulation can be achieved by Declaring all the variables in the class as private and writing public
methods in the class to set and get the values of variables.
Advantages of Encapsulation
Data Hiding: it is a way of restricting the access of our data members by hiding the implementation details.
Encapsulation also provides a way for data hiding. The user will have no idea about the inner implementation of
the class. It will not be visible to the user how the class is storing values in the variables. The user will only know
that we are passing the values to a setter method and variables are getting initialized with that value.
Increased Flexibility: We can make the variables of the class read-only or write-only depending on our
requirements. If we wish to make the variables read-only then we have to omit the setter methods like
setName(), setAge(), etc. from the above program or if we wish to make the variables write-only then we have
to omit the get methods like getName(), getAge(), etc. from the above program
Reusability: Encapsulation also improves the re-usability and is easy to change with new requirements.
Testing code is easy: Encapsulated code is easy to test for unit testing.
Freedom to programmer in implementing the details of the system: This is one of the major advantage of
encapsulation that it gives the programmer freedom in implementing the details of a system. The only
constraint on the programmer is to maintain the abstract interface that outsiders see.
Read-Only class
//A Java class which has only getter methods.
public class Student{
//private data member
private String college="AKG";
//getter method for college
public String getCollege(){
return college;
}
}
Now, you can't change the value of the college data member which is "AKG".
Write-Only class
//A Java class which has only setter methods.
public class Student{
//private data member
private String college;
//getter method for college
public void setCollege(String college){
this.college=college;
}
}
Now, you can't get the value of the college, you can only change the value of college data member.
Occasionally, you need to convert a primitive type like int to an object. All primitive types
have class counterparts. For example, a class Integer corresponds to the primitive type int.
These kinds of classes are usually called wrappers. The wrapper classes have obvious
names: Integer, Long, Float, Double, Short, Byte, Character, Void, and Boolean. (The first six inherit
from the common superclass Number.) The wrapper classes are immutable—you cannot
change a wrapped value after the wrapper has been constructed. They are also final, so
you cannot subclass them.
Suppose we want an array list of integers. Unfortunately, the type parameter inside the
angle brackets cannot be a primitive type. It is not possible to form an ArrayList<int>. Here,
the Integer wrapper class comes in. It is OK to declare an array list of Integer objects.
ArrayList<Integer> list = new ArrayList<>();
Another Java SE 5.0 innovation makes it easy to add and get array elements. The call
list.add(3); is automatically translated to
list.add(Integer.valueOf(3));
This conversion is called autoboxing.
The compiler automatically inserts instructions to unbox the object, increment the
resulting value, and box it back.
In most cases, you get the illusion that the primitive types and their wrappers are one and
the same. There is just one point in which they differ considerably: identity. As you
know, the == operator, applied to wrapper objects, only tests whether the objects have
identical memory locations. The following comparison would therefore probably fail:
Integer a = 1000;
Integer b = 1000;
if (a == b) . . .
Finally, let us emphasize that boxing and unboxing is a courtesy of the compiler, not the
virtual machine. The compiler inserts the necessary calls when it generates the bytecodes
of a class. The virtual machine simply executes those bytecodes.
autoboxing
The automatic conversion of primitive data type into its corresponding
wrapper class is known as autoboxing, for example, byte to Byte, char to
Character, int to Integer, long to Long, float to Float, boolean to Boolean,
double to Double, and short to Short.
Since Java 5, we do not need to use the valueOf() method of wrapper classes
to convert the primitive into objects.
Wrapper class Example: Primitive to Wrapper
//Java program to convert primitive into objects
//Autoboxing example of int to Integer
public class Ex
{
public static void main(String args[])
{
//Converting int into Integer
int a=20;
Integer i=Integer.valueOf(a);
//converting int into Integer explicitly
Integer j=a;
//autoboxing, now compiler will write Integer.valueOf(a) internally
System.out.println(a+" "+i+" "+j);
}
}
Output:
20 20 20
Unboxing
The automatic conversion of wrapper type into its corresponding primitive
type is known as unboxing. It is the reverse process of autoboxing. Since
Java 5, we do not need to use the intValue() method of wrapper classes to
convert the wrapper type into primitives.
Wrapper class Example: Wrapper to Primitive
//Java program to convert object into primitives
//Unboxing example of Integer to int
public class Ex
{
public static void main(String args[])
{
//Converting Integer to int
Integer a=new Integer(3);
int i=a.intValue(); //converting Integer to int explicitly
int j=a; //unboxing, now compiler will write a.intValue() internally
System.out.println(a+" "+i+" "+j);
}
}
Output:
333