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

DSA Notes

Uploaded by

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

DSA Notes

Uploaded by

deviv94340
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 39

Access Modifiers

Access Modifiers specify where a property/method is accessible. There are four types of access modifiers in
java :
• private • protected
• default • public

From the below table, notice


Access Modifier Within Class Within Package Outside Class by Outside Package
sub-class only
Public YES YES YES YES
Protected YES YES YES NO
Default YES YES NO NO
Private YES NO NO NO

that the private access modifier can only be accessed within the class. So, let's try to access private modifiers
outside the class :

class Employee {
private int id;
private String name;
}
public class DSA {
public static void main(String[] args) {
Employee emp1 = new Employee();
emp1.id = 3;
emp1.name = "YSG";
}
}

OUTPUT: java: id has private access in Employee

You can see that the above code produces an error that we're trying to access a private variable outside the
class. So, is there any way by which we can access the private access modifiers outside the class? The
answer is Yes! We can access the private access modifiers outside the class with the help of getters and
setters.

Getters and Setters :

Getter: Returns the value [accessors]


Setter: Sets / updates the value [mutators]

In the below code, we've created total 4 methods:


setName(): The argument passed to this method is assigned to the private variable name.
getName(): The method returns the value set by the setName() method.
setId(): The integer argument passed to this method is assigned to the private variable id.
getId): This method returns the value set by the setId() method.
class Employee {
private int id;
private String name;
public String getName(){
return name;
}
public void setName(String n){
name = n;
}
public void setId(int i){
id = i;
}
public int getId(){
return id;
}
}

public class DSA {


public static void main(String[] args) {
Employee emp1 = new Employee();
emp1.setName("YSG");
System.out.println(emp1.getName());
emp1.setId(1);
System.out.println(emp1.getId());
}
}
Output :
YSG
1

As you can see that we've got our expected output. So, that's how we use the getters and setters method to
get and set the values of private access modifiers outside the class.

Constructors in Java :

• Constructors are similar to methods,, but they are used to initialize an object.
• Constructors do not have any return type(not even void).
• Every time we create an object by using the new() keyword, a constructor is called.
• If we do not create a constructor by ourself, then the default constructor(created by Java compiler) is
called.
• Rules for creating a Constructor :
• The class name and constructor name should be the same.
• It must have no explicit return type.
• It cannot be abstract, static, final, and synchronized.

Types of Constructors in Java :


There are two types of constructors in Java :
1. Default constructor : A constructor with 0 parameters is known as default constructor.
Syntax :
<class_name>(){
//code to be executed on the execution of the constructor
}
Example :
class DSA {
DSA(){
System.out.println("This is the default constructor of DSA
class.");
}
}
public class DSA_constructors {
public static void main(String[] args) {
DSA obj1 = new DSA();
}
}

Output :
This is the default constructor of DSA class.

In the above code, DSA() is the constructor of class DSA The DSA () constructor is invoked automatically
with the creation of object ob1.

2. Parameterized constructor : A constructor with some specified number of parameters is known as a


parameterized constructor.

Syntax :
<class-name>(<data-type> param1, <data-type> param2,......){
//code to be executed on the invocation of the constructor
}

Example:
class DSA{
DSA (String s, int b){
System.out.println("This is the " +b+ "nd week of "+ " "+ s);
}
}
public class DSA_constructors {
public static void main(String[] args) {
DSA obj1 = new DSA("Coding with Java",2);
}
}

Output :
This is the 2nd week of Coding with Java
In the above example, DSA() constructor accepts two parameters i.e.,
string s and int b.

Constructor Overloading in Java :


Just like methods, constructors can also be overloaded in Java. We can overload the Employee constructor
like below:

public Employee (String n)


name = n;
}
Note:
• Constructors can take parameters without being overloaded
• There can be more than two overloaded constructors
• Let's take an example to understand the concept of constructor overloading.

In the below example, the class Employee has a constructor named Employee(). It takes
two argument, i.e., string s & int i. The same constructor is overloaded and then it
accepts three arguments i.e., string s, int i & int salary.

class Employee {
// First constructor
Employee(String s, int i){
System.out.println("The name of the first employee is : " + s);
System.out.println("The id of the first employee is : " + i);
}
// Constructor overloaded
Employee(String s, int i, int salary){
System.out.println("The name of the second employee is : " + s);
System.out.println("The id of the second employee is : " + i);
System.out.println("The salary of second employee is : " +
salary);
}
}
public class DSA_constructors {
public static void main(String[] args) {
Employee Ysg = new Employee("ysg",1);
Employee Mr = new Employee("Mr",2,70000);
}
}
Output :
The name of the first employee is : Ysg
The id of the first employee is : 1
The name of the second employee is : Mr
The id of the second employee is : 2
The salary of second employee is : 70000

Create a class cylinder and use getter and setters to set its radius and height.
Use [1] to calculate surface and volume of the cylinder
Use a constructor and repeat [1].
Overload a constructor used to initialize a rectangle of length and breath 5 for using
custom parameters
Repeat [1] for a sphere.

class Cylinder{
private int radius;
private int height;
public Cylinder(int radius, int height) {
this.radius = radius;
this.height = height;
}
public int getRadius() {
return radius;
}
public void setRadius(int radius) {
this.radius = radius;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public double surfaceArea(){
return 2* Math.PI* radius * radius + 2*Math.PI*radius*height;
}
public double volume(){
return Math.PI * radius * radius * height;
}
}
class Rectangle{
private int length;
private int breadth;
public Rectangle() {
this.length = 4;
this.breadth = 5;
}
public Rectangle(int length, int breadth) {
this.length = length;
this.breadth = breadth;
}
public int getLength() {
return length;
}
public int getBreadth() {
return breadth;
}
}
public class dsa_4 {
Rectangle r = new Rectangle(12, 56);
System.out.println(r.getLength());
System.out.println(r.getBreadth());
}
}

