Object
Object
• Every class is directly or indirectly derived from the Object class. If a class does not extend any other class
then it is a direct child class of the Java Object class and if it extends another class then it is indirectly
derived.
• The Object class provides several methods such as toString(),equals(), hashCode(), and many others.
• The Object class acts as a root of the inheritance hierarchy in any Java Program.
Here, we use the toString() and hashCode() methods of Object class to provide a custom string representation for a
class.
// Java Code to demonstrate Object class class Person {
String n; //name
Output
Person{name:'Geek'}
321001045
Explanation: In the above example, we override the toString() method to provide a custom string representation of
the Person class and use the hashCode() method to display the default hash code value of the object.
• toString() method
• hashCode() method
• finalize() method
• getClass() method
• clone() method
The toString() provides a String representation of an object and is used to convert an object to a String. The default
toString() method for class Object returns a string consisting of the name of the class of which the object is an
instance, the at-sign character `@', and the unsigned hexadecimal representation of the hash code of the object.
Note: Whenever we try to print any Object reference, then internally toString() method is called.
Example:
public class Student { public String toString() { return "Student object";
}
}
Explanation: The toString() method is overridden to return a custom string representation of the Student object.
2. hashCode() Method
For every object, JVM generates a unique number which is a hashcode. It returns distinct integers for distinct
objects. A common misconception about this method is that the hashCode() method returns the address of the
object, which is not correct. It converts the internal address of the object to an integer by using an algorithm. The
hashCode() method is native because in Java it is impossible to find the address of an object, so it uses native
languages like C/C++ to find the address of the object.
It returns a hash value that is used to search objects in a collection. JVM(Java Virtual Machine) uses the hashcode
method while saving objects into hashing-related data structures like HashSet, HashMap, Hashtable, etc. The main
advantage of saving objects based on hash code is that searching becomes easy.
Note: Override of hashCode() method needs to be done such that for every object we generate a unique number. For
example, for a Student class, we can return the roll no. of a student from the hashCode() method as it is unique.
Example:
public class Student {
int roll;
@Override public int hashCode() { return roll;
}
}
Explanation: The hashCode() method is overridden to return a custom hash value based on the roll of the Student
object.
The equals() method compares the given object with the current object. It is recommended to override this method
to define custom equality conditions.
Note: It is generally necessary to override the hashCode() method whenever this method is overridden, so as to
maintain the general contract for the hashCode method, which states that equal objects must have equal hash
codes. Example:
public class Student {
int roll;
@Override
public boolean equals(Object o) { if (o instanceof Student) { return this.roll ==
((Student) o).roll;
}
return false;
}
}
Explanation: The equals() method is overridden to compare roll between two Student objects.
4. getClass() method
The getClass() method returns the class object of "this" object and is used to get the actual runtime class of the
object. It can also be used to get metadata of this class. The returned Class object is the object that is locked by static
synchronized methods of the represented class. As it is final so we don't override it.
Example:
// Demonstrate working of getClass() public class Geeks { public static void
main(String[] args)
{
Object o = new String("GeeksForGeeks");
Class c = o.getClass();
System.out.println("Class of Object o is: "
+ c.getName());
}
}
Output
Explanation: The getClass() method is used to print the runtime class of the "o" object.
Note: After loading a .class file, JVM will create an object of the type java.lang.Class in the Heap area. We can use
this class object to get Class level information. It is widely used in Reflection
5. finalize() method
The finalize() method is called just before an object is garbage collected. It is called the Garbage Collector on an
object when the garbage collector determines that there are no more references to the object. We should override
finalize() method to dispose of system resources, perform clean-up activities and minimize memory leaks. For
example, before destroying the Servlet objects web container, always called finalize method to perform clean-up
activities of the session.
Note: The finalize method is called just once on an object even though that object is eligible for garbage collection
multiple times.
Example:
Example:
// Demonstrate working of finalize() public class Geeks { public static void
main(String[] args) {
Geeks t = new Geeks();
System.out.println(t.hashCode());
t = null;
// calling garbage collector
System.gc();
System.out.println("end");
}
@Override protected void finalize()
{
System.out.println("finalize method called");
}
}
Output 1510467688
called
Explanation: The finalize() method is called just before the object is garbage collected.
6. clone() method
The clone() method creates and returns a new object that is a copy of the current object.
Example:
public class Book implements Cloneable {
private String t; //title
public Book(String t) {
this.t = t;
}
@Override public Object clone() throws CloneNotSupportedException { return
super.clone();
}
}
Explanation: The clone() method is overridden to return a cloned copy of the Book object.
These methods are related to thread Communication in Java. They are used to make threads wait or notify others in
concurrent programming.
Output
Explanation: The above example demonstrates the use of toString(), equals(), hashCode(), and clone() methods in
the Book class.
Abstract Class
System.out.println(name);
System.out.println(age);
System.out.println(salary);
}
}
Output
avinash 21
222.2
• data member
• abstract method
• constructor
• main() method.
void Learn(){
System.out.println("Preparing Right Now!");
}
}
x.syllabus();
x.Learn();
}
}
Output
Learning Subject
C , Java , C++
Let us elaborate on these observations and do justify them with help of clean java programs as follows.
Observation 1
In Java, just like in C++ an instance of an abstract class cannot be created, we can have references to abstract class
type though. It is as shown below via the clean Java program.
Example
// Java Program to Illustrate
// that an instance of Abstract
// Class can not be created
Output
Like C++, an abstract class can contain constructors in Java. And a constructor of an abstract class is called when an
instance of an inherited class is created. It is as shown in the program below as follows:
Example:
// Java Program to Illustrate Abstract Class
// Can contain Constructors
// Constructor of class 1
Base()
{
// Print statement
System.out.println("Base Constructor Called");
}
// Class 2
class Derived extends Base {
// Constructor of class2
Derived()
{
System.out.println("Derived Constructor Called");
}
// Class 3
// Main class class GFG {
Output
Observation 3
In Java, we can have an abstract class without any abstract method. This allows us to create classes that cannot be
instantiated but can only be inherited. It is as shown below as follows with help of a clean java program.
Example:
// Java Program to illustrate Abstract class
// Without any abstract method
// Class 1
// An abstract class without any abstract method abstract class Base {
Output
Observation 4
Abstract classes can also have final methods (methods that cannot be overridden)
Example:
// Java Program to Illustrate Abstract classes
// Can also have Final Methods
b.fun();
}
}
}
Output
Observation 5
For any abstract java class we are not allowed to create an object i.e., for an abstract class instantiation is not
possible.
// Java Program to Illustrate Abstract Class
Output:
Observation 6
Similar to the interface we can define static methods in an abstract class that can be called independently without
an object.
// Java Program to Illustrate
// Static Methods in Abstract
// Class Can be called Independently
// Print statement
System.out.println("Geeks for Geeks");
}
}
// Class 2
// Main class extending Helper class public class GFG extends Helper {
Output
Geeks for Geeks
Observation 7
We can use the abstract keyword for declaring top-level classes (Outer class) as well as
inner classes as abstract import java.io.*;
abstract class B {
// declaring inner class as abstract with abstract
// method abstract class C { abstract void myAbstractMethod();
}
}
class D extends B { class E extends C {
// implementing the abstract method void myAbstractMethod()
{
System.out.println(
"Inside abstract method implementation");
}
}
}
Output
Observation 8
If a class contains at least one abstract method then compulsory that we should declare the class as abstract
otherwise we will get a compile-time error ,If a class contains at least one abstract method then, implementation
is not complete for that class, and hence it is not recommended to create an object so in order to restrict object
creation for such partial classes we use abstract keyword. /*package whatever //do not write package name
here */
import java.io.*;
Hello
Observation 9
If the Child class is unable to provide implementation to all abstract methods of the Parent class then we should
declare that Child class as abstract so that the next level Child class should provide implementation to the remaining
abstract method.
// Java Program to demonstrate
// Observation import java.io.*;
abstract class Demo { abstract void m1(); abstract void m2(); abstract void
m3();
}
Output
Inside m1
Inside m2
Inside m3
Java Interface
An Interface in Java programming language is defined as an abstract type used to specify the behaviour of a class. An
interface in Java is a blueprint of a behaviour. A Java interface contains static constants and abstract methods.
• In other words, interfaces primarily define methods that other classes must implement.
• An interface in Java defines a set of behaviours that a class can implement, usually representing a CAN-DO
relationship, but not always in every scenario.
Example: This example demonstrates how an interface in Java defines constants and abstract methods, which are
implemented by a class.
interface testInterface {
class Geeks
{
Output
Geek
10
Note: In Java, the abstract keyword applies only to classes and methods, indicating that they cannot be instantiated
directly and must be implemented. When we decide on a type of entity by its behaviour and not via attribute we
should define it as an interface.
Syntax:
interface InterfaceName {
// Constant fields (public static final by default) int CONSTANT = 10;
// Abstract method (public abstract by default) void methodName(); //
Default method (JDK 8+) default void defaultMethod() {
System.out.println("Default implementation");
}
// Static method (JDK 8+) static void staticMethod() {
System.out.println("Static method in interface");
}
// Private method (JDK 9+) private void privateMethod() {
System.out.println("Private helper method");
}
}
Note:
• Private methods can only be called inside default or static methods in the interface, not by implementing
classes
• Static methods are also accessible via the3interface itself not through objects
To declare an interface, use the interface keyword. It is used to provide total abstraction. That means all the
methods in an interface are declared with an empty body and are public and all fields are public, static and final by
default. A class that implements an interface must implement all the methods declared in the interface. To
implement the interface, use the implements keyword.
A class can extend another class and similarly, an interface can extend another interface. However, only a class can
implement an interface and the reverse (an interface implementing a class) is not allowed.
• Use a class when you need to represent a real-world entity with attributes (fields) and behaviors (methods).
• Use a class when you need to create objects that hold state and perform actions
• Classes are used for defining templates for objects with specific functionality and properties.
• Use an interface when you need to define a contract for behavior that multiple classes can implement.
Let’s consider the example of Vehicles like bicycles, cars and bikes share common functionalities, which can be
defined in an interface, allowing each class (e.g., Bicycle, Car, Bike) to implement them in its own way. This approach
ensures code reusability, scalability and consistency across different vehicle types.
Example: This example demonstrates how an interface can be used to define common behavior for different classes
(Bicycle and Bike) that implement the interface.
import java.io.*;
interface Vehicle {
// Decrease speed
@Override public void applyBrakes(int decrement){ speed = speed -
decrement;
}
class Main
{
public static void main (String[] args)
{
// Instance of Bicycle(Object)
Bicycle bicycle = new Bicycle();
bicycle.changeGear(2); bicycle.speedUp(3);
bicycle.applyBrakes(1);
Output
Java does not support multiple inheritance with classes to avoid ambiguity, but it supports multiple inheritance using
interfaces.
Example: This example demonstrates how a class can implement multiple interfaces (Add and Sub) to provide
functionality for both addition and subtraction operations.
import java.io.*; // Add interface interface Add{
int add(int a,int b);
}
// Sub interface interface Sub{
int sub(int a,int b);
}
// Calculator class implementing Add and Sub class Cal implements Add , Sub
{
// Method to add two numbers
public int add(int a,int b){
return a+b;
}
// Method to sub two numbers
public int sub(int a,int b){ return a-b;
}
}
class GFG{ // Main Method
public static void main (String[] args)
{
// instance of Cal class
Cal x = new Cal();
System.out.println("Addition : " + x.add(2,1));
System.out.println("Substraction : " + x.sub(2,1));
}
}
Output
Addition : 3
Substraction : 1
There are certain features added to Interfaces in JDK 8 update mentioned below:
1. Default Methods
• Useful for adding new methods to interfaces without breaking existing implementations.
Example: This example demonstrates the use of default methods in interfaces (introduced
in JDK 8) to provide a method implementation within the interface itself. // interfaces
can have methods from JDK 1.8 onwards interface TestInterface
{
final int a = 10;
Output
hello
2. Static Methods
• These methods are called directly using the interface name and are not inherited by implementing classes.
Another feature that was added in JDK 8 is that we can now define static methods in interfaces that can be called
independently without an object. These methods are not inherited.
Example: This example demonstrates the use of static methods in interfaces (introduced in JDK 8), which can be
called directly using the interface name without needing an instance.
interface TestInterface
{ final int a = 10; static void display()
{
System.out.println("hello");
}
}
// A class that implements the interface. class TestClass implements TestInterface
{
// Driver Code public static void main (String[] args)
{
TestInterface.display();
}
}
Output
hello
3. Functional Interface
• The @FunctionalInterface annotation can be used to indicate that an interface is a functional interface,
although it’s optional.
Example: This example demonstrates the use of a functional interface in Java, which contains exactly one abstract
method and can be used with lambda expressions or method references.
@FunctionalInterface interface
MyFunctionalInterface { void
singleAbstractMethod();
Extending Interfaces
One interface can inherit another by the use of keyword extends. When a class implements an interface that inherits
another interface, it must provide an implementation for all methods required by the interface inheritance chain.
Example: This example demonstrates how interface inheritance works in Java, where one interface (B) extends
another (A) and a class (GFG) implements all the methods from both interfaces.
interface A { void method1(); void method2();
}
Output
Method 1
Method 2
Method 3
In a Simple way, the interface contains multiple abstract methods, so write the implementation in implementation
classes. If the implementation is unable to provide an implementation of all abstract methods, then declare the
implementation class with an abstract modifier and complete the remaining method implementation in the next
created child classes. It is possible to declare multiple child classes but at final we have completed the
implementation of all abstract methods.
// Level 3 class Dev3 extends Dev2 { public void loan() {} public void
account() {} }
Output
Advantages of Interfaces
• Without bothering about the implementation part, we can achieve the security of the implementation.
• In Java, multiple inheritances are not allowed, however, you can use an interface to make use of it as you
can implement more than one interface.
1. Private methods
1. Private Methods
• Private methods are defined within the interface but it cannot be accessed by the implementing classes.
• Private methods cannot be overridden by implementing classes as they are not inherited.
Example: This example demonstrates the use of private methods in interfaces (introduced in JDK 8) that can be
called by default methods within the same interface but are not accessible outside the interface.
interface Vehicle {
// Private method for internal use private void startEngine() {
System.out.println("Engine started.");
}
// Default method that uses the private method default void drive() {
// Calls the private method startEngine();
System.out.println("Vehicle is now driving.");
}
}
class Car implements Vehicle {
// Car class implements Vehicle interface and inherits the default method 'drive'
}
public class Main { public static void main(String[] args) {
Car car = new Car();
// This will call the default method, which in turn calls the private method
car.drive();
}
}
Output
Engine started.
Although Class and Interface seem the same there are certain differences between Classes and Interface. The major
differences between a class and an interface are mentioned below: