Classes

package com.hitarth.packages;

class Calculator {
    int a;

    public int add(int x, int y) {
        a = x + y;
        return a;
    }
}

public class _01_classes {
    public static void main(String[] args) {
        int num1 = 4;
        int num2 = 5;

        Calculator calc = new Calculator();
        int res = calc.add(num1, num2);
        System.out.println(res); // → 9

    }
}

Array of Objects :

package com.hitarth.packages;

class Student
{
    int roll;

    public Student(int roll) {
        this.roll = roll;
    }
}

public class _02_ArrayOfObjects {

    public static void main(String[] args) {

        Student s1 = new Student(23);
        Student s2 = new Student(43);
        Student s3 = new Student(12);

        Student[] arr = new Student[3];
        arr[0] = s1;
        arr[1] = s2;
        arr[2] = s3;

        System.out.println(arr[0].roll); // → 23

    }
}

String Buffer

package com.hitarth.packages;

public class _03_StringBuffer {

    public static void main(String[] args) {

        // StringBuffer let's us change data (i.e. mutable, unlike a String which is immutable)
        StringBuffer sb = new StringBuffer();

        // string buffer gives us a size of 16bytes by default
        System.out.println(sb.capacity()); // → 16
        sb.append("Navin");
        System.out.println(sb.capacity()); // → 16

        sb.delete(0, 13);
        sb.append("apekasnfkeloanfs"); // total 16 chars
        System.out.println(sb.capacity()); // → 16
        sb.append("a"); // now total 17 chars
        System.out.println(sb.capacity()); // → 34

        //type "sb." to see all performable functions
    }
}

Encapsulation : (Private Variables)

package com.hitarth.packages;

class Human
{
    // here private means that this particular variable is accessible only inside the class
    // this private data should be accessible via a method
    private int age;

    public Human(int age) {
        this.age = age;
    }

    public int getAge()
    {
        return age;
    }
}

public class _04_Encapsulation {
    public static void main(String[] args) {
        Human obj = new Human(23);
        System.out.println(obj.age); // → Error : 'age' has private access in 'com.hitarth.packages.Human'
        System.out.println(obj.getAge()); // → 23

    }
}

this() and super() :

//Class A is referred to as the superclass or base class.
//Class B is referred to as the subclass or derived class.

class A {
    //constructor
    public A() {
        super();
        System.out.println("in A");
    }

    public A(int n) {
        super();
        System.out.println("in A int n");
    }

}

class B extends A {
    //constructor
    public B() {
        super();
        System.out.println("in B");
    }

    public B(int n) {
        super(n);
        System.out.println("in B int n");
    }
}

class C extends A {
    //constructor
    public C() {
        super();
        System.out.println("in B");
    }

    public C(int n) {
        this(); // this will execute the default constructor `public C() {`.
        System.out.println("in B int n");
    }
}

public class _05_ThisAndSuper {
    public static void main(String[] args) {
        /* ------------------------------------------------------ */
        // without using super()
        B obj = new B(); // → "in A" \n "in B"

        B obj2 = new B(2); // → "in A" \n "in B int n"
        // Why is it calling the constructor of the parent class ?
        //The thing is, every constructor in JAVA has a super(); method even if you don't see it.
        // By default, in every constructor the first statement is super();

        // super(); means that : call the constructor of the super class (here, class A), but which one? The default one (and not the parameterized one).

        //However, if we want to call the parameterized constructor we'll  use super(n); i.e parameterized super. (see below)

        /* ------------------------------------------------------ */
        // with super(n);
        B obj4 = new B(2);
        /* Prints :

        in A int n
        in B int n

        */

        /* ------------------------------------------------------ */

        // but what is the super class of class A ?
        // by default class A is extended to Object i.e.
        // class A extends Object {..}

        /* ------------------------------------------------------ */
        // what if we want to execute both the constructors in a class ?
        // we'll use "this" keyword for that.
        C obj5 = new C(32);
        /* Prints : 

        in A
        in B
        in B int n
        
        */
    }
}

Anonymous Object :

package com.hitarth.packages;

class A {
    int age;
}

public class _06_AnonymousObject {
    public static void main(String[] args) {
        new A(); // no reference variable is present to store the address of the object so it just lays there in the heap
    }
}