Inheritance in Java

Inheritance in Java is a mechanism in which one object acquires all the properties and behaviors of a
parent object. It is an important part of Object Oriented programming system).
The idea behind inheritance in Java is that you can create new classes that are built upon existing classes.
When you inherit from an existing class, you can reuse methods and fields of the parent class. Moreover,
you can add new methods and fields in your current class also.
Inheritance represents the IS-A relationship which is also known as a parent-child relationship.

Need For Inheritance:


• For Method Overriding (so runtime polymorphism can be achieved).
• For Code Reusability.

Terms used in Inheritance


Class: A class is a group of objects which have common properties. It is a template or blueprint from which
objects are created.
Sub Class/Child Class: Subclass is a class which inherits the other class. It is also called a derived class,
extended class, or child class.
Super Class/Parent Class: Superclass is the class from where a subclass inherits the features. It is also
called a base class or a parent class.
Reusability: As the name specifies, reusability is a mechanism which facilitates you to reuse the fields and
methods of the existing class when you create a new class. You can use the same fields and methods already
defined in the previous class.

The syntax of Java Inheritance:

class Subclass-name extends Superclass-name


{
//methods and fields
}

The extends keyword indicates that you are making a new class that derives from an existing class. The
meaning of "extends" is to increase the functionality. In the terminology of Java, a class which is inherited is
called a parent or superclass, and the new class is called child or subclass.

Example:
import java.io.*;
// Base or Super Class
class Employee {
int salary = 60000;
}
// Inherited or Sub Class
class Engineer extends Employee {
int benefits = 10000;
}
// Driver Class
class SOA {
public static void main(String args[])
{
Engineer E1 = new Engineer();
System.out.println("Salary : " + E1.salary
+ "\nBenefits : " + E1.benefits);
}
}
Output
Salary : 60000
Benefits : 10000

Types of inheritance in java

On the basis of class, there can be three types of inheritance in java: single, multilevel and hierarchical.
In java programming, multiple and hybrid inheritance is supported through interface only.
1. Single Inheritance
In single inheritance, subclasses inherit the features of one superclass. In the image below, class A serves
as a base class for the derived class B.

Example:
class Animal{
void eat(){System.out.println("eating...");}
}
class Dog extends Animal{
void bark(){System.out.println("barking...");}
}
class TestInheritance{
public static void main(String args[]){
Dog d=new Dog();
d.bark();
d.eat();
}
}
Output:
barking...
eating...

2. Multilevel Inheritance
In Multilevel Inheritance, a derived class will be inheriting a base class, and as well as the derived class
also acts as the base class for other classes. In the below image, class A serves as a base class for the
derived class B, which in turn serves as a base class for the derived class C. In Java, a class cannot directly
access the grandparent’s members.

