blog posts

Nested And Inner Classes In Java

In this tutorial, you will learn how to work with Inner and Nested classes in Java.

In Java, you can define one class in another. This class is known as the Nested class.

class OuterClass {

//…

class NestedClass {

//…

}

}

You can create two types of Nested or nested classes in Java.

  • Non-static nested class (Inner class)
  • Static nested class

Let’s look at non-static nested classes first.

Non-static nested class

A non-static nested class is a class in another class that has access to members of the enclosed class (outer class). Commonly known as the inner class.

There is an internal class inside the outer class (to define an inner class, you must first define an outer class).

For example, you can define internal classes in Java.

Example 1: Internal class

  1. class CPU {
  2. double price;
  3. class Processor {
  4. double cores;
  5. String manufacturer;
  6. double getCache () {
  7. return 4.3;
  8. }
  9. }
  10. protected class RAM {
  11. double memory;
  12. String manufacturer;
  13. double getClockSpeed ​​() {
  14. return 5.5;
  15. }
  16. }
  17. }
  18. public class Main {
  19. public static void main (String [] args) {
  20. CPU cpu = new CPU ();
  21. CPU.Processor processor = cpu.new Processor ();
  22. CPU.RAM ram = cpu.new RAM ();
  23. System.out.println (“Processor Cache =” + processor.getCache ());
  24. System.out.println (“Ram Clock speed =” + ram.getClockSpeed ​​());
  25. }
  26. }

Output

Processor Cache = 4.3

Ram Clock speed = 5.5

In the above program, the CPU class has two internal classes, Processor and RAM. Since the RAM class is an internal class, you can set it to protected.

In the Main class, the CPU instance is created first. And in order to create the Processor, Operator instance (Dot) is used.

Access to external class members in the internal class

As we discussed, internal classes can access members of the outer class, which is possible using the keyword this.

Example 2: Access to members

  1. public class Car {
  2. String carName;
  3. String carType;
  4. public Car (String name, String type) {
  5. this.carName = name;
  6. this.carType = type;
  7. }
  8. private String getCarName () {
  9. return this.carName;
  10. }
  11. class Engine {
  12. String engineType;
  13. void setEngine () {
  14. // Accessing carType property of Car
  15. if (Car.this.carType.equals (“4WD”)) {
  16. // Invoking method getCarName () of Car
  17. if (Car.this.getCarName (). equals (“Crysler”)) {
  18. this.engineType = “Bigger”;
  19. } else {
  20. this.engineType = “Smaller”;
  21. }
  22. } else {
  23. this.engineType = “Bigger”;
  24. }
  25. }
  26. String getEngineType () {
  27. return this.engineType;
  28. }
  29. }
  30. }
  31. public class CarMain {
  32. public static void main (String [] args) {
  33. Car car1 = new Car (“Mazda”, “8WD”);
  34. Car.Engine engine = car1.new Engine ();
  35. engine.setEngine ();
  36. System.out.println (“Engine Type for 8WD =” + engine.getEngineType ());
  37. Car car2 = new Car (“Crysler”, “4WD”);
  38. Car.Engine c2engine = car2.new Engine ();
  39. c2engine.setEngine ();
  40. System.out.println (“Engine Type for 4WD =” + c2engine.getEngineType ());
  41. }
  42. }

Output

Engine Type for 8WD = Bigger

Engine Type for 4WD = Smaller

In the above program, in the internal class of Engine, we used the keyword this to access the carType variable of external class Car:

Car.this.carType.equals (“4WD)

This is possible even if carType is a private member of the Car class.

You can also see that we have used Car.this to access Car members. If you use this instead of Car.this, you only have access to members of the Engine class.

Similarly, we used the this keyword to access getCarName () of the Car class:

Car.this.getCarName (). Equals (“Crysler”)

Here, the getCarName () method is a private method of class Car.

Static internal class

In Java, you can define a nested class that is static. Such a class is known as a static nested class.

Unlike the inner class, the static nested class cannot access the variables that are members of the outer class because the static nested class does not need to create an instance of the outer class. Hence, there is no external class reference with OuterClass.this.

So, you can create an instance of a static nested class like this:

OuterClass.InnerClass obj = new OuterClass.InnerClass ();

Example 3: Static internal class

  1. Public class MotherBoard {
  2. String model;
  3. public MotherBoard (String model) {
  4. this.model = model;
  5. }
  6. static class USB {
  7. int usb2 = 2;
  8. int usb3 = 1;
  9. int getTotalPorts () {
  10. return usb2 + usb3;
  11. }
  12. }
  13. }
  14. public class Main {
  15. public static void main (String [] args) {
  16. MotherBoard.USB usb = new MotherBoard.USB ();
  17. System.out.println (“Total Ports =” + usb.getTotalPorts ());
  18. }
  19. }

Output

Total Ports = 3

In the above program, we defined the internal static USB class using the static keyword.

You can also see, in the Main class, a direct instance of USB from the MotherBoard with the operator We defined (dot) without creating a sample of the Motherboard.

MotherBoard.USB usb = new MotherBoard.USB ();

Let’s see what happens if we try to reach out to outside class members:

Example 4: Access to external class members in static internal class

  1. String model;
  2. public MotherBoard (String model) {
  3. this.model = model;
  4. }
  5. static class USB {
  6. int usb2 = 2;
  7. int usb3 = 1;
  8. int getTotalPorts () {
  9. if (MotherBoard.this.model.equals (“MSI”)) {
  10. return 4;
  11. }
  12. else {
  13. return usb2 + usb3;
  14. }
  15. }
  16. }
  17. }
  18. public class Main {
  19. public static void main (String [] args) {
  20. MotherBoard.USB usb = new MotherBoard.USB ();
  21. System.out.println (“Total Ports =” + usb.getTotalPorts ());
  22. }
  23. }

Output

error: non-static variable this cannot be referenced from a static context

Key points to remember

  • Java treats the internal class as a regular member of the class. They are just like the methods and variables defined within a class.
  • Because the internal class is a member of the external class, you can apply any access level regulator such as praivate and protected to the internal class, which is not possible in normal classes.
  • Since the nested class is a member of the external enclosed class, you can use the operator (Dot) Use to access the nested class and its parameters.
  • Using a nested class makes the code more readable and provides better encapsulation.
  • Non-static nested classes (internal classes) have access to other members of the external / enclosed class even if they are private.