Inheritance :

  • "khud ka paisa khud ka paisa, papa ka paisa bhi khud ka paisa ☠️☠️"
package com.hitarth.packages;
/* ------------------------------------------------------ */

//superclass
class Calc {
    public int add(int n1, int n2) {
        return n1 + n2;
    }

    public int sub(int n1, int n2) {
        return n1 - n2;
    }
}

//subclass
class AdvCalc extends Calc
{
    public int mult(int n1, int n2)
    {
        return n1*n2;
    }
}

/* ------------------------------------------------------ */

public class _07_Inheritance {
    public static void main(String[] args) {
        Calc obj = new Calc();
        int r1 = obj.add(1,2);
        System.out.println(r1); // → 3

        AdvCalc obj2 = new AdvCalc();
        int r2 = obj2.mult(2,3);
        int r3 = obj2.add(1,3);
        System.out.println(r2); // → 6
        System.out.println(r3); // → 4
    }
}

Single and Multilevel Inheritance :

Pasted image 20240106012553.png

Multiple Inheritance

Pasted image 20240106012757.png

  • this syntax will not work
    Basically there is NO such thing as Multiple Inheritance.
    This is why :
    Pasted image 20240106013554.png

Method Overriding :

package com.hitarth.packages;

class A
{
    public void show()
    {
        System.out.println("in A show");
    }
    public void config()
    {
        System.out.println("in A config");
    }
}

class B extends A
{
    // method overriding
    public void show()
    {
        System.out.println("in B show");
    }
}

public class _08_Overriding {

    public static void main(String[] args) {
        B obj = new B();
        obj.show(); // → in B show
        obj.config(); // → in A config
    }
}

Packages

import

Pasted image 20240106015238.png

Access Modifiers :

Pasted image 20240106021639.png
Pasted image 20240106021705.png

Pasted image 20240106021130.png

Default : Which can be accessed in the same package.

Pasted image 20240106022114.png

Polymorphism :

Two Types :

  • Compile Time
  • Run Time
    Pasted image 20240106022826.png
    Pasted image 20240106023026.png

Dynamic Method Dispatch in Java

class A{
public void show(){
    Systeem.out.println("in show A");
}
}
class B extends A{
public void show(){
    Systeem.out.println("in show B");
}
}

class C extends A{
public void show(){
    Systeem.out.println("in show C");
}
}

class D
{

}

public class Demo{
    public static void main(String []args){
        A obj =new A();  
        obj.show();  //Output: in show A

        obj =new B(); //reference is A (we can use reference of parents) and create object of B  and assign to parents reference variable.
        obj.show();  //Output: in show B

        obj =new C();  //reference is A (we can use reference of parents) and create object of C and assign to parents reference variable.
        obj.show();  //Output: in show C

		obj = new D(); // this will not work as D is not extending to A
 
    }
}

Note: during compile time we do not know which show() method is called from which class.
    -- we can know during run time which show method is called this is known as run time polymorphism.
    -- all this concept is class dynamic method dispatch

Final Keyword :

  • final int num = 9; : final word is equivalent of const keyword used in c++, it prevents us from changing the data and makes it constant.
package com.hitarth.packages;



final class A{
    public void show(){
        System.out.println("In Calc show");
    }

    public void add(int a,int b){
        System.out.println(a+b);
    }
}

//Suppose someone wants to extend your class. However, we want to stop inheritance then we need to make it as final
// if you make a class final then no one can inherit your class,
// but you can use the final class by making object of final class

class B{
    //declaring the method as final
    public final void show(){
        System.out.print("IN A");
    }
}

class C extends B{
    // you inherit class, but you cannot override show() method if your method is final
    //since show method is final
}

// if you make method as final no one can override your method.

public class _09_FinalKeyword {
}

Object Class equals toString hashcode in Java

Sir's Notes :

// every class in java inherit object class
// in this lecture we see some member method of object class

