BogoToBogo
  • Home
  • About
  • Big Data
  • Machine Learning
  • AngularJS
  • Python
  • C++
  • go
  • DevOps
  • Kubernetes
  • Algorithms
  • More...
    • Qt 5
    • Linux
    • FFmpeg
    • Matlab
    • Django 1.8
    • Ruby On Rails
    • HTML5 & CSS

Inner Classes - 2020

Duke 512




Bookmark and Share





bogotobogo.com site search:




Inner Classes

A java class within another class is an inner class.
Inner class is a type of nested classes.

Inner Class:

  1. (Regular) Inner Class
  2. Static Inner Class
  3. Anonymous Inner Class





Regular Inner Classes

Here is the simple example of inner class.

class OuterClass {
	public static void main(String[] args) {	
		System.out.println("Outer");
	}
	class InnerClass {	
		public void inner_print() {
			System.out.println("Inner");
		}
	}
}

The output is just one line:

Outer

and the file in bin directory should look like:

OuterClass.class
OuterClass$InnerClass.class

But how do we get access to the method of inner class?
To the outer class, inner class is just another class. So, to create an instance of the inner class, we can use:

	InnerClass inner = new InnerClass();

Then, we invoke the method of inner class on the reference.

	inner.inner_print();

How about the following code?

class OuterClass {
	public static void main(String[] args) {	
		System.out.println("Outer");
		InnerClass inner = new InnerClass();
		inner.inner_print();
	}
	class InnerClass {	
		public void inner_print() {
			System.out.println("Inner");
		}
	}
}

The preceding code won't work.
To create an instance of an inner class, we must have an instance of the outer class. Actually, when we create an inner class, an object of that inner class has a link to the outer object that made it. Compiler hand an implicit reference to the outer class to the inner class instances. In that way, the inner class has the ability to access members of the outer class.

So, at the moment of instantiating an inner class, we should know about the outer class. In this case, we should make an instance of outer class first. Then, on that reference, we instantiate the inner class.

		OuterClass o = new OuterClass();
		InnerClass inner = o.new InnerClass();

In other words, we're invoking a method on the outer instance. But the method is special in this case, and it happens to be instantiation method for an inner class.

The code that's working should look like this:

class OuterClass {
	public static void main(String[] args) {	
		System.out.println("Outer");
		OuterClass o = new OuterClass();
		InnerClass inner = o.new InnerClass();
		inner.inner_print();
	}
	class InnerClass {	
		public void inner_print() {
			System.out.println("Inner");
		}
	}
}

This time, the output is:

Outer
Inner

Static Inner Classes

The static nested class is a class enclosed within another class. It is marked with the static modifier.

Let's modify the preceding code and make it static:

class OuterClass {
	static class InnerClass {	
		public void inner_print() {
			System.out.println("Inner");
		}
	}
}

Note that we made the InnerClass as static.

That means it's tied to the class, not a particular instance. Static nested classes are more like regular classes that are not nested. That is they don't enjoy a special relationship with an enclosing outer object. But because static nested classes are still treated as a member of the enclosing outer class, they still get access to any private members of the outer class. However, it can only access to static members. Since the static nested class isn't connected to an instance of the outer class, it doesn't have any special way to access the non-static instance variables and method.

The driver class is:

public class StaticNestedClassTest {
	public static void main(String[] args) {	
		System.out.println("Outer");
		OuterClass.InnerClass inner = new OuterClass.InnerClass();
		inner.inner_print();
	}
}

Because a static nested class is static, we don't use an instance of the outer class. We just use the name of the class, the same way we invoke static methods or access static variables.


Anonymous Inner Classes

Anonymous inner classes are inner classes declared without any class name at all. We can define these classes even within an argument to a method.

As an example, we'll make two classes. One for the class that has static main method and the other has a very simple method of printing.

public class MyClass {
	public void myprint() {
		System.out.println("MyClass");
	}
}

public class AnonymousTest {
	public static void main(String[] args) {	
		MyClass myclass = new MyClass() {
			public void myprint() {
				System.out.println("Anonymous");
			}
		};
		myclass.myprint();
	}
}

The output is:

Anonymous

