07 Java - Classes (Part I)

Chetan DattaChetan Datta
6 min read

1. Concrete Class

  • These are classes that can be instantiated using the new keyword.

  • All the methods in the is class have implementation

  • It can also be a subclass that implements an interface or extends an abstract class.

  • A class access modifier can be either "public" or "package private" (no explicit modifier defined/ No keyword present)

public class Person {

    int empId;

    public Person(int empId) {
        this.empId = empId;
    }

    public int getEmpId() {
        return empId;
    }
}
public interface Shape {
    public void computeArea();
}

public class Rectangle implements Shape{

    @Override
    public void computeArea() {
        System.out.println("Area of rectangle");
    }
}

2. Abstract Class (0 to 100% Abstraction)

Show only important features to users and hide its internal implementation.

2 ways to achieve abstraction:

  • Class is declared as abstracted through keyword "abstract".

  • It can have both abstract (method without body) and non abstract methods.

  • We can not create an instance of this class.

  • We parent has some features which all child classes have in common, then this can be used.

  • Constructors can be created inside them. And with super keyword from child classes we can access them.

  • If all the methods are abstract then it is 100% abstraction. Interface is by default it is 100% abstraction.

Example:

Abstract class Car

public abstract class Car {

    int mileage;

    public Car(int mileage) {
        this.mileage = mileage;
    }

    public abstract void pressBreak();

    public abstract void pressClutch();

    public int getNumberOfWheels(){
        return 4;
    }
}

Abstract class LuxuryCar inherited Car

public abstract class LuxuryCar extends Car{

    public LuxuryCar(int mileage) {
        super(mileage);
    }

    @Override
    public void pressBreak() {
        //Implementation of break in luxury car
    }

    public abstract void pressDualBreakSystem();

}

Concrete class Audi

public class Audi extends LuxuryCar{
    public Audi(int mileage) {
        super(mileage);
    }

    @Override
    public void pressClutch() {
        //implementation of clutch
    }

    @Override
    public void pressDualBreakSystem() {
        //implementation of dual break system
    }
}

3. Super and Sub Class

  • A class that is derived from another class is called a Subclass

  • And from class through which Subclass is dervied its called superclass.

  • In Java, in the absence of any other explicit superclass, every class is implicitly a subclasss of Object class.

  • Object is the topmost class in java

Object: It has some common methods like clone(), toString(), equals(), notify(), wait() etc...

package learn;

public class ObjectTest {

    public static void main(String[] args) {
        ObjectTest test = new ObjectTest();

        Object person = new Person();
        Object audi = new Audi(1);

        System.out.println(person.getClass());
        System.out.println(audi.getClass());
    }
}

/* Output:
class learn.Person
class learn.Audi
*/

4. Nested Class

A nested class is a class defined within another class.

When to Use Nested Classes

  • Single Usage: If a class (Class A) is only going to be used by one other class (Class B), you can define Class A as a nested class within Class B. This avoids the need for a separate file for Class A.

  • Logical Grouping: Nested classes help in logically grouping related classes together in one file, making the code more organized and easier to manage.

Scope

The scope of a nested class is the same as its outer class. If the outer class is public, the nested class will also be public.

Types of Nested Classes

  • Static Nested Class

  • Non Static Nested Class (Inner Class)

    • Member Inner Class

    • Local Inner Class

    • Annonymous Inner Class

Static Nested Class

  • It do not have access to the non static instance variable and method of outer class.

  • Its object can be initiated without initiating the object of outer class.

  • It can be private, public, protected or package-private (default, no explicit declaration)

Note: Outer class is same as class so it can be public or package-private

Example 1:

package learn;

public class OuterClass {
    int instanceVariable = 10;
    static int classVariable = 20;

    static class NestedClass{
        public void print(){
            System.out.println(classVariable);
        }
    }
}

/* Usage

        OuterClass.NestedClass nest = new OuterClass.NestedClass();
        nest.print();
*/

Example 2:

package learn;

public class OuterClass {
    int instanceVariable = 10;
    static int classVariable = 20;

    private static class NestedClass{
        public void print(){
            System.out.println(classVariable);
        }
    }

    public void display(){
        NestedClass nest = new NestedClass();
        nest.print();
    }
}

/*
        OuterClass outerClass = new OuterClass();
        outerClass.display();
*/

