Download as pptx, pdf, or txt
Download as pptx, pdf, or txt
You are on page 1of 24

CHAPTER 3 :

NESTED CLASSES
ADVANCED OBJECT–ORIENTED PROGRAMMING
Introduction to nested classes (1)
■ Is a class within a classs
■ The purpose of nested classes is to group classes that belong together. This makes the code more readable,
maintainable and increases the use of encapsulation.
■ The class written within is called the nested class, and the class that holds the inner class is called the outer
class.
■ To access the inner class, create an object of the outer class, and then create an object of the inner class.
■ The scope of a nested class is bounded by the scope of its enclosing class. Class NestedClass does not exist
independently of class OuterClass.
■ A nested class has access to the members, including private members, of the class in which it is nested.
However, reverse is not true (The outer class is accessible to inner class but the inner class is not accessible to
the outer class
■ A nested class is also a member of its enclosing class.
■ As a member of its enclosing class, a nested class can be declared private, public, protected, or package
private(default).
■ Nested classes are divided into two categories:
a) inner class : An inner class is a non-static nested class.
Two special kinds of inner classes: local classes and anonymous classes
b) static nested class : Nested classes that are declared static are called static nested classes.
OuterClass

INNER CLASS
Why Use Nested Classes?

■ It is a way of logically grouping classes that are only used in one place: If a class is
useful to only one other class, then it is logical to embed it in that class and keep the two
together. Nesting such "helper classes" makes their package more streamlined.
■ It increases encapsulation: Consider two top-level classes, A and B, where B needs access
to members of A that would otherwise be declared private. By hiding class B within class A,
A's members can be declared private and B can access them. In addition, B itself can be
hidden from the outside world.
■ It can lead to more readable and maintainable code: Nesting small classes within top-
level classes places the code closer to where it is used.
a. Inner classes (1)
■ An inner class is a non-static nested class.
■ One advantage of inner classes, is that they can access attributes and methods of the
outer class, even if they are declared private.
■ Inner classes are of two types depending on how and where the classes are defined.
 local Inner Class
 Anonymous Inner Class
INNER CLASSCreating
instance of inner class outside the outer class in java -example 1

class OuterClass {
int x = 10; If you try to access a private inner class from an outside class
class InnerClass { (MyMainClass), an error occurs
int y = 5;
} MyMainClass.java:12: error:
} OuterClass.InnerClass has private access in
public class MyMainClass { OuterClass
public static void main(String[] args) {
OuterClass myOuter = new So create an inner object
OuterClass(); OuterClass.InnerClass OuterClass.InnerClass myInner = myOuter.new
myInner = myOuter.new InnerClass(); InnerClass();
System.out.println(myInner.y +
myOuter.x);
}
}
// Outputs 15 (5 + 10)
Creating instance of inner class outside the outer class in java
-example 2

class CPU {
double price;
class Processor{
double cores;
OUTPUT:
String manufacturer;
double getCache(){ Processor Cache = 4.3
return 4.3; Ram Clock speed = 5.5
}
}
protected class RAM{
double memory;
String manufacturer;
double getClockSpeed(){
return 5.5;
}
}
}
public class Main {
public static void main(String[] args) {
CPU cpu = new CPU();
CPU.Processor processor = cpu.new Processor();
CPU.RAM ram = cpu.new RAM();
System.out.println("Processor Cache = " + processor.getCache());
System.out.println("Ram Clock speed = " + ram.getClockSpeed());
}
Accessing Members of Outer Class within Inner Class - example 3

public class car {


string carname;
string cartype; public class carmain {
public car(string name, string type) { public static void main(string[] args) {
this.carname = name; car car1 = new car("mazda", "8wd");
this.cartype = type; car.engine engine = car1.new engine();
} engine.setengine();
private string getcarname() { system.out.println("engine type for 8wd= " +
return this.carname; engine.getenginetype());
} car car2 = new car("crysler", "4wd");
class engine { car.engine c2engine = car2.new engine();
string enginetype; c2engine.setengine();
}
void setengine() { system.out.println("engine type for 4wd = " +
// Accessing Members of Outer Class within Inner Class c2engine.getenginetype());
// accessing cartype property of car }
if(car.this.cartype.equals("4wd")){ }
// invoking method getcarname() of car
if(car.this.getcarname().equals("crysler")) {
this.enginetype = "bigger";
} else {
this.enginetype = "smaller";
}
}else{ OUTPUT:
this.enginetype = "bigger";
}
} Engine Type for 8WD= Bigger Engine
string getenginetype(){ Type for 4WD = Smaller
return this.enginetype;
}
}
} An instance of outer class must be created before instance of inner class
b. Static Inner Class
■ An inner class can also be static, the members can be accessed it without creating an object of the outer class
■ Nested static class doesn’t need any reference of the Outer class. Non-static members are not accessed by a static class.
■ Nested classes that are declared static are called static nested classes.

EXAMPLE 1
class OuterClass {
int x = 10;

static class InnerClass {


int y = 5;
static inner class }
}

public class MyMainClass {


public static void main(String[] args) {
OuterClass.InnerClass myInner = new
OuterClass.InnerClass();
Does not need a reference from the Outer class. System.out.println(myInner.y);
}
}

// Outputs 5
Static Inner Class
EXAMPLE 2
// Java program to demonstrate accessing public class StaticNestedClassDemo{
// a static nested class public static void main(String[] args) {
// outer class // accessing a static nested class
class OuterClass{ OuterClass.StaticNestedClass nestedObject = new
OuterClass.StaticNestedClass();
static int outer_x = 10;
nestedObject.display();
int outer_y = 20; }
private static int outer_private = 30; }

// static nested class Output:


static class StaticNestedClass {
void display() { outer_x = 10
// can access static member of outer class System.out.println("outer_x = outer_private = 30
" + outer_x);
// can access display private static member of outer class
System.out.println("outer_private = " + outer_private);
// The following statement will give compilation error
// as static nested class cannot directly access non-static members //
System.out.println("outer_y = " + outer_y);
}
}
} Note: just like static attributes and methods, a static inner class does not have
access to non static members of the outer class.
Static Inner Class Output:

EXAMPLE 3 Total Ports = 3

public class MotherBoard {


String model;
public MotherBoard(String model) {
this.model = model;
}
static class USB{ An instance of USB from MotherBoard with the .
int usb2 = 2;
(dot) operator can be created without creating an
int usb3 = 1;
int getTotalPorts(){
instance of MotherBoard first.
return usb2 + usb3; }
}
}

public class Main { public static void main(String[] args) {


MotherBoard.USB usb = new MotherBoard.USB();
System.out.println("Total Ports = " + usb.getTotalPorts());
}
}
Static Inner Class EXAMPLE 4
public class MotherBoard
EXAMPLE 3 {
String model;
public MotherBoard(String model) {
this.model = model;
}
static class USB{
int usb2 = 2;
int usb3 = 1;
int getTotalPorts(){ When you run above program, you'll get an error:
if(MotherBoard.this.model.equals("MSI")) {
return 4;
} error: non-static variable this cannot be referenced from
else a static context
{ return usb2 + usb3;
}
}
}
}
public class Main {
public static void main(String[] args) {
MotherBoard.USB usb = new MotherBoard.USB();
System.out.println("Total Ports = " + usb.getTotalPorts());
}
}
Static Class(example5)
class OuterClass{ public class StaticClass {
private static String messageToReaders = "Hello Readers! Welcome to public static void main(String args[]){
DataFlair"; // instance of nested Static class
// Static nested class OuterClass.NestedStaticClass printer = new
public static class NestedStaticClass{ OuterClass.NestedStaticClass();
public void myMessage() {
System.out.println("Message from nested static class: " + // call non static method of nested static class
messageToReaders); printer.myMessage();
} OuterClass outer = new OuterClass();
} OuterClass.InnerClass inner = outer.new InnerClass();
// non-static nested class
public class InnerClass{ same // calling non-static method of Inner class
public void display(){ inner.display();
System.out.println("Message from non-static nested class: "+ OuterClass.InnerClass innerObject = new
messageToReaders); OuterClass().new InnerClass();
} innerObject.display();
} }
} }

printer.display() : illegal
Difference between static and
inner(non-static nested) classes:
• Static nested classes do not directly have access to other members (non-static variables
and methods) of the outer class, because as it is static, it must access the non-static
members of its enclosing class through an object. That is, it cannot refer to non-static
members of its enclosing class directly.  
• If the nested class does not access any of the variables of the enclosing class, it can be
made static. The advantage of this is that you do not need an enclosing instance of the
outer class to use the nested class.
• Non-static nested classes (inner classes) have access to all members (static and non-
static variables and methods, including private) of its outer class and may refer to them
directly in the same way that other non-static members of the outer class do. But it can
not  contain static members
Shadowed Variables
 happens when we define a variable in a closure scope with a variable name that is the same as
one for a variable we've already defined in an outer scope.
 Declaration of a type (such as a member variable or a parameter name) in a particular
scope (such as an inner class or a method definition) has the same name as another
declaration in the enclosing scope, then the declaration shadows the declaration of the
enclosing scope.
 To refer to a shadowed declaration by its name alone is not allowed
Shadowed Variables – how to access
public class ShadowTest {
 
public int x = 0;
output of this example:
  x = 23
class FirstLevel { this.x = 1
 
ShadowTest.this.x = 0
public int x = 1;
 
void methodInFirstLevel(int x) {
System.out.println("x = " + x);
System.out.println("this.x = " + this.x);
System.out.println("ShadowTest.this.x = " + ShadowTest.this.x);
}
}
 
public static void main(String... args) {
ShadowTest st = new ShadowTest();
ShadowTest.FirstLevel fl = st.new FirstLevel();
fl.methodInFirstLevel(23);
}
}
Local classes
• A local class is declared locally within a block of Java code, rather than as a member of a
class.