Let's look at what's in the code:

  1. We defined two classes, MyClass and AnonymousTest.
  2. MyClass has one method, myprint().
  3. AnonymousTest class has one instance variable, myclass.
    This myclass refers not to an instance of MyClass, but to an instance of an anonymous subclass of MyClass.
    So, the line
    	MyClass myclass = new MyClass() {
    is declaring a reference variable myclass. Then we declare a new class that has no name. But it's a subclass of MyClass.

The method, myprint(), defined in the anonymous class is overriding the method in MyClass. So, the output is from the myprint() of a new class.

There are two reasons of using anonymous classes.

  1. To override methods of the superclass (as in this example).
  2. To implement methods of an interface (we'll see it later).

Here is a short quiz.
What will happen if we add another method myprint2() and call the method?

		MyClass myclass = new MyClass() {
			public void myprint() {
				System.out.println("Anonymous");
			}
			public void myprint2() {
				System.out.println("Anonymous2");
			}
		};
		myclass.myprint();
		myclass.myprint2();

We'll have following error:

The method myprint2() is undefined for the type MyClass.

Why?

When we use the reference variable, myclass, we're using a superclass reference variable type to refer to a subclass object. So, we can only call methods on an anonymous inner class reference that are defined in the reference variable type.


We have another type of anonymous inner class. In the previous example, the anonymous inner class was created as a subclass of the specified class type. But in this example, an anonymous implementer will be created as the specified interface type.

interface MyInterfaceable {
	public void myprint();
}

public class AnonymousTest {
	public static void main(String[] args) {	
		MyInterfaceable myinterface = new MyInterfaceable() {
			public void myprint() {
				System.out.println("Anonymous");
			}
		};
		myinterface.myprint();
	}
}

What's going on in the line:

	MyInterfaceable myinterface = new MyInterfaceable() {

It creates an instance of an anonymous inner class, an implementer of the MyInterface interface. Notice that we have

	new MyInterfaceable() 
even though MyInterface is an interface and so we can't make an instance of it. But this syntax is saying, "create a new class (with no name) that implements the MyInterface interface, and we have the implementation of the interface methods: myprint().

Compare the following two cases:

  1. Illegal
    	MyInterfaceable myinterface = new MyInterfaceable();	
    	
  2. Legal
    	MyInterfaceable myinterface = new MyInterfaceable() {
    		public void myprint() {}
    	};
    	

This third example is similar to the second example, implementer case. But at this time, we make sort of just-in-time implementer as an argument of a method.

Here is the example:

public class AnonymousTest {
	public static void main(String[] args) {
		CookableHandle handle = new CookableHandle();
		handle.useCookableInterface(new MyCookable() {
			public void mycook() {
				System.out.println(
				"Cooking Anonymous Arg Inner Class");
			} // end of mycook()
		}   // end of inner class
		); // end of argument	
	}
}

public class CookableHandle {
	void useCookableInterface(MyCookable f) {
		f.mycook();
	}
}

interface MyCookable {
	public void mycook();
}

The output is:

Cooking Anonymous Arg Inner Class

Let's look at what's going on the line:

	handle.useCookableInterface(new MyCookable() {

We call useCookableInterface() on a CookableHandle object. However, the method takes an instance which is an interface MyCookable. That's why we have to make both an implementation class and an instance of that class.

So, we start with:

	new MyCookable() {

It defines the new class for the anonymous class that implements the MyCookable interface. MyCookable interface has one method to implement, mycook(). So, we implement the mycook() method.







Ph.D. / Golden Gate Ave, San Francisco / Seoul National Univ / Carnegie Mellon / UC Berkeley / DevOps / Deep Learning / Visualization

YouTubeMy YouTube channel

Sponsor Open Source development activities and free contents for everyone.

Thank you.

- K Hong







Java Tutorials



Java Tutorial Home

Basics - Compiling and Launching

Inner Classes

Constructor

Enums

Static & Finally

Default and Protected

Polymorphism

Exception Handling

Exception Handling II

String Class

Threads

Threads II - State Transition

Threads III - Synchronization

Object Class

File I/O

Serialization

ArrayList

Autoboxing

Java Graphics Interface I - Basics

Java Graphics Interface II - Labels, Text Fields, Layouts

Java Graphics Interface III - paintComponent

TCP Sockets Server/Client

Scala - Functional Java Programming

Apache CXF install

Tomcat 7 Ubuntu 14 Install on Amazon EC2 instance

What is Apache Maven?

Maven life cycle

Eclipse Maven 3 plugin on Ubuntu 14.04

Apache Maven 3 - Setting up and creating a project

Apache Maven 3 - Compile, build, and install a Maven project

Apache Maven 3 - Dependencies

Apache Maven 3 - Web Application

Apache Maven 3 - Plugins (compiler)

Apache Maven 3 - Plugins (Jetty)

Eclipse CDT / JNI (Java Native Interface) / MinGW



Spring Framework

Hello World App with Spring 4 & Maven 3 - Part I




Sponsor Open Source development activities and free contents for everyone.

Thank you.

- K Hong







Spring Boot



Spring Boot : Hello world with Mavan 3

Spring Boot : Hello world with Gradle 2

Spring Boot (Gradle 2) : Hello world with Authentication

Spring Boot : Deploying War file to Tomcat 8's webapps

How to Setup Apache as Reverse Proxy for Tomcat Server using mod proxy

Maven : mvn command cheat sheet

Spring-Boot REST API with CORS App Maven war file deploy to Tomcat

Spring-Boot / Spring Security with AngularJS - Part I (Introduction)

Spring-Boot / Spring Security with AngularJS - Part II (Dynamic resource load from Angular)

Spring-Boot / Spring Security with AngularJS : Part III (Form-based Authentication)





JUnit & Maven Tutorial



JUnit 4 Introduction (Hello World)

JUnit 4 Test with Eclipse Luna (Hello World)

JUnit 4 Test with Maven (Hello World)











Contact

BogoToBogo
contactus@bogotobogo.com

Follow Bogotobogo

About Us

contactus@bogotobogo.com

YouTubeMy YouTube channel
Pacific Ave, San Francisco, CA 94115

Pacific Ave, San Francisco, CA 94115

Copyright © 2024, bogotobogo
Design: Web Master