//public native int hashCode();
//public boolean equals( Object);
//public  String toString();

        /*1)hashCode() method:
In Java, the hashCode () method is a method that is defined in the Object class,
which is the parent class of all classes in Java. It returns an integer value that
represents the unique hash code of an object.*/

        /*2)equals(Object) method:
equals(Object obj) is the method of Object class. This method is used to compare
the given objects. It is suggested to override equals(Object obj) method to get our own equality condition on Objects.*/

        /*3)toString() method:
We typically generally do use the toString() method to get the string representation of an object. It is very important
and readers should be aware that whenever we try to print the object reference then internally toString() method is invoked.
If we did not define the toString() method in your class then the Object class toString() method is invoked otherwise our
        implemented or overridden toString() method will be called.*/

        //case 1: class which not override object class toString(), hashCode(), equals() method
class Mobile{
    String model;
    int price;
}

class Main{
    public static void main(String []args){
        Mobile mb1=new Mobile();
        mb1.model="Apple";
        mb1.price=100000;

        Mobile mb2=new Mobile();
        mb2.model="Apple";
        mb2.price=100000;


        System.out.println(mb1); //Internally mb1.toString() is called and print Mobile@4617c264
        System.out.println(mb2); // Internally mb2.toString() is called and print Mobile@36baf30c


        //use of equals() method to compare to object
        boolean result =mb1.equals(mb2); //right now it gives a false result because by default implementation of equals() method compare reference of two objects
        System.out.println(result); //false 

        //use of hashCode()
        System.out.println(mb1.hashCode()); //1175962212
        System.out.println(mb2.hashCode());  //918221580 , provide some unique value 
    }
}

        //case 2: class can override object class hashCode(), toString(), equals()
class Mobile{
    String model;
    int price;

    @Override
    public String toString(){
        return "Model: "+model+" and price: "+price;
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((model == null) ? 0 : model.hashCode());
        result = prime * result + price;
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Mobile other = (Mobile) obj;
        if (model == null) {
            if (other.model != null)
                return false;
        } else if (!model.equals(other.model))
            return false;
        if (price != other.price)
            return false;
        return true;
    }

}

class Main{
    public static void main(String []args){
        Mobile mb1=new Mobile();
        mb1.model="Apple";
        mb1.price=100000;

        Mobile mb2=new Mobile();
        mb2.model="Apple";
        mb2.price=100000;

        //use of toString() method,  overrides method 
        System.out.println(mb1); //Internally mb1.toString() is called and print Model: Apple and price: 100000
        System.out.println(mb2); // Internally mb2.toString() is called and print Model: Apple and price: 100000

        //use of equals() method to compare two object, overrides method
        boolean result =mb1.equals(mb2); //right now it give true result because we override equals() method
        System.out.println(result); //true

        //use of hashCode()
        System.out.println(mb1.hashCode()); //1967873639 due to overrides hashcode method
        System.out.println(mb2.hashCode());  //1967873639  

        System.out.println(mb1==mb2);
    }
}

//Note: it is not mandatory to override every member method of object class but it is advice able
// to override toString() and equals() method to compare and print own object.

Upcasting and Downcasting

package com.hitarth.packages;

class A
{
    public void show1()
    {
        System.out.println("in A Show");
    }
}
class B extends A
{
    public void show2()
    {
        System.out.println("in B show");
    }
}

public class temp {
    public static void main(String[] args) {

        /*UPCASTING*/
        A obj = (A) new B(); // typecasting to parent class // UPCASTING : as we are going up, i.e. class A
        // doing this is not comuplsory as it happens implicitly behind the scenes
        obj.show1();
        obj.show2(); // error

        /*DOWNCASTING*/
        B obj1 = (B) obj; // obj was initially of type A so we had to cast it down to type B
        obj1.show1();
        obj1.show2(); // no error
    }
}

Wrapper Class

package com.hitarth.packages;

public class temp {
    public static void main(String[] args) {
        int num = 7;
        // Integer num1 = new Integer(num or 7); // → deprecated
        //wrapper class
        Integer num1 = 8;
        int num2 = num1; // auto-boxing : It is automatic conversion of primitive type data into non-primitive data type
        int num3 = num1.intValue(); // auto-unboxing : It is automatic conversion of non primitive type data into primitive data type.

        String str = "12";
        int num4 = Integer.parseInt(str);
    }
}

How Method returns instance of Interface in Java?