Internal and nested java classes. Part 1

Hello dear Habr readers.

Internal and nested java classes. Part 1

03/02/2017 - 2019

Part 1. Start

Purpose of the article: To tell about internal, nested, local, anonymous classes. Show examples of their use. Write and test classes in java code. Tell about the properties of these classes.

A little introduction. I suggest you heed a cycle of three articles.
In them, I talk about internal, nested, local, anonymous classes. It's about terminology and application. For these articles, I wrote quite a lot of code.
This is a training code, not a guide to action. That is, I wrote the code for better understanding. I also tried to explain the work of the training code. It took quite a long time to write the publication. The publication consists of three parts. Please treat with understanding.

To begin with, what is the inner and nested classes. Let's look at the terminology found in the documentation >>> :

In Java, there are 4 types of nested (nested) classes:

  1. Static nested classes
  2. Inner classes
  3. Local Classes
  4. Anonymous (unnamed) classes



Joshua Bloch:

“There are four categories of nested classes:

  • static member class
  • nonstatic member class,
  • anonymous class (anonymous class)
  • and local class.
"


Let's try to figure out what it is.

Let's start a bit remotely, since all this is directly related to our questions. Recall object-oriented programming. Relationship composition and inheritance.

In his book “Java 2 Developer Guide,” Michael Morgan very well and describes in detail the relationships between classes and objects. We will look at some of them. The “this is - that” relationship is expressed by inheritance, and the “has a part” relationship is described by composition.

In our examples, we mainly consider composition. Since nested classes are part of something. That is, we have a wrapper class and a nested class defined within the wrapper class. Composition example: the car has an engine, a door, 4 wheels, a housing. And we can describe the car using internal (Inner) classes.

An example of this use can be found in Bruce Ekkel’s book, The Java Philosophy.

/* Пример №1 *///: c06:Car.java// композиция с использованием открытых объектов// двигатель classEngine{
publicvoidstart(){}
publicvoidrev(){}
publicvoidstop(){}
}
classWheel{
publicvoidinflare(int psi){}// накачать
}
// окноclassWindow{
publicvoidrollup(){}// приоткрытьpublicvoidrolldown(){}// опустить
}
// дверьclassDoor{
public Window window=new Window();
publicvoidopen(){}//открыть publicvoidclose(){}// закрыть
}
// машина publicclassCar{
public Engine engine = new Engine();
public Wheel[] wheel = new Wheel[4];
public Door left = new Door(),
right = new Door();//две двериpublicCar(){
for(int i = 0; i<4; i++)
	wheel[i]= new Wheel();
}
publicstaticvoidmain(String[] args){
Car car= new Car();
car.left.window.rollup();
car.wheel[0].inflare(72);
}
}

There is some author warning about using the code in this form:
Since the composition of the object is part of the analysis of the task (and not
just a part of the class implementation), declaring class members open, helps the client programmer understand how to use the class, and makes it easier for the creator to write code. However, it must be remembered that the described case is special, and basically the fields of the class must be declared as private.


Static Nested Classes

Definition of Nested Classes:

A class is called nested if it is defined inside another class.

That is, a class is simply defined inside another, not even important statically defined or not statically. A nested class is created to serve the class around it. If the nested class is useful in some other context, it should become a top-level class.

Application

Nested classes are used in cases when you need to write a small auxiliary code for another class. A nested class is also created to hide its variables and methods from the outside world. Thus, the nested class is another elegant way to limit the scope. It also makes sense to use inner classes if it is assumed that they will use parent elements in order not to pass on too much in constructors.

You can see an example of a nested class in the Orakle documentation:

/* Пример №2 *///classOuterClass{
    ...
    classNestedClass{
        ...
    }
}

We do not have, so far, any context for the use of this construct. With the same success, we can name the nested class instead of: “Nested class” (NestedClass) - “Inner class” InnerClass. Further we will understand what the differences are and in what contexts the classes are used. Bruce Ekkel writes in his book The Java Philosophy:
“A class is called nested if it is defined inside another class.”
Oracle documentation can be viewed at this link: >>>

Terminology:

There are four categories of nested classes:

  1. Static nested classes and non-static nested classes. Nested classes declared statically are called nested static classes.
  2. Inner classes - when an object of the inner class is associated with an object of the frame class. Non-static nested classes are called inner classes if they are associated with an outer class.
  3. Local classes are declared inside a block of code and are not a member of the framing class. In this case, you can consider the class as a local variable of type class.
  4. Anonymous classes are inheritable from any class in which the class name is not specified when declaring.

