Nested classes

Java Multithreading
Level 3 , Lesson 3
Available

"Hi, Amigo!"

"Hi, Ellie!"

"Today we have a very interesting topic. Today I'm going to tell you about nested classes."

"If a class is declared inside another class, then it is a nested class. Non-static nested classes are called inner classes."

"Objects of an inner class are nested inside objects of the outer class and can therefore access the outer class's variables."

Example
public class Car
{
 int height = 160;
 ArrayList doors = new ArrayList();

 public Car
 {
  doors.add(new Door());
  doors.add(new Door());
  doors.add(new Door());
  doors.add(new Door());
 }

class Door()
 {
  public int getDoorHeight()
  {
   return (int)(height * 0.80);
  }
 }
}

"Note that the Door class has a getDoorHeight method. It uses the Car object's height variable and returns the height of the door."

Nested classes - 1

"A Door object cannot exist independently of a Car object. After all, it uses the Car object's variables. The compiler invisibly adds to the constructor and to the Door class a reference to the outer Car object, so that methods of the inner Door class can access the outer Car class's variables and call its methods."

"Nested objects. Makes sense to me. Judging by the diagram, it's all pretty straightforward."

"And so it is. Except for a couple of nuances."

"The inner Door class has a reference to the Car object, therefore:"

1) You can't create a Door object inside a static method of the Car class, because static methods don't contain a reference to the Car object that is implicitly passed to the Door constructor.

Correct Incorrect
public class Car
{
 public static Door createDoor()
 {
 Car car = new Car();
  return car.new Door();
 }

 public class Door
 {
  int width, height;
 }
}
public class Car
{
 public static Door createDoor()
 {
  return new Door();
 }

 public class Door
 {
  int width, height;
 }
}

2) The Door class cannot contain static variables or methods.

Correct Incorrect
public class Car
{
 public int count;
 public int getCount()
 {
  return count;
 }

 public class Door
 {
  int width, height;
 }
}
public class Car
{

 public class Door
 {
  public static int count;
  int width, height;

  public static int getCount()
  {
   return count;
  }
 }
}

"And what if I need a variable that is shared by all Door objects?"

"You can always simply declare it in the Car class. Then it will be shared by all Door objects nested in a Car object."

3) Note: if the inner class is declared as public, instances of it can be created outside of the outer class, but an instance of the outer class must exist first:

Car car = new Car();
Car.Door door = car.new Door();
Car.Door door = new Car().newDoor();

4) And one more comment that I almost forgot.

"Since we have two nested objects, the inner object's methods have access to two references called 'this':"

public class Car
{
 int width, height;

 public class Door
 {
  int width, height;

  public void setHeight(int height)
  {
   this.height = height;
  }

 public int getHeight()
 {
  if (height != 0)
   return this.height;
  else
   return (int)(Car.this.height * 0.8);
 }
}

"I deliberately declared variables with the same name in the classes."

"To access a variable from the outer class when it is hidden, or to access 'this' inside an inner class, simply write 'YourClassName.this':"

How to access the 'this' of an outer (or any other) class
Car.this
Car.Door.this
Car.Door.InnerClass2.InnerClass3.this

"So, if we write 'this' inside an inner class's method, then 'this' refers to the inner class?"

"Yes. Exactly."

"What do you think of inner classes, Amigo?"

"They are very interesting. I wouldn't say they're too difficult."

"There are a lot of restrictions, but they seem quite logical after you explained where those restrictions come from and why they exist."

"Plus, I've been writing nested classes in tasks for two months, but only now do I realize what I've really been writing."

"Thanks for the great lesson, Ellie."

"I'm glad you liked it, Amigo."

Comments (10)
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION
Hoist Level 36, San Diego, United States
5 January 2024
OK. Except for a couple of nuances ...
Ibrahim Level 41, Sheffield, United Kingdom
30 January 2022
Read all of these codegym articles before continuing, they are from the end of this lesson: https://codegym.cc/groups/posts/262-nested-inner-classes https://codegym.cc/groups/posts/207-static-nested-classes https://codegym.cc/groups/posts/263-inner-classes-in-a-local-method https://codegym.cc/groups/posts/261-anonymous-classes https://codegym.cc/groups/posts/206-lets-talk-about-final
Vesa Level 41, Kaliningrad, Russia
23 January 2021
>Car.Door door = new Car().newDoor(); should be so:

Car.Door door = new Car().new Door();
Johannes Level 27, Centurion, Pretoria, South-Africa
2 May 2020
If you want to refer to the "width" variable in Car class, why can't you simply say: "Car.width" , instead of "Car.this.width" ? Because that already distinguishes it from "Door.width" ? Or am I missing something else ? regards
Vesa Level 41, Kaliningrad, Russia
7 May 2020
>why can't you simply say: "Car.width" , instead of "Car.this.width" We need a reference to an outer object. We can get it through this keyword. The this keyword points to an object, not a class. I think so.
Johannes Level 27, Centurion, Pretoria, South-Africa
8 May 2020
hi, thanks for your explanation. I see there's a missing bracket "}", which would make it inner classes, I missed that.
Vahan Level 41, Tbilisi, Georgia
17 January 2020
In forth comment why variables are named objects? Or I miss smth?
Juanf Level 26
1 November 2019
Sometimes the syntax and style of the examples is not the best, even happens it's wrong: declaring a class like this?: class Door(){} !!??
Seb Level 41, Crefeld, Germany
18 January 2020
Good catch. :-)
Ewerton Level 30, Belo Horizonte, Brasil
11 July 2019
"There are a lot of restrictions, but they seem quite logical after you explained where those restrictions come from and why they exist." I think this should be in blue.