Example:
class Subject{
void study(){System.out.println("study DSA");}
}
class Section extends Subject{ void learn(){System.out.println("learn
concept");}
}
class Student extends Section{
void write(){System.out.println("write in exam");}
}
class Multilevel{
public static void main(String args[]){
Student s=new Student();
s.study();
s.learn();
s.write();
}}

Output:
study DSA
learn concept
write in exam

3. Hierarchical Inheritance
In Hierarchical Inheritance, one class serves as a superclass (base class) for more than one subclass. Here,
class A serves as a base class for the derived classes B, C, and D.

Example:
class DSA {
public void print_DSA() { System.out.println("Subject DSA"); }
}
class SectionN2 extends DSA {
public void print_N2() { System.out.println("Section N2"); }
}
class SectionG1 extends DSA {
public void print_G1() { System.out.println("Section G1"); }
}
// Driver Class
public class Hierarchical {
public static void main(String[] args)
{
SectionN2 obj_N2 = new SectionN2();
obj_N2.print_DSA();
obj_N2.print_N2();
SectionG1 obj_G1 = new SectionG1();
obj_G1.print_DSA();
obj_G1.print_G1();
}
}

Output:
Subject DSA
Section N2
Subject DSA
Section G1

Polymorphism: Polymorphism refers to the concept of having many forms. Simply put, it allows a
message to be displayed in multiple forms.
Two types:
1. Compile Time Polymorphism: achieved by Method Overloading
2. Run Time Polymorphism: achieved by Method Overriding
Method Overloading & Compile Time Polymorphism
• Compile-Time Polymorphism occurs when an object's functionality is determined at compile-time. In
Java, this is achieved through method overloading. Method overloading allows multiple methods with
the same name but different parameter lists within a single class. During compilation, Java distinguishes
which method to call based on the method signatures. This process is also known as static or early
binding. In essence, compile-time polymorphism ensures that the appropriate method is bound to an
object at compile-time, based on its signature.
• Compile-time polymorphism offers flexibility and clarity in code organization. By defining multiple
methods with the same name but different parameter lists, developers can provide various ways to
interact with objects, enhancing code readability and maintainability. However, it's essential to note that
while method overloading is a form of polymorphism, not all programming languages support it or rely
on it for achieving polymorphic behaviour. Java, however, adopts function overloading at compile-time,
making it a key aspect of polymorphism in Java programming.

Java program to demonstrate compile-time polymorphism


public class DSA {
// First addition function
public static int add(int a, int b)
{
return a + b;
}
// Second addition function
public static double add(double a, double b)
{
return a + b;
}
// Driver code
public static void main(String args[])
{
// Here, the first addition function is called
System.out.println(add(6, 4));
// Here, the second addition function is called
System.out.println(add(6.0, 4.0));
}
}
Output:
10
10.0

Method Overriding & Run-Time Polymorphism:


• In Java, Overriding is a feature that allows a subclass or child class to provide a specific implementation
of a method that is already provided by one of its super-classes or parent classes. When a method in a
subclass has the same name, the same parameters or signature, and the same return type(or sub-type) as
a method in its super-class, then the method in the subclass is said to override the method in the super-
class.
• Method overriding is one of the ways by which Java achieves Run Time Polymorphism (Dynamic
Dispatch Method). The version of a method that is executed will be determined by the object that is
used to invoke it. If an object of a parent class is used to invoke the method, then the version in the
parent class will be executed, but if an object of the subclass is used to invoke the method, then the
version in the child class will be executed. In other words, it is the type of the object being referred
to (not the type of the reference variable) that determines which version of an overridden method will be
executed.
Example 1:
// Base Class
class A {
void show() {
System.out.println("This is class A");
}
}
// Inherited class
class B extends A {
void show()
{
System.out.println("This is class B");
}
}
// Driver class
class Main {
public static void main(String[] args)
{
// If a A type reference refers to a A object, then A's show is
called
A obj1 = new A();
obj1.show();
// If a A type reference refers to a B object B's show() is
called. This is called RUN TIME POLYMORPHISM.
A obj2 = new B();
obj2.show();
}
}

Output:
This is class A
This is class B

Example 2:
class Animal {
public void animalSound() {
System.out.println("The animal makes a sound");
}
}
class Pig extends Animal {
public void animalSound() {
System.out.println("The pig says: wee wee");
}
}
class Dog extends Animal {
public void animalSound() {
System.out.println("The dog says: bow wow");
}
}
class Main {
public static void main(String[] args) {
Animal myAnimal = new Animal();
Animal myPig = new Pig();
Animal myDog = new Dog();
myAnimal.animalSound();
myPig.animalSound();
myDog.animalSound();
}
}

Output:
The animal makes a sound
The pig says: wee wee
The dog says: bow wow

Rules for Java Method Overriding


1. Overriding and Access Modifiers
When overriding a method in Java, the access modifier in the subclass can be the same as or more
permissive than the access modifier in the superclass. However, it cannot be more restrictive. For instance,
if a method in the superclass is declared as `protected`, the overriding method in the subclass can be made
`public` or `protected`, but not `private`. Attempting to make it `private` will result in a compilation error.

A Simple Java program to demonstrate Overriding and Access-Modifiers

class Parent {
// private methods are not overridden
private void p1()
{
System.out.println("Its Parent p1");
}
protected void p2()
{
System.out.println("Its Parent p2”);
}
}
class Child extends Parent {
// new p1() method unique to Child class
private void p1()
{
System.out.println("Its child p1");
}
// overriding method with more accessibility
@Override public void p2()
{
System.out.println(“Its child p2");
}
}
class Main {
public static void main(String[] args)
{
Parent obj1 = new Parent();
obj1.p2();
Parent obj2 = new Child();
obj2.p2();
}
}
Output:
Its Parent p2
Its child p2

2. Final methods cannot be overridden


If we don’t want a method to be overridden, we declare it as final.

A Java program to demonstrate that final methods cannot be overridden

class A {
// Can't be overridden
final void display() {}
}
class B extends A {
// This would produce error
void display() {}
}
Output:
13: error: display() in B cannot override display() in A
void display() { }
^
overridden method is final

3. Static methods cannot be overridden(Method Overriding vs Method Hiding):


When you define a static method in a subclass with the same signature as a static method in the
superclass, it's termed as method hiding. The following table outlines the behavior when you define a
method with the same signature as a method in the superclass:

SuperClass Subclass
Result
Method Method
Method hiding. The subclass method hides the superclass
Static Static
method.
No hiding occurs. The subclass method is unrelated to the
Static Instance
superclass method.
No hiding occurs. The subclass method is unrelated to the
Instance Static
superclass method.
Method overriding. The subclass method overrides the superclass
Instance Instance
method.

Java program to show that if the static method is redefined by a derived class, then it is not
overriding, it is hiding

class Parent {
// Static method in base class
// which will be hidden in subclass
static void p1()
{
System.out.println("Its parent static p1");
}
// Non-static method which will be overridden in derived class
void p2()
{
System.out.println(
" Its parent static non - static(instance) p2 ");
}
}
class Child extends Parent {
// This method hides p1() in Parent
static void p1()
{
System.out.println("Its child static p1");
}
// This method overrides p2() in Parent
@Override public void p2()
{
System.out.println(
"Its child non - static(instance) p2 ");
}
}
// Driver class
class Main {
public static void main(String[] args)
{
Parent obj1 = new Child();
// As per overriding rules this should call to class Child static
// overridden method. Since static method cannot be overridden, it
// calls Parent's p1()
obj1.p1();
// Here overriding works and Child's p2() is called
obj1.p2();
}
}
Output:
Its parent static p1
Its child non- static p2

4. Private methods cannot be overridden


Private methods cannot be overridden in Java because they are bound during compile time. Therefore, it's
not possible to override private methods in a subclass.

Example:
class A {
private void privateMethod()
{
System.out.println(
"This is a private method in A");
}

public void publicMethod()


{
System.out.println(
"This is a public method in A");
privateMethod();
}
}
class B extends A {
// This is a new method with the same name as the
// private method in A
private void privateMethod()
{
System.out.println(
"This is a private method in B");
}

// This method overrides the public method in A


public void publicMethod()
{
System.out.println(
"This is a public method in B");
privateMethod(); // calls the private method in B, not A
}
}

public class Main {


public static void main(String[] args)
{
A obj1 = new A();
obj1.publicMethod(); // calls the public method in A
B obj2 = new B();
obj2.publicMethod(); // calls the overridden public method in B
}
}
Output:
This is a public method in A
This is a private method in A
This is a public method in B
This is a private method in B

5. The overriding method must have the same return type (or subtype)
From Java 5.0 onwards it is possible to have different return types for an overriding method in the child
class, but the child’s return type should be a sub-type of the parent’s return type.

Java Program to Demonstrate Different Return Types if Return Type in Overridden


method is Sub-type

// Class 1
class A {
}
// Class 2
class B extends A {
}
// Class 3
// Helper class (Base class)
class Base {
// Method of this class of class1 return type
A fun()
{
// Display message only
System.out.println("Base fun()");
return new A();
}
}
// Class 4
// Helper class extending above class
class Derived extends Base {
// Method of this class of class1 return type
B fun()
{
// Display message only
System.out.println("Derived fun()");

return new B();


}
}
// Class 5
// Main class
public class GFG {
// Main driver method
public static void main(String args[])
{
// Creating object of class3 type
Base base = new Base();
// Calling method fun() over this object
// inside main() method
base.fun();
// Creating object of class4 type
Derived derived = new Derived();
// Again calling method fun() over this object
// inside main() method
derived.fun();
}
}

Output:
Base fun()
Derived fun()

6. Invoking overridden method from sub-class


We can call the parent class method in the overriding method using the super keyword.

// A Java program to demonstrate that overridden method can be called


from sub-class
// Base Class
class Parent {
void show() { System.out.println("Parent's show()"); }
}
// Inherited class
class Child extends Parent {
// This method overrides show() of Parent
@Override void show()
{
super.show();
System.out.println("Child's show()");
}
}

// Driver class
class Main {
public static void main(String[] args)
{
Parent obj = new Child();
obj.show();
}
}
Output:
Parent's show()
Child's show()

Write a Java program to create a base class Shape with a method called
calculateArea(). Create three subclasses: Circle, Rectangle, and Triangle. Override the
calculateArea() method in each subclass to calculate and return the shape's area.

// Shape.java
// Base class Shape
public class Shape {
public double calculateArea() {
return 0; // Default implementation returns 0
}
}

// Circle.java
// Subclass Circle
public class Circle extends Shape {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public double calculateArea() {
return Math.PI * radius * radius; // Calculate area of circle
}
}
// Rectangle.java
// Subclass Rectangle
public class Rectangle extends Shape {
private double width;
private double height;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
@Override
public double calculateArea() {
return width * height; // Calculate area of rectangle
}
}
// Triangle.java
// Subclass Triangle
public class Triangle extends Shape {
private double base;
private double height;
public Triangle(double base, double height) {
this.base = base;
this.height = height;
}
@Override
public double calculateArea() {
return 0.5 * base * height; // Calculate area of triangle
}
}
// Main.java
// Main class
public class Main {
public static void main(String[] args) {
Circle circle = new Circle(4);
System.out.println("Area of Circle: " +
circle.calculateArea());
Rectangle rectangle = new Rectangle(12, 34);
System.out.println("\nArea of Rectangle: " +
rectangle.calculateArea());
Triangle triangle = new Triangle(5, 9);
System.out.println("\nArea of Triangle: " +
triangle.calculateArea());
}
}
Output:
Area of Circle: 50.26548245743669
Area of Rectangle: 408.0
Area of Triangle: 22.5

Write a Java program to create a class Employee with a method called


calculateSalary(). Create two subclasses Manager and Programmer. In each subclass,
override the calculateSalary() method to calculate and return the salary based on their
specific roles.

// Employee.java
// Base class Employee
class Employee {
private String name;
private String role;
public Employee(String name, String role) {
this.name = name;
this.role = role;
}
public String getName() {
return name;
}
public String getRole() {
return role;
}
public double calculateSalary() {
return 0.0;
}
}
// Manager.java
// Subclass Manager
class Manager extends Employee {
private double baseSalary;
private double bonus;
public Manager(String name, double baseSalary, double bonus) {
super(name, "Manager");
this.baseSalary = baseSalary;
this.bonus = bonus;
}
@Override
public double calculateSalary() {
return baseSalary + bonus;
}
}
// Programmer.java
// Subclass Programmer
class Programmer extends Employee {
private double baseSalary;
private double overtimePay;
public Programmer(String name, double baseSalary, double
overtimePay) {
super(name, "Programmer");
this.baseSalary = baseSalary;
this.overtimePay = overtimePay;
}
@Override
public double calculateSalary() {
return baseSalary + overtimePay;
}
}
// Main.java
// Main class
public class Main {
public static void main(String[] args) {
Employee emp1 = new Manager("Lilo Heidi", 7500.0, 1500.0);
Employee emp2 = new Programmer("Margrit Cathrin", 5000.0,
600.0);
System.out.println("Manager: " + emp1.getName() + "\nRole: " +
emp1.getRole() + "\nSalary: $" + emp1.calculateSalary());
System.out.println("\nProgrammer: " + emp2.getName() + "\nRole:
" + emp2.getRole() + "\nSalary: $" + emp2.calculateSalary());
}
}
Output:
Manager: Lilo Heidi
Role: Manager
Salary: $9000.0
Programmer: Margrit Cathrin
Role: Programmer
Salary: $5600.0
Write a Java program to create a base class Sports with a method called play(). Create
three subclasses: Football, Basketball, and Rugby. Override the play() method in each
subclass to play a specific statement for each sport.

// Sports.java
// Base class Sports
class Sports {
public void play() {
System.out.println("Playing a sport...\n");
}
}
// Football.java
// Subclass Football
class Football extends Sports {
@Override
public void play() {
System.out.println("Playing football...");
}
}
// Basketball.java
// Subclass Basketball
class Basketball extends Sports {
@Override
public void play() {
System.out.println("Playing basketball...");
}
}
// Rugby.java
// Subclass Rugby
class Rugby extends Sports {
@Override
public void play() {
System.out.println("Playing rugby...");
}
}
// Main.java
// Main class
public class Main {
public static void main(String[] args) {
Sports sports = new Sports();
Football football = new Football();
Basketball basketball = new Basketball();
Rugby rugby = new Rugby();
sports.play();
football.play();
basketball.play();
rugby.play();
}
}
Sample Output:
Playing a sport...
Playing football...
Playing basketball...
Playing rugby...
JAVA ABSTRACTION
• 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.
• Abstract Classes and Methods:
• An abstract class is a class that is declared abstract—it may or may not include abstract methods.
Abstract classes cannot be instantiated, but they can be subclassed.
• An abstract method is a method that is declared without an implementation (without braces, and
followed by a semicolon), like this:
• abstract void moveTo(double deltaX, double deltaY);
If a class includes abstract methods, then the class itself must be declared abstract, as in:

public abstract class GraphicObject {


// declare fields
// declare nonabstract methods
abstract void draw();
}

Example of Abstract Class that has Abstract method

// Abstract class
abstract class Student {
abstract void printInfo();
}
// Abstraction performed using extends
class Employee extends Student {
voidprintInfo()
{
String name = "Rohan";
int age = 25;
float salary = 3000.5F;
System.out.println(name);
System.out.println(age);
System.out.println(salary);
}
}
// Base class
class Base {
public static void main(String args[])
{
Student s = new Employee();
s.printInfo();
}
}
Output:
Rohan
25
3000.5

Abstract Class having constructor, data member, and methods


Java Program to implement Abstract Class having constructor, data member, and
methods

import java.io.*;
abstract class Subject {
Subject() {
System.out.println("Learning Subject");
}

abstract void topics();


void Learn(){
System.out.println("Understanding syllabus");
}
}
class DSAextends Subject {
void topics(){
System.out.println(" Java , OOPS, Stack");
}
}
class Main {
public static void main(String[] args) {
Subject x=new DSA();
x.topics();
x.Learn();
}
}
Output:
Learning Subject
Java , OOPS, Stack
Understanding syllabus

Java Program to Illustrate Abstract Class containing Constructors

abstract class Parent {


// Constructor of class Parent
Parent()
{
System.out.println("Parent Constructor Called");
}
abstract void disp();// Abstract method
}
class Child extends Parent {
Child() // Constructor of child
{
System.out.println("Child Constructor Called");
}
voiddisp()
{
System.out.println("Child disp() called");
}
}
// Main class
class DSA {
public static void main(String args[])
{
Child d = new Child();
d.disp();
}
}

Output:
Parent Constructor Called
Child Constructor Called
Child disp() called

Java Program to illustrate Abstract class without any abstract method

abstract class B {
void print() // Regular method, not an abstract method.
{
System.out.println("B class is called");
}
}
class D extends B {
}
class Main {
public static void main(String args[])
{
D d = new D();
d.print();
}
}
Output:
B class is called

Java Program to Illustrate Abstract classes can also have final methods

abstract class B {
final void print()
{
System.out.println("Base print() called");
}
}

class D extends B {
}
Class DSA {
public static void main(String args[])
{
{
B b = new D();
b.print();
}
}
}
Output:
Base print() called
If the Child class cannot implement all the abstract methods of the Parent class, it's advisable to mark that
Child class as abstract. This ensures that any subsequent Child class can then implement the remaining
abstract method(s).

import java.io.*;
abstract class D {
abstract void dsa1();
abstract void dsa2();
abstract void dsa3();
}

abstract class Child1 extends D {


public void dsa1() {
System.out.println("Inside dsa1");
}
}

class Child2 extends Child1 {


public void dsa2() {
System.out.println("Inside dsa2");
}
public void dsa3() {
System.out.println("Inside dsa3");
}
}

class DSA {
public static void main(String[] args)
{
// Child1 c1=new Child1();
// c1.dsa1(); // will throw error since it is abstract

Child2 c2 = new Child2();


c2.dsa1();
c2.dsa2();
c2.dsa3();
}
}
Output:
Inside dsa1
Inside dsa2
Inside dsa3

[Abstraction lets you focus on what the object does instead of how it does it.]
Ways to achieve Abstraction
There are two ways to achieve abstraction in java
1. Abstract class (0 to 100%)
2. Interface (100%)
Important points:
✓ An abstract class must be declared with an abstract keyword.
✓ It can have abstract and non-abstract methods.
✓ It cannot be instantiated.
✓ It can have constructors and static methods also.
✓ It can have final methods which will force the subclass not to change the body of the method.

Interface in Java:
An interface is a fully abstract class. It includes a group of abstract methods (methods without a body). In
Java, an interface serves as a means to achieve abstraction by allowing only abstract methods without
method bodies. It facilitates abstraction and multiple inheritances by using interfaces. In essence, interfaces
can contain abstract methods and variables but not method bodies. They also establish an IS-A relationship.
When we classify an entity based on its behavior rather than its attributes, defining it as an interface is
appropriate.

Syntax:
interface {
// declare constant fields
// declare methods that abstract by default.
}

To declare an interface, you use the interface keyword. This establishes total abstraction, meaning all
methods within the interface are declared without bodies, and they are automatically public. Additionally, all
fields within an interface are public, static, and final by default. When a class implements an interface, it
must provide implementations for all the methods declared in that interface. This implementation is
achieved using the implements keyword.
1. Interfaces indeed facilitate total abstraction in Java.
2. While Java doesn't support multiple inheritances with classes, it does so through interfaces, allowing a
class to implement multiple interfaces.
3. Unlike class inheritance, where a class can only extend one superclass, a class can implement any number
of interfaces. This feature promotes loose coupling between classes, enhancing flexibility and
maintainability in software design.
4. Interfaces are a fundamental tool for implementing abstraction in Java, enabling developers to define
contracts without specifying implementation details.

Difference between Abstract class& Interface


An abstract class is a class that cannot be instantiated and may contain both abstract and non-abstract
methods. It serves as a blueprint for other classes to extend. Abstract methods within an abstract class are
those without implementation, which must be overridden by concrete subclasses.
In contrast, an interface is a contract specifying a set of methods that a class must implement. All methods
within an interface are implicitly abstract, lacking implementation details. Classes that implement an
interface must provide concrete implementations for all the methods declared in that interface.
In summary, the key differences are:
- Instantiation: Abstract classes cannot be instantiated directly, while interfaces cannot be instantiated at all.
They serve as templates or blueprints for other classes.
- Method Implementation: Abstract classes can have both abstract and non-abstract methods. Abstract
methods within abstract classes require implementation in subclasses, while non-abstract methods can have
implementations. Interfaces, on the other hand, contain only abstract methods, all of which must be
implemented by any class that implements the interface.
-Inheritance: A class is limited to inheriting from just one abstract class, whereas it can implement multiple
interfaces. This distinction arises from the fact that an abstract class signifies a specific type of object, while
an interface delineates a collection of behaviors.
-Access Modifiers: Abstract classes are capable of employing access modifiers like public, protected, and
private for their methods and properties. Conversely, interfaces are restricted to public access for their
methods and properties.
The query emerges: why opt for interfaces when abstract classes are available?
The rationale lies in the fact that abstract classes can accommodate non-final variables, whereas interface
variables are inherently final, public, and static.

Java program to demonstrate working of interface

import java.io.*;
interface intr1 {

final int b = 20; // public, static and final


// public and abstract
void display();
}
// A class that implements the interface.
class Demo implements intr1 {
public void display(){
System.out.println("DSA");
}
public static void main(String[] args)
{
Demo t = new Demo();
t.display();
System.out.println(b);
}
}
Output:
DSA
20

Java program to demonstrate the real-world example of Interfaces

import java.io.*;
interface Vehicle {
void changeGear(int a);
void speedUp(int a);
void applyBrakes(int a);
}

class Bicycle implements Vehicle{


int speed;
int gear;
@Override
public void changeGear(int newGear){
gear = newGear;
}
@Override
public void speedUp(int increment){
speed = speed + increment;
}
@Override
public void applyBrakes(int decrement){
speed = speed - decrement;
}
public void printStates() {
System.out.println("speed: " + speed
+ " gear: " + gear);
}
}
class Bike implements Vehicle {
int speed;
int gear;
@Override
public void changeGear(int newGear){
gear = newGear;
}
@Override
public void speedUp(int increment){
speed = speed + increment;
}
@Override
public void applyBrakes(int decrement){
speed = speed - decrement;
}
public void printStates() {
System.out.println("speed: " + speed
+ " gear: " + gear);
}
}
class DSA {
public static void main (String[] args) {
Bicycle bicycle = new Bicycle();
bicycle.changeGear(2);
bicycle.speedUp(3);
bicycle.applyBrakes(1);
System.out.println("Bicycle present state :");
bicycle.printStates();
Bike bike = new Bike();
bike.changeGear(1);
bike.speedUp(4);
bike.applyBrakes(3);
System.out.println("Bike present state :");
bike.printStates();
}
}
Output:
Bicycle present state :
speed: 2 gear: 2
Bike present state :
speed: 1 gear: 1

Multiple Inheritance in Java Using Interface

Multiple Inheritance is a concept in Object-Oriented Programming (OOP) that cannot be directly


implemented in Java using classes. However, Java allows for multiple inheritances through interfaces. Let's
verify this statement with an example.

interface P{
void print();
}
interface S{
void show();
}
class Main implements P,S{

public void print(){


System.out.println("Study");
}
public void show(){
System.out.println("DSA");
}

public static void main(String args[]){


Main obj = new Main();
obj.print();
obj.show();
}
}
Output:
Study
DSA
Multiple inheritance is not supported through classes in Java due to the potential for ambiguity in resolving
conflicting method implementations from multiple parent classes. However, it is possible through interfaces
because there is no such ambiguity. In the case of interfaces, the implementation is provided by the
implementing class, thus avoiding conflicts.

interface Print{
void disp();
}
interface Show {
void disp();
}

class Demo implements Print,Show{

public void print(){

System.out.println("Java");
}
public static void main(String args[]){

Demo obj = new Demo();

obj.disp();

}
}

Output: Java

Explanation: In the above example, Print and Show interface have same methods but its implementation is
provided by class Demo, so there is no ambiguity.
Interface inheritance
A class implements an interface, but one interface extends another interface.

interface Print{
void print();
}
interface Show extends Print{
void show();
}
class Demo implements Show{
public void print(){
System.out.println("Hi");
}
public void show(){
System.out.println("DSA");
}
public static void main(String args[]){
Demo obj = new Demo();
obj.print();
obj.show();
}
}

Output:
Hi
DSA

• Java 8 Default Method in Interface


• Since Java 8, we can have method body in interface. But we need to make it default method. Let's see an
example:

interface Draw{
void draw();
default void msg(){
System.out.println("default method");
}
}
class Rectangle implements Draw{
public void draw(){
System.out.println("drawing rectangle");
}
}
class DemoInterfaceDefault{
public static void main(String args[]){
Draw d=new Rectangle();
d.draw();
d.msg();
}
}

Output:
drawing rectangle
default method
Java 8 Static Method in Interface
Since Java 8, we can have static method in interface. Let's see an example:

interface Draw{
void draw();
static int cube(int a){
return a*a*a;
}
}

class Rectangle implements Draw{


public void draw(){
System.out.println("drawing rectangle");
}
}

class DemoInterfaceStatic{
public static void main(String args[]){
Draw d=new Rectangle();
d.draw();
System.out.println(Draw.cube(3));
}
}

Output:
drawing rectangle
27

Hybrid Inheritance using interfaces


A hybrid inheritance is a combination of more than one types of inheritance. For example when class A and
B extends class C & another class D extends class A then this is a hybrid inheritance, because it is a
combination of single and hierarchical inheritance.

class C
{
public void disp()
{
System.out.println("C");
}
}
class A extends C
{
public void disp()
{
System.out.println("A");
}
}
class B extends C
{
public void disp()
{
System.out.println("B");
}
}
class D extends A
{
public void disp()
{
System.out.println("D");
}
public static void main(String args[]){
D obj = new D();
obj.disp();
}
}
Output:
D

Super keyword in java


In Java, the super keyword is a reference variable that is used to refer to the immediate parent class object.
When you create an instance of a subclass, an instance of the parent class is created implicitly, and it is
referred to by the super reference variable.

Use of super keyword:


1. Accessing Parent Class Instance Variables: You can use super to refer to immediate parent class
instance variables.
class Parent {
int parentVar = 10;
}

class Child extends Parent {


int childVar = 20;

void display() {
System.out.println("Parent variable: " +
super.parentVar);
System.out.println("Child variable: " + childVar);
}
}

public class Main {


public static void main(String[] args) {
Child obj = new Child();
obj.display();
}
}

Output:
Parent variable: 10
Child variable: 20

Invoking Parent Class Methods: You can use super to invoke immediate parent
class methods.

class Parent {
void parentMethod() {
System.out.println("Parent method");
}
}

class Child extends Parent {


void childMethod() {
super.parentMethod();
System.out.println("Child method");
}
}

public class Main {


public static void main(String[] args) {
Child obj = new Child();
obj.childMethod();
}
}

Output:
Parent method
Child method

Invoking Parent Class Constructor: You can use super() to invoke the immediate
parent class constructor.

class Parent {
Parent() {
System.out.println("Parent constructor");
}
}

class Child extends Parent {


Child() {
super(); // Calls the parent class constructor
System.out.println("Child constructor");
}
}

public class Main {


public static void main(String[] args) {
Child obj = new Child();
}
}

Output:
Parent constructor
Child constructor

Example to show super keyword where super() is provided by the compiler


implicitly.

class Animal{
Animal(){System.out.println("animal is created");}
}
class Dog extends Animal{
Dog(){
System.out.println("dog is created");
}
}
class Main{
public static void main(String args[]){
Dog d=new Dog();
}
}

Output:
animal is created
dog is created

class Person{
int id;
String name;
Person(int id,String name){
this.id=id;
this.name=name;
}
}
class Emp extends Person{
float salary;
Emp(int id,String name,float salary){
super(id,name);//reusing parent constructor
this.salary=salary;
}
void display(){System.out.println(id+" "+name+" "+salary);}
}
class Main{
public static void main(String[] args){
Emp e1=new Emp(1,"ysg",50000f);
e1.display();
}
}

Output

1 ysg 50000.0

this keyword in Java:


The ‘this’ keyword in Java refers to the current objectin a method or constructor. It's particularly
useful in scenarios where you need to differentiate between instance variables and local variables or
parameters with the same name.

Following are the ways to use the ‘this’ keyword in Java mentioned below:
• Using the ‘this’ keyword to refer to current class instance variables.
• Using this() to invoke the current class constructor
• Using ‘this’ keyword to return the current class instance
• Using ‘this’ keyword as the method parameter
• Using ‘this’ keyword to invoke the current class method
• Using ‘this’ keyword as an argument in the constructor call

Using ‘this’ keyword to refer to current class instance variables

class A {
int a;
int b;

// Parameterized constructor
A(int a, int b)
{
this.a = a;
this.b = b;
}

void display()
{
// Displaying value of variables a and b
System.out.println("a = " + a + " b = " + b);
}

public static void main(String[] args)


{
A obj = new A(10, 20);
obj.display();
}
}
Output:
a = 10 b = 20

Using this() to invoke current class constructor

class A {
int a;
int b;
A()
{
this(10, 20);
System.out.println(
"Inside default constructor \n");
}
A(int a, int b)
{
this.a = a;
this.b = b;
System.out.println(
"Inside parameterized constructor");
}
public static void main(String[] args)
{
A obj = new A();
}
}
Output:
Inside parameterized constructor
Inside default constructor

Using ‘this’ keyword to return the current class instance

class A {
int a;
int b;
A()
{
a = 10;
b = 20;
}

A get() { return this; }


void display()
{
System.out.println("a = " + a + " b = " + b);
}
public static void main(String[] args)
{
A obj = new A();
obj.get().display();
}
}

Output:
a = 10 b = 20

Using ‘this’ keyword as a method parameter

class A {
int a;
int b;
A()
{
a = 10;
b = 20;
}
void display(A obj)
{
System.out.println("a = " + obj.a
+ " b = " + obj.b);
}
void get() {
display(this);
}
public static void main(String[] args)
{
A obj = new A();
obj.get();
}
}
Output:
a = 10 b = 20

Using ‘this’ keyword to invoke the current class method

class A {
void display()
{
this.show();
System.out.println("Inside display function");
}
void show()
{
System.out.println("Inside show function");
}
public static void main(String args[])
{
A obj1 = new A();
obj1.display();
}
}
Output:
Inside show function
Inside display function

Using ‘this’ keyword as an argument in the constructor call

class A {
B obj;
A(B obj)
{
this.obj = obj;
obj.display();
}
}
class B {
int x = 5;
B() {
A obj = new A(this);
}
void display()
{
System.out.println("Value of x in Class B : " + x);
}
public static void main(String[] args)
{
B obj = new B();
}
}

Output:
Value of x in Class B : 5
Advantages of using the `this` reference:

Distinguishing between instance variables and local variables with the same name:
• The `this` reference helps to differentiate between instance variables and local variables that share the
same name, reducing ambiguity and ensuring correct assignment.
• Passing the current object as an argument to another method: By using `this`, the current object can be
passed as an argument to another method, enabling operations that require the object's state or behavior.
• Returning the current object from a method: `this` can be returned from a method, allowing methods to
return the current object itself, which can be useful for method chaining or maintaining fluent interfaces.
• Invoking a constructor from another overloaded constructor in the same class: The `this` reference can
be used to invoke another constructor within the same class, allowing code reuse and reducing
redundancy in overloaded constructors.

Disadvantages of using the `this` reference:


• Overuse can make the code harder to read and understand: Excessive use of `this` can clutter the code and
make it less readable, especially in situations where it is not necessary for disambiguation.
• Adding unnecessary overhead to the program: Using `this` unnecessarily may introduce unnecessary
overhead to the program, impacting performance and increasing complexity without adding significant
benefits.
• Using `this` in a static context results in a compile-time error: Since `this` refers to the current object
instance, attempting to use it in a static context, such as a static method or initializer, will result in a
compile-time error. This limitation restricts its usage in certain scenarios.

Packages In java
In Java, a package serves as a container for organizing related classes, interfaces, and sub-packages.
Packages in Java can be classified into two main categories: built-in packages and user-defined packages.
Built-in packages encompass a variety of functionalities and are provided by the Java platform. Examples of
built-in packages include java, lang, awt, javax, swing, net, io, util, and sql. These packages offer a wide
range of pre-implemented classes and interfaces to facilitate common programming tasks and operations.

Advantage of Java Package


1) Java package is used to categorize the classes and interfaces so that they can be easily maintained.
2) Java package provides access protection.
3) Java package removes naming collision.

The package keyword is used to create a package in java.


//save as Simple.java
package mypack;
public class Simple{
public static void main(String args[]){
System.out.println("Welcome to package");
}
}

How to access package from another package?


There are three ways to access the package from outside the package.

import package.*;
import package.classname;
fully qualified name.

1) Using packagename.
If you use package.* then all the classes and interfaces of this package will be accessible but not
subpackages.
The import keyword is used to make the classes and interface of another package accessible to the current
package.

Example of package that import the packagename.*


/save by A.java
package pack;
public class A{
public void msg(){System.out.println("Hello");}
}
//save by B.java
package mypack;
import pack.*;

class B{
public static void main(String args[]){
A obj = new A();
obj.msg();
}
}
Output: Hello

2) Using packagename.classname
If you import package.classname then only declared class of this package will be accessible.

