Interfaces in Java
Java Interface
Introduction:
In Java, an interface is a reference type that is similar to a class but has a specific purpose. It defines a contract for classes to follow, specifying a set of methods that the implementing classes must provide. Interfaces allow for the creation of common methods that can be shared among unrelated classes, enabling a level of abstraction and polymorphism in Java programming.
Interface defination :
An interface is declared using the interface keyword and defines a list of abstract methods (methods without implementation) that must be implemented by any class that claims to implement that interface. Additionally, an interface can also contain constants (fields that are implicitly static and final) and default methods (methods with implementation introduced in Java 8).
Interface methods:
Abstract Methods: These are the main components of an interface. Abstract methods do not have an implementation; they only define the method signature. Any class implementing the interface must provide concrete implementations for all the abstract methods defined in the interface.
public interface Shape {
void draw();
double getArea();
}
Constants: Interfaces can have constants, which are public, static, and final by default which means they are accessible without creating an instance of the interface.
public interface Constants {
int MAX_COUNT = 100;
String NAME = "John";
}
Default Method: Starting from Java 8, interfaces can have default methods, which provide a default implementation for a method. Default methods are denoted by the default keyword and can be used as-is by implementing classes. This feature was introduced to maintain backward compatibility when adding new methods to existing interfaces.
public interface Printable {
void print();
default void display() {
System.out.println("Displaying...");
}
}
Static Method: Static methods are methods which are associated with the interface itself, not with any particular instance of the implementing class. Static methods in interfaces are defined using the static keyword.
public interface MathOperations {
static int add(int a, int b) {
return a + b;
}
}
public class Circle implements Shape, Constants {
// Implementation of the abstract methods from Shape interface
// ...
}
Interface Declaration Syntax:
public interface InterfaceName {
// Constants (optional)
// Abstract method declarations (mandatory)
// Default methods (optional)
// Static methods (optional)
}
Interface Declaration Example:
public interface Shape {
// Constants
double PI = 3.14159;
// Abstract methods
void draw();
double getArea();
// Default method
default void printDescription() {
System.out.println("This is a shape.");
}
// Static method
static void displayInfo() {
System.out.println("This is a Shape interface.");
}
}
Interface Implementation: When a class implements an interface, it must provide concrete (non-abstract) implementations for all the abstract methods defined in the interface.
public interface Shape {
void draw();
double getArea();
}
public class Circle implements Shape {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public void draw() {
System.out.println("Drawing a circle.");
}
@Override
public double getArea() {
return Math.PI * radius * radius;
}
}
public class Main {
public static void main(String[] args) {
// Create a Circle object
Circle circle = new Circle(5.0);
// Use the Circle object as a Shape
circle.draw();
double area = circle.getArea();
System.out.println("Circle area: " + area);
}
}
Other Java Interfaces:@FunctionalInterface
public interface MathOperation {
int operate(int a, int b);
}
public class Calculator {
public static void main(String[] args) {
MathOperation add = (a, b) -> a + b;
MathOperation subtract = (a, b) -> a - b;
int resultAdd = performOperation(add, 10, 5);
int resultSubtract = performOperation(subtract, 10, 5);
System.out.println("Addition result: " + resultAdd); // Output: Addition result: 15
System.out.println("Subtraction result: " + resultSubtract); // Output: Subtraction result: 5
}
private static int performOperation(MathOperation operation, int a, int b) {
return operation.operate(a, b);
}
}
Marker Interface:A marker interface is an interface without any methods, serving as a marker or a tag to indicate some special behavior or capability of a class. By implementing a marker interface, a class signals that it possesses certain characteristics or is eligible for specific operations. Two well-known marker interfaces in Java are Serializable and Cloneable.import java.io.*;
class Person implements Serializable {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// Getter and setter methods...
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
public class Main {
public static void main(String[] args) {
Person person = new Person("John", 30);
// Serialization
try {
FileOutputStream fileOut = new FileOutputStream("person.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(person);
out.close();
fileOut.close();
System.out.println("Person object serialized and saved to person.ser");
} catch (IOException e) {
e.printStackTrace();
}
// Deserialization
try {
FileInputStream fileIn = new FileInputStream("person.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
Person deserializedPerson = (Person) in.readObject();
in.close();
fileIn.close();
System.out.println("Deserialized Person: " + deserializedPerson);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
Cloneable marker interface:The Cloneable interface in Java is a marker interface used to indicate that a class supports the clone() method for creating duplicate copies of objects. It allows objects to be cloned, but by default, it performs a shallow copy, meaning referenced objects are not cloned. For deep cloning or classes with mutable objects, additional measures are required.class Person implements Cloneable {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// Getter and setter methods...
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
public class Main {
public static void main(String[] args) {
Person person1 = new Person("John", 30);
try {
// Cloning the object
Person person2 = (Person) person1.clone();
// Modifying the cloned object
person2.setName("Alice");
person2.setAge(25);
System.out.println("Original Person: " + person1);
System.out.println("Cloned Person: " + person2);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
import javax.swing.*;
public class SimpleSwingGUI {
public static void main(String[] args) {
// Create a new JFrame (window)
JFrame frame = new JFrame("Simple Swing GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300, 200);
// Create a new JLabel (text label)
JLabel label = new JLabel("Hello, Swing!");
label.setHorizontalAlignment(JLabel.CENTER);
// Add the label to the frame
frame.add(label);
// Set the frame visible
frame.setVisible(true);
}
}
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class SimpleJavaFXGUI extends Application {
@Override
public void start(Stage primaryStage) {
// Create a new Label (text label)
Label label = new Label("Hello, JavaFX!");
// Create a new StackPane to hold the label
StackPane root = new StackPane();
root.getChildren().add(label);
// Create a new Scene with the StackPane as the root
Scene scene = new Scene(root, 300, 200);
// Set the Scene for the primary stage (window)
primaryStage.setTitle("Simple JavaFX GUI");
primaryStage.setScene(scene);
// Show the primary stage
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}