Overriding :
A obj = new A("asasdfad");
System.out.println(obj); // → com.hitarth.oop.A@5f184fc6 // some random stuff is printed out
// we don't want this hash value to be printed but want the name and number to be printed out.
// for that we use @Override
class A {
final int num = 10;
String name;
A(String name)
{
this.name = name;
}
}
Internally, when we try to print obj
the .toString
method is called upon the object.
If the .toString
method is NOT present in the object (see class A
above, there is no .toString()
method present there) then the default .toString
method is called which looks like this :
Packages are basically containers for classes. It is used to keep the class names compartmentalized.
In simple terms, packages are just folders.
com.kunal
means com/kunal
i.e. kunal
folder lives inside com
folder
import
as both Human and Main classes are in the same folderProperties which are not really related to a specific object but are common to all the object of the class, we declare those as static
.
public class Human {
int age;
String name;
int salary;
boolean married;
long population=0; // population is not dependent on the object, for 2 different humans the population will remain same so we declare it as static.
//constructor
public Human(int age, String name, int salary, boolean married) {
this.age = age;
this.name = name;
this.salary = salary;
this.married = married;
this.population +=1;
}
}
Now if we perform this :
Human kunal = new Human(22, "Kunal Kushwaha", 10000, false);
Human raka = new Human(22, "raka", 10000, false);
System.out.println(kunal.population); // → 1
System.out.println(raka.population); // → 1
we get the output as 1 and 1, to correct this behavior we'll use static
Using static : static long population=0;
public class Human {
int age;
String name;
int salary;
boolean married;
static long population=0; // population is not dependent on the object, for 2 different humans the population will remain same so we declare it as static.
//constructor
public Human(int age, String name, int salary, boolean married) {
this.age = age;
this.name = name;
this.salary = salary;
this.married = married;
this.population +=1;
}
}
2
and 2
as the outputNow since static
is not really related to the object, so why are we using this
keyword in this.population +=1;
as this
refers to the object. Since this population
variable is common to all the human beings, therefore we can use Class_name
instead of this
keyword here.
So the code now becomes :
package com.hitarth.oop;
public class Human {
int age;
String name;
int salary;
boolean married;
static long population=0; // population is not dependent on the object, for 2 different humans the population will remain same so we declare it as static.
public Human(int age, String name, int salary, boolean married) {
this.age = age;
this.name = name;
this.salary = salary;
this.married = married;
Human.population +=1; // removed the "this" keyword
}
}
Human
and this
keyword will give same results, the only difference is that with this
keywords then it'll first look for whether population
exists in the object
or not, since it doesn't so then it'll look for it in the class Human
and then update it. With Human.
keyword it'll directly look in the class for the required static variable.population
variable does not exist in the objects
, it only resides in the class. Human kunal = new Human(22, "Kunal Kushwaha", 10000, false);
Human raka = new Human(22, "raka", 10000, false);
System.out.println(Human.population); // → 2
System.out.println(Human.population); // → 2
NOTE:
when a member is declared as
static
it can be accessed before any of the object of the class is being created and without referencing to that object (nokunal.population
) needed.
So, even if we haven't created any object, we can still access the population
variable using Human.population;
We can create static methods as well, one of the common static methods is psvm : public static void main
.
psvm
is static so that we can use this method/function without actually creating an object of that class firstmain
(not Main
) is the very first thing that is run in the programpublic class Main {
public static void main(String[] args) {
}
}
public class Main {
), you have to create an object of that class, but how can you run the program to create an object if main
i.e. public static void main(String[] args) {
is the very first thing running.main
method without creating any object of the class Main
, this is why we use static
in psvm.package com.hitarth.oop;
public class Main {
public static void main(String[] args) {
greeting();
}
// NOT using static below will give us this error :
// "Non-static method 'greeting()' cannot be referenced from a static context"
// we also know that something which is static belongs to an object
static void greeting() {
System.out.println("Hello World");
}
}
package com.hitarth.oop;
public class Main {
public static void main(String[] args) {
fun(); // no error shown
fun2(); // gives an error : Non-static method 'fun2()' cannot be referenced from a static context
Main funn = new Main();
funn.fun2(); // no error shown
}
// this is not dependent on objects
static void fun(){
greeting(); // this will give an ERROR
// you can't use this because it requires an instance
// but the function you are using it in does not depend on instances
//in simple terms fun() does not depend on instances so how can you have something that depends on instances inside of fun() ? You can't.
// you can't access non static stuff without referencing their instances in a static context
// hence, here we are referencing it :
Main obj = new Main();
obj.greeting(); // no this won't give any errors.
}
void fun2() {
greeting(); // here we won't get any errors cuz we know that directly or indirectly fun2() will get called from `main` so we know that object for `fun2()` will be created. i.e why we won't have to manually create an object for it.
}
// we know that something which is not static belongs to an object
void greeting() {
System.out.println("hello");
}
}
package com.hitarth.oop;
// this is a demo to show initialisation of static variables
public class StaticBlock {
static int a =4;
static int b;
// static block: will get executed exactly once when the class is loaded
static {
System.out.println("I'm in a static block");
b = a*5;
}
public static void main(String[] args) {
StaticBlock obj = new StaticBlock();
System.out.println(StaticBlock.a + " " + StaticBlock.b);
}
}
I'm in a static block
4 20
package com.hitarth.oop;
// this is a demo to show initialisation of static variables
public class StaticBlock {
static int a =4;
static int b;
// static block: will get executed exactly once when the class is loaded
static {
System.out.println("I'm in a static block"); // → I'm in a static block
b = a*5;
}
public static void main(String[] args) {
StaticBlock obj = new StaticBlock();
System.out.println(StaticBlock.a + " " + StaticBlock.b); // → 4 20
StaticBlock.b +=3;
StaticBlock obj2 = new StaticBlock();
System.out.println(b); // → 23 // so when we created a new object it did not run the static block again, hence the static things are only run once when the first object is created. Even if we had not created objects "obj" and "obj2" we'd still be able to perform the same calculations.
}
}
Class inside a class.
NOTE : Outside classes (The classes which are not inside any classes, for e.g. InnerClasses
class in the code block below) can't be static.
package com.hitarth.oop;
/* ------------------------------------------------------ */
// since this class is an outside class it needs not be a static class.
class TestOutside {
static String text;
public TestOutside(String text) {
this.text = text;
}
}
/* ------------------------------------------------------ */
public class InnerClasses {
// this "Test" class is inside a class so, it can be static.
// with static, this class is not dependent on the class outside, it does require an object of the container class to be created
static class Test {
String name;
public Test(String name) {
this.name = name;
}
}
public static void main(String[] args) {
//Test
Test a = new Test("some name");
Test b = new Test("changed name");
System.out.println(a.name); // → some name
System.out.println(b.name); // → changed name
//TestOutside
TestOutside random = new TestOutside("alkasdd");
TestOutside random_2 = new TestOutside("jhgfa");
System.out.println(random.text); // → jhgfa
System.out.println(random_2.text); // → jhgfa
// hence the same static variable was changed
}
}
Above code in text format : (Both files are in the same folder)
Main.java :
package com.hitarth.oop;
public class Main {
public static void main(String[] args) {
Singleton obj = Singleton.getInstance();
Singleton obj2 = Singleton.getInstance();
Singleton obj3 = Singleton.getInstance();
// so, every time someone asks for a new instance we are giving it the same instance again and again, hence no more than 1 instance is being created.
// therefore all 3 ref variables are pointing to just one object
// since the constructor is private therefore we can't call a constructor here either, hence we can't create more than 1 objects
}
}
Singleton.java :
package com.hitarth.oop;
public class Singleton {
// constructor
private Singleton() {
// private class is basically a class only accessible to this file
// whatever thing is private will only run in this class
}
// since this instance is not going to be dependent on the class "SingletonClass", we aren't going to create an object of that outside class right, it is not allowed, so we are only going to be returning the "instance" object created below, so we can put it as static.
private static Singleton instance;
public static Singleton getInstance() {
// first, check whether 1 obj only is created or not
// instance == null will be true if no object had been created, i.e. reference variable will be null and will not be assigned to any pointer.
if (instance == null) {
// if no object had been created, we'll make one
instance = new Singleton(); // constructor can be called here since it is in the same file
}
return instance;
}
}