• Typically, a local class is defined within a method, but it can also be defined within a static
initializer or instance initializer of a class.

• Like member classes, local classes are associated with a containing instance, and can access
any members, including private members, of the containing class. local classes can access
any local variables, method parameters, or exception parameters that are in the scope of the
local method definition. but only if those variables or parameters are declared final.

• A local class is visible only within the block that defines it; it can never be used outside that
block.
Local Classes – cont.

• They cannot be declared public, protected, private, or static. These modifiers are for
members of classes; they are not allowed with local variable declarations or local
class declarations. Like member classes, and for the same reasons, local classes
cannot contain static fields, methods, or classes

• The only exception is for constants that are declared both static and final.

• A local class, like a member class, cannot have the same name as any of its
enclosing classes. This is because the lifetime of an instance of a local class can be
much longer than the execution of the method in which the class is defined.

• Because all blocks of Java code appear within class definitions, all local classes are
nested within containing classes 
Local classes example
public class LocalClassExample {
static String regularExpression = "[^0-9]"; PhoneNumber myNumber1 = new PhoneNumber(phoneNumber1);
PhoneNumber myNumber2 = new
public static void validatePhoneNumber( String phoneNumber1, String phoneNumber2) { PhoneNumber(phoneNu
final int numberLength = 10; // Valid in JDK 8 and later: mber2); //Valid in JDK 8
// int numberLength = 10; and later:
class PhoneNumber { // myNumber1.printOriginalNumbers();
String formattedPhoneNumber = null; if (myNumber1.getNumber() == null)
PhoneNumber(String phoneNumber){ System.out.println("First number is invalid");
// numberLength = 7; else
String currentNumber = phoneNumber.replaceAll( regularExpression, ""); System.out.println("First number is " + myNumber1.getNumber());
if (currentNumber.length() == numberLength)
formattedPhoneNumber = currentNumber; if (myNumber2.getNumber() == null)
else System.out.println("Second number is invalid");
formattedPhoneNumber = null; else
} System.out.println("Second number is " + myNumber2.getNumber());
public String getNumber() { } //end of method validatePhoneNumbeer
return formattedPhoneNumber;
} // Valid in JDK 8 and later: public static void main(String [] args) {
// public void printOriginalNumbers() { validatePhoneNumber("123-456-7890", "456-7890");
// System.out.println("Original numbers are " + phoneNumber1 + // " and " + }
phoneNumber2); }
// }
} //end of claa OhoneNumber

Output:

First number is 1234567890


Second number is invalid
ANONYMOUS CLASS
• A nested class that doesn't have any name.
• Must be defined inside another class. Hence, it is also known as an anonymous inner class.
Its syntax is:
• Syntax :
class outerClass {
 
// defining anonymous class
object1 = new Type(parameterList) {
// body of the anonymous class
};
}
Note: Anonymous classes are defined inside an expression. So, the semicolon is used at the end of anonymous
classes to indicate the end of the expression.

• Anonymous classes usually extend subclasses or implement interfaces.


Example 1: Anonymous Class Extending a Class
.

class Polygon {
public void display() { class Main {
System.out.println("Inside the Polygon class"); public static void main(String[] args) {
} AnonymousDemo an = new AnonymousDemo();
} an.createClass();
  }
class AnonymousDemo { }
public void createClass() {
  Output:
// creation of anonymous class extending class Polygon Inside an anonymous class.
Polygon p1 = new Polygon() {
public void display() {
System.out.println("Inside an anonymous class."); • an anonymous class is created that extends
} the class Polygon and overrides the
};  display() method.
p1.display(); • an object p1 of the anonymous class is
} created. The object then calls the  display()
}  method of the anonymous class
 
Example 2: Anonymous Class Implementing an
Interface
interface Polygon {
public void display();}
class AnonymousDemo { class Main {
public void createClass() { public static void main(String[] args) {
// anonymous class implementing interface AnonymousDemo an = new AnonymousDemo();
Polygon p1 = new Polygon() { an.createClass();
public void display() { }
System.out.println("Inside an }
anonymous class.");
} Output:
}; Inside an anonymous class.
p1.display();
}
}

• we have created an anonymous class that


implements the Polygon interface.
Guidelines In Using Anonymous Classes

• Anonymous class is useful when we have to create an instance of


the object with overloading methods of a class or interface
without creating a subclass of class.
• Anonymous can be created in two ways:
1. Class(can also be Abstract)
2. Interface
• In the anonymous class we can declare the following:
1. Fields
2. Extra methods
3. Instance Initializers
4. Local classes
 
Difference Between Regular and Anonymous Inner
Class
• We can implement multiple numbers of interfaces by using normal class but, with an
anonymous inner class, we can only implement one interface.

• With regular class we can extend a class and also implement multiple interfaces but, with
an anonymous inner class, we can either extend a class or implement an interface but not
both at the same time.

• With anonymous we cannot write constructor because the anonymous inner class does
not have name and name of the constructor should be same as the class name.

You might also like