Example of package by import package.classname


//save by A.java

package pack;
public class A{
public void msg(){System.out.println("Hello");}
}
//save by B.java
package mypack;
import pack.A;
class B{
public static void main(String args[]){
A obj = new A();
}
}

Output:
Output: Hello

3) Using fully qualified name


If you use fully qualified name then only declared class of this package will be accessible. Now there is no
need to import. But you need to use fully qualified name every time when you are accessing the class or
interface. It is generally used when two packages have same class name e.g. java.util and java.sql packages
contain Date class.

Example of package by import fully qualified name

//save by A.java
package pack;
public class A{
public void msg(){System.out.println("Hello");}
}
//save by B.java
package mypack;
class B{
public static void main(String args[]){
pack.A obj = new pack.A();//using fully qualified name
obj.msg();
}
}
Output: Hello

Note: If you import a package, all the classes and interface of that package will be imported excluding the
classes and interfaces of the subpackages. Hence, you need to import the subpackage as well. Sequence of
the program must be package then import then class.
Subpackage in java
Package inside the package is called the subpackage. It should be created to categorize the package further.

Example of Subpackage

package com.dsa.core;
class Demo{
public static void main(String args[]){
System.out.println("Hello subpackage");
}
}

Output: Hello subpackage

Using Static Import


Static import is a feature introduced in Java programming language ( versions 5 and above ) that allows
members ( fields and methods ) defined in a class as public static to be used in Java code without
specifying the class in which the field is defined.
Following program demonstrates static import :

import static java.lang.System.*;

class Demo
{
public static void main(String args[])
{
// We don't need to use 'System.out' as imported using static.
out.println("JavaforDSA");
}
}
Output:
JavafortDSA

You might also like