Reasons for using nested classes (Nesred Classes)
Why use nested classes?


The reasons for using nested classes are as follows. If a class is only useful for one other class, then it is logical to embed it in this class and store them together. Using nested classes increases encapsulation. Consider two top-level classes, A and B, where B needs access to members that would otherwise be declared closed.

/* Пример №3 *///classA{
    ...
    classB{
        ...
    }
}


By hiding class “B” within class “A”, members of class “A” can be declared closed, and “B” can access them. In addition, the "B" itself can be hidden from the outside world.

Let's demonstrate it in the code:

/* Учебный пример №4 */package innernested;
/**
 *
 * @author Ar20L80
 */publicclassA{
    privatestaticint iPrivVar;
    classB{
         voidsetPrivateOfA(intvar){
           A.iPrivVar = var;
         }
    }
}

Using nested classes leads to more readable and supported code: Placing a class closer to the place where it will be used makes the code more readable.

Static Nested Classes
Static Nested Classes


The reasons for using static nested classes are.

For the case when the relationship between the object of the nested class and the object of the external class is not needed, you can make the nested class static.

Since the inner class is associated with an instance, it cannot define any static members in itself.

Static nested classes have no restrictions on declaring their data and fields as static.

From the nested static class, we do not have access to the external non-static variable of the external class.

The code below demonstrates this:

/*
	Учебный пример №5
   Статические вложенные классы
    Попытка доступа к нестатической переменной 
    внешнего класса Outer2 через  обращение из вложенного статического класса Nested2
 */package nested;
/**
 *
 * @author Ar20L80
 * 20.03.2016
 */publicclassOuter2{
     publicint pubOutVar; // переменная не статическая и мы не имеем к ней доступа// из внутреннего статического классаprivateint prOutVar;
    publicOuter2(){}
    staticclassNested2{
        publicstaticint pub_innVar; // тут все в порядкеpublicNested2(){}
           intgetOuterPublicVariable(){
                  return Outer2.this.pubOutVar; // ошибкаreturn Outer2.pubOutVar; // ошибка
                }
           intgetOuterPrivateVariable(){
                 return Outer2.this.prOutVar; // ошибкаreturn Outer2.prOutVar; // ошибка
                }
    }
}
/*
вывод программы:
программа не компилируется
*/

Conclusion: We do not have access to the non-static field of the outer class through the static context of the nested class.

But we have access to the private static fields of the outer class from the nested static class.

The following code snippet demonstrates this:

/*
  Учебный пример №6  
  Статические вложенные классы 
 Демонстрация доступа к «приватной» статической переменной
 внешнего класса из внутреннего статического класса
   20.03.2016
 */package nested;
/**
 *
 * @author Ar20L80
 */publicclassOuter3{
      privatestaticint prStOuterVar;
      publicOuter3(){}
          staticclassNested3	  // Nested{ 
				 intgetStaticOuterVar(){
						  return Outer3.prStOuterVar; //  ok
						}
				 voidsetStaticOuterVariable(intvar){
						   Outer3.prStOuterVar = var; // ok
						}
			}
       publicstaticvoidmain(String[] args){
       Outer3.Nested3 nestedObj = new Outer3.Nested3(); // экземпляр класса внутренний
         Outer3.prStOuterVar = 19;
         System.out.println("nestedObj.getStaticOuterVar() = "+nestedObj.getStaticOuterVar());//статическая переменная внешнего класса из экземпляра внутреннего// устанавливаем через экземпляр внутреннего класса
        nestedObj.setStaticOuterVariable(77);
        System.out.println("Outer3.prStOuterVar = "+ Outer3.prStOuterVar);
       }
}
/*
Вывод программы:
nestedObj.getStaticOuterVar() = 19
Outer3.prStOuterVar = 77
*/

In this sample code, we created an instance of the inner class with the name "nestedObj".
That is, we get access to a private static variable of the outer class, through an instance of the inner class. In the context of the instance associated with the outer class, we have an inner class.

Literature by

Michael Morgan. “Java 2. Developer Guide” ISBN 5-8459-0046-8
Bruce Ekkel. “The Java Philosophy.” ISBN 5-272-00250-4
Herbert Schildt “Java. Complete guide. 8th edition. ”ISBN: 978-5-8459-1759-1

References:

ru.wikipedia.org
src-code.net/lokalnye-vnutrennie-klassy-java

Oracle Documentation

Any questions, comments, additions, criticisms are welcome.

To be continued ...
Part 2 >>>

Also popular now: