CodeGym /Courses /Java Multithreading /Anonymous inner classes, and examples

Anonymous inner classes, and examples

Java Multithreading
Level 3 , Lesson 7
Available
Anonymous inner classes, and examples - 1

"Hi, Amigo!"

"But we've already said hello, Ellie!"

"Hey, don't argue with your aunt. In the 31st century, if you haven't seen someone for more than half an hour, it's customary to say hello again. So don't give me your attitude!"

"Anyway, it's time for another interesting topic: robot reproduction!"

"O_O."

"Just kidding, the new topic is anonymous inner classes."

"In Java, sometimes there are situations where you'll need a class to inherit several classes. Since Java doesn't support multiple inheritance, they've solved this problem using inner classes: in our class, we declare an inner class and make it inherit whatever class we need it to inherit. Here's an example:"

Example of an inner class that inherits the Thread class
class Tiger extends Cat
{
 public void tigerRun()
 {
  .....
 }

 public void startTiger()
 {
  TigerThread thread = new TigerThread();
  thread.start();
 }

 class TigerThread extends Thread
 {
  public void run()
  {
   tigerRun();
  }
 }
}

"Let's dig into another example:"

We need a subclass of the Thread class in order to override its run method."

"That's why in the Tiger class we declared the TigerThread inner class, which inherits Thread and overrides the run method.

"For convenience, we defined two methods in the Tiger class: tigerRun and startTiger (which are analogous to Thread's run and start methods."

"In the tigerStart method, we create a TigerThread object and invoke its start() method."

"The JVM will create a new thread that will start running when TigerThread's run method is called."

"This method then calls our run method: tigerRun."

"I've worked with threads before, so this seems straightforward."

"Do we have to name the methods tigerRun and tigerStart?"

"No, we could have called them run and start, but I also wanted to demonstrate that we are not inheriting Thread. An explanation might have been more confusing."

"OK. Then I think I get it. But if tigerStart is called a second time, we'll create and start a second Thread object. Doesn't that mean that we'll have «one tiger running on two different threads»?"

"Well, aren't you sharp! You're right, and that's not good. Let's rewrite the code like this:"

Code
class Tiger extends Cat
{
 public void tigerRun()
 {
  .....
 }

 public void startTiger()
 {
  thread.start();
 }

 private TigerThread thread = new TigerThread();

 private class TigerThread extends Thread
 {
  public void run()
  {
   tigerRun();
  }
 }
}

"It's not quite perfect. You still can't call a method like that twice. But this time, at least we won't create a second thread and make it seem like everything is fine."

"That's right. The second time a Tiger is started, you'll get an exception."

"I'm already spotting mistakes better than you, Ellie!"

"Yeah, you're doing great. Then let's move on to anonymous inner classes."

"Note several aspects of the code above:"

1) We inherited the Thread class, but implemented practically no code there. "It was more «we had to inherit the Thread class» rather than «we inherited it to extend it».

2) Only one TigerThread object will be created.

In other words, we wrote a whole bunch of code just to override one method and create one object.

Do you remember how I talked about the invention of constructors?

Before constructors After constructors
TigerThread thread = new TigerThread();

private class TigerThread extends Thread
{
 public void run()
 {
  tigerRun();
 }
}
Thread thread = new Thread()
{
 public void run()
 {
  tigerRun();
 }
};

"I see the code became more compact, but I don't quite understand what's happening."

"We can combine four things into one:"

1) declaration of a derived class

2) method overriding

3) declaration of a variable

4) creation of an instance of a derived class.

"In fact, what we're doing is combining two operations: declaring a derived class and creating an instance of that class."

Without anonymous class With anonymous class
Cat tiger = new Tiger();

class Tiger extends Cat
{
}
Cat tiger = new Cat()
{
};

"Let's explore the syntax again:"

Declaration of a Thread variable
Thread thread = new Thread();
Declaration of a variable whose type is «an anonymous class that inherits Thread»
Thread thread = new Thread()
{

};

"Note that we aren't simply defining a new class. We're creating a variable—there's a semicolon at the end!"

"And if we want to override the run method, then we need to write this:"

Declaration of a Thread variable
Thread thread = new Thread()
{
 public void run()
  {
   System.out.println("new run-method");
  }
};

"You catch on quickly. Well done!"

"Thanks. What if we need other methods that aren't part of the Thread class?"

"You can write them."

"Though anonymous, this is a full-fledged inner class:"

Java code Description
Thread thread = new Thread()
{ public void run() { printHi(); } public void printHi() { System.out.println("Hi!"); } }; 
Red: code for creating the variable.

Green: code for creating the object.

Blue: code for the anonymous derived class.

"A full-fledged inner class?"

"So I can use the variables of the outer class?"

"Absolutely."

"And I can pass something to the constructor?"

"Yes, but only the arguments for the superclass's constructor:"

Class Instance of an anonymous inner class
class Cat
{
 int x, y;
 Cat(int x, int y)
 {
  this.x = x;
  thix.y = y;
 }
}
Cat cat = new Cat(3,4)
{
  public void print()
  {
   System.out.println(x+" "+y);
  }
};

"We can't add our own parameters to someone else's constructor. But we can use the variables of the outer class, which compensates nicely for this shortcoming."

"What if I still really need to add other parameters to the constructor?"

"Then declare an ordinary (non-anonymous) inner class and use that."

"Right, I almost forgot about that."

"What if I declare a static variable? Would that make the anonymous class become a static nested class rather than an inner class? In other words, will it lack a reference to the outer class?"

"No. It would be an anonymous inner class. Look at these examples."

With anonymous class Without anonymous class
Thread thread = new Thread()
{
  public void run()
  {
   tigerRun();
  }
};
TigerThread thread = new TigerThread();

private class TigerThread extends Thread
{
 public void run()
 {
  tigerRun();
 }
}
static Thread thread = new Thread()
{
  public void run()
  {
   tigerRun();
  }
};
static TigerThread thread = new TigerThread();

private class TigerThread extends Thread
{
 public void run()
 {
  tigerRun();
 }
}

"I see. Only the static variable would be static, not the class."

"Yep."

"In fact, the compiler creates inner classes for all anonymous inner classes. These classes are usually named «1», «2», «3», etc."

Comments (16)
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION
Abhishek Tripathi Level 72, Rewa, India Expert
30 November 2023
Here's my explanation for the first task: as inner class extends the Outer class hence the private method is not available for it. So insite the inner class's printName() method we are actually calling the getName on a object of Outer class like this - Solution.this.getName(); so after making the getName() method public the method is called inside the printName() method something like this - this.getName(); // called on the inner class's object not the outer class's object.
manny9876 Level 36, Israel
15 November 2023
For some reason the only line my mind managed to process: "Anyway, it's time for another interesting topic: robot reproduction!" LOL!
Mateusz Level 30, Poland
5 April 2023
We can't use multiple inheritance but we can implement many interfaces. Wouldn't that be easier to implement Runnable interface?
Ibrahim Level 41, Sheffield, United Kingdom
30 January 2022
Great explanation here: https://youtu.be/V7yVbG9_xkM
Jurij Thmsn Level 29, Flensburg, Germany
14 October 2021
I didn't really understand, this video helped me: https://youtu.be/n2Dpffp_HLc
2 April 2021
Read multiple times, something isn't clear! Also Cat superclass is confusing her.
2 April 2021
Ok, Cat class is just to show that Tiger class is already subclass of Cat, so it cannot extend Thread class.
Manish Sinha Level 1, london, United Kingdom
13 October 2020
make sense after reading more than thrice. worth reading multiple times i believe.
BlueJavaBanana Level 37
23 July 2020
I found this later lesson beneficial to understand an anonymous class. https://codegym.cc/groups/posts/261-anonymous-classes Basically they are temporary local classes that exist as long and the method your create them in is running. It saves you the effort of writing a whole new class just for a one off use in your code.
MaGaby2280 Level 41, Guatemala City, Guatemala
15 July 2020
I read it three times and still is very confusing... hope to get it clarified soon ;o)
Vesa Level 41, Kaliningrad, Russia
8 May 2020
>In the tigerStart method, we create a TigerThread object >But if tigerStart is called a second time Name is startTiger