Non Static Nested Class:

  • It has access to all the instance variables and methods of outer class.

  • An instance of the outer class must be created before initializing an object of the inner class.

1. Member Inner Class:

  • It can be private, public, protected, default

  • If an inner class is private, its object can only be instantiated within the outer class.

package learn;

public class OuterClass {
    int instanceVariable = 10;
    static int classVariable = 20;

    class InnerClass{
        public void print(){
            System.out.println(classVariable+instanceVariable);
        }
    }
}

/* Usage -
        OuterClass outerClass = new OuterClass();
        OuterClass.InnerClass inner = outerClass.new InnerClass();
*/

2. Local Inner Class

  • These are those classes which are defined in any block like for loop, while loop block, if condition block, method etc

  • It can not be declared as private, protected, public. Only default (not defined explicit) access modifier is used.

  • It can not be initiated outside of this block.

package learn;

public class OuterClass {
    int instanceVariable = 10;
    static int classVariable = 20;

    public void display(){
        int methodLocalVariable = 3;

        class LocalInnerClass{
            int localInnerVariable = 4;
            public void print(){
                System.out.println(instanceVariable+classVariable+methodLocalVariable+localInnerVariable);
            }
        }

        LocalInnerClass localObj= new LocalInnerClass();
        localObj.print();
    }
}

/* Usage -
        OuterClass outerClass = new OuterClass();
        outerClass.display();
*/

Inheritance in Nested classes

Example 1: One inner class inherit another inner class in same outer class

package learn;

public class OuterClass {
    int instanceVariable = 10;
    static int classVariable = 20;

    class InnerClass1{
        int innerClass1Variable = 3;
    }

    class InnerClass2 extends InnerClass1{
        int innerClass2Variable = 4;

        void display(){
            System.out.println(innerClass1Variable+innerClass2Variable+instanceVariable+classVariable);
        }
    }
}

/* Usage
        OuterClass outerClass = new OuterClass();
        OuterClass.InnerClass2 innerClass2Obj = outerClass.new InnerClass2();
        innerClass2Obj.display();
*/

Example 2: Static Inner Class inherited by different class

package learn;

public class OuterClass {
    static class NestedClass{
        public void display(){
            System.out.println("Inside Innerclass");
        }
    }
}

Inheritacne usage


public class SomeOtherClass extends OuterClass.NestedClass{
    public void display1(){
        display();
    }
}

Example 3: Non Static Inner Class inherited by different class

package learn;

public class OuterClass {

    class InnerClass{
        public void display(){
            System.out.println("Inside Innerclass");
        }
    }
}

Inheritance usage

package learn;

public class SomeOtherClass extends OuterClass.InnerClass{

    SomeOtherClass(){
        new OuterClass().super();
        //Imp step
        // as you know, when child class constructor invoked, it first invoked the constructor of parent.
        // but here the parent is Inner class, so it can only be accessed by the object of outerclass only
    }

    public void display1(){
        display();
    }
}

3. Anonymous Class

An inner class without a name called Anonymous class

Why its used

  • When we want to override the behaviour of the method without even creating any subclass.
package learn.anonymous;

public abstract class Car {
    public abstract void pressBreak();
}

Anonymous Usage -

package learn.anonymous;

public class Test {
    public static void main(String[] args) {
        Car audiCarObj = new Car() {
            @Override
            public void pressBreak() {
                //my audi specific implementation here
                System.out.println("Audi specific break changes");
            }
        };

        audiCarObj.pressBreak();
    }
}

Internal Working - 2 things happened behind the scene:

  • Sub class is created, name decided by the compiler

  • Creates an object of subclass and assign its reference to object "audiCarObj"

Similarly for interface also, it works in the same way...

command to get the byte code

javac Test.java Car.java

/* 3 Class files
Test.class
Test$1.class
Car.class
*/
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package learn.anonymous;

class Test$1 extends Car {
    Test$1() {
    }

    public void pressBreak() {
        System.out.println("Audi specific break changes");
    }
}
0
Subscribe to my newsletter

Read articles from Chetan Datta directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Chetan Datta
Chetan Datta

I'm someone deeply engrossed in the world of software developement, and I find joy in sharing my thoughts and insights on various topics. You can explore my exclusive content here, where I meticulously document all things tech-related that spark my curiosity. Stay connected for my latest discoveries and observations.