Advanced Java class Nested Classes Interfaces Types of






















![Anonymous Local Inner Classes • syntax: – Type object. Name = new [Super. Type()] Anonymous Local Inner Classes • syntax: – Type object. Name = new [Super. Type()]](https://slidetodoc.com/presentation_image_h2/cbb9b200d046dadc3dddcebc013fb8a3/image-23.jpg)

- Slides: 24

Advanced Java class Nested Classes & Interfaces

Types of Nested Classes & Interfaces • top-level nested – classes – interfaces • inner classes – member – local • named • anonymous

Some Definitions • Nested = a class or interface definition is somewhere inside another one • Top-level class or interface = an instance of a type does not need to be instantiated with a reference to any enclosing instance • Inner class = an instance of a class does need to be instantiated with an enclosing instance • Inner Member class = defined inside another class, but not inside any methods. • Inner Local class = defined inside a method • Named Inner Local class = has a class name • Anonymous Inner Local class = does not have a class name

Top-level Classes & Interfaces • Declared inside a class (or interface) definition • Must be declared as static • The class (or interface) definition is not a member of an instantiation of the outer class (or interface). • Shows a close functional relationship between the types. • Class referencing syntax: Outer. Class. Inner. Class • You can nest classes in interfaces, and vice versa.

Here Property is a Top-Level Nested Class public class Property. Value. Finder { final String GET = "get"; public void print. Properties(Object o) {. . . } private Property property. Gotten. By(Method m) {. . . } private boolean is. Getter(Method m) {. . . } static public class Property {. . . } } in another class, far away. . . Property. Value. Finder. Property p = new Property. Value. Finder. Property("hi", String. class); • No enclosing instance of Property. Value. Finder is needed to make an instance of Property

Scope of Top-level Nested Classes • Enclosed classes share private access with other enclosed classes in the same enclosing class, and with the enclosing class. – (Note: the book is wrong on this point, as shown by the compilation and running of the following example. )

public class Top. Level. Nested { private int my. Int. TLN = 3; void test() { new Other 1(). print. Other 2(); new Other 2(). print. Other 1(); } private void test 2() {System. out. println("test 2"); } static class Other 1 { private int my. Int. O 1 = 1; static void print. Other 2(){ System. out. println(new Other 2(). my. Int. O 2); new Top. Level. Nested(). test 2(); } } private static class Other 2 { private int my. Int. O 2 = 2; private static void print. Other 1(){ System. out. println(new Other 1(). my. Int. O 1); System. out. println(new Top. Level. Nested(). my. Int. TLN); } } }

Inner Classes • Member – Defined in class definition, not static • Local (private, not static) – Defined in method definition – May be named or anonymous

Using Inner Classes • Reasons to use: – Nice for classes that implement 1 -method interfaces – Adapter classes (see ex. page. 129) Presenting some aspect(s) of the enclosing class in terms of an interface that it does not implement • Can not be static. • The class definition is a member of the outer class. (And therefore accessible via reflection. ) • Inner object shares scope of outer object. • These are classes, not interfaces.

Here Property is a Member Inner Class public class Property. Value. Finder { final String GET = "get"; public void print. Properties(Object o) {. . . } private Property property. Gotten. By(Method m) {. . . } private boolean is. Getter(Method m) {. . . } public class Property {. . . } } in another class, far away. . . Property. Value. Finder pvf = new Property. Value. Finder(); Property. Value. Finder. Property p = pvf. new Property("hi", String. class); • An enclosing instance of Property. Value. Finder is needed to make an instance of Property

Scope of Inner Classes • Scope: – in the inner class, “this” refers to both the instance of the inner class and its enclosing class instance – this means that the inner object can refer directly to fields and methods of the outer object – See example next page

public class Outer { private String my. String = "outer"; private String outer. String ="outer !"; void test() { System. out. print("test "); System. out. println(my. String); new Inner(). test. Inner(); } private void test 2() { System. out. print("test 2 "); System. out. println(my. String); } class Inner { private String my. String = "inner"; private void test. Inner(){ System. out. print("test. Inner "); System. out. println(my. String); System. out. println(outer. String); test 2(); } } }

Inner classes extend other classes • Inheritance vs. Enclosing Scope – If not fully specified, order is: • inner, super, enclosing • (book says won’t compile, but I don’t find this true) – If all of these exist, you should specify to: • inner: this. X • super: super. X • enclosing: Enclosing. Class. Name. this. X

Enclosing Class has outer most scope public class Scope. Conflict { String s = "outer"; class Inner extends Super. Class { //String s = "inner"; void foo(){ System. out. println(s); } } } class Super. Class { //String s = "super"; } in another class: Scope. Conflict sc = new Scope. Conflict(); Scope. Conflict. Inner inner = sc. new Inner(); inner. foo(); output: outer

Super class has scope between Enclosing and Inner class public class Scope. Conflict { String s = "outer"; class Inner extends Super. Class { //String s = "inner"; void foo(){ System. out. println(s); } } } class Super. Class { String s = "super"; } in another class: Scope. Conflict sc = new Scope. Conflict(); Scope. Conflict. Inner inner = sc. new Inner(); inner. foo(); output: super

Inner class has innermost scope public class Scope. Conflict { String s = "outer"; class Inner extends Super. Class { String s = "inner"; void foo(){ System. out. println(s); } } } class Super. Class { String s = "super"; } in another class: Scope. Conflict sc = new Scope. Conflict(); Scope. Conflict. Inner inner = sc. new Inner(); inner. foo(); output: inner

Specifying which scope you want: public class Scope. Conflict { output: String s = "outer"; class Inner extends Super. Class { String s = "inner"; void foo(){ System. out. println(this. s); System. out. println(super. s); System. out. println(Scope. Conflict. this. s); } } } class Super. Class { String s = "super"; } inner (from this. s) super (from super. s) outer (from Scope. Conflict. this. s)

Member Inner Class as Superclasses public class Computer { int model; Computer(int i) { model = i; } public class Hard. Drive { int size; public Hard. Drive(int i) { size = i; } public Hard. Drive() { size = 40; } } } class SCSI extends Computer. Hard. Drive{ SCSI (Computer c) { c. super(80); } }

Local Inner Classes • Defined inside a method in an enclosing class • Has access not only to the scope of the enclosing object(s), but also to the scope of the enclosing method any code blocks that are final. • Two types – Local Inner Named Classes – Local Inner Anonymous Classes

Local Inner Classes • In a instance method – Can use all members of the enclosing instance • In a class method – Can only use class members (because it’s in a static context).

Local Inner Classes • Why must the local enclosing fields be final to be in scope? Because the objects (not the classes) can be used outside of the scope they were created in, so they must have a copy of the local fields from their original scope. These local copies would be wrong if the fields changed, so the fields must be final to protect the integrity of the local inner class object.

Named Local Inner classes public class Outer { public void outer. Method() { class Inner. Class {. . . } } } • See example 2 -30 on page 129 – accesses all of these things from different scopes: • private instance variable of enclosing object [equation. Input] • arguments of the instance method the local inner class was defined in [input 1 & input 2] • private variable local to method [local. Var[2]] • private instance of local inner class [normal. Field]
![Anonymous Local Inner Classes syntax Type object Name new Super Type Anonymous Local Inner Classes • syntax: – Type object. Name = new [Super. Type()]](https://slidetodoc.com/presentation_image_h2/cbb9b200d046dadc3dddcebc013fb8a3/image-23.jpg)
Anonymous Local Inner Classes • syntax: – Type object. Name = new [Super. Type()] {. . . } • (If you don’t provide a Super. Type, defaults to Object, as usual. ) • This syntax both defines the class and instantiates it. • No name, and no constructors. • To initialize instance variables, use a initialization statement: { // initializations go here }

Group Task None for now! Will be combined with other tasks, relating to Threads, Events, GUI, etc.