Java笔记丨20 内部类与匿名类

内部类是在其他类中的类

匿名类是一种特殊的内部类,它没有类名

 

内部类

内部类的定义

将类的定义class xxxx{…}置入一个类的内部即可

编译器生成xxxx$xxxx这样的class文件

内部类不能与外部类同名

内部类的使用

在封装它的类的内部使用内部类,与普通类的使用方式相同

在其他地方使用,类名前要冠以外部类的名字。在用new创建内部类时,也要在new前面冠以对象变量:外部对象名.new内部类名(参数)

示例:TestInnerClass.java

class TestInnerClass{

       public static void main( String[] args ){

              Parcel p = new Parcel();

              p.testShip();



              Parcel.Contents c = p.new Contents(33);

              Parcel.Destination d = p.new Destination( "Hawii" );

              p.setProperty( c, d );

              p.ship();

       }

}



class Parcel {

  private Contents c;

  private Destination d;

  class Contents {

    private int i;

       Contents( int i ){ this.i = i; }

    int value() { return i; }

  }

  class Destination {

    private String label;

    Destination(String whereTo) {label = whereTo;}

    String readLabel() { return label; }

  }

  void setProperty( Contents c, Destination d ){

       this.c =c; this.d = d;

  }

  void ship(){

       System.out.println( "move "+ c.value() +" to "+ d.readLabel() );

  }

  public void testShip() {

    c = new Contents(22);

    d = new Destination("Beijing");

    ship();

  }

}

 

在内部类中使用外部类的成员

内部类可以直接访问外部类的字段及方法(即使private也可以)

如果内部类有与外部类同名的字段或方法,可以用:外部类名.this.字段及方法

示例:TestInnerThis.java

public class TestInnerThis

{   

       public static void main(String args[]){

           A a = new A();

           A.B b = a.new B();

           b.mb(333);

    }

}



class A

{

       private int s = 111;



       public class B {

           private int s = 222;

           public void mb(int s) {

               System.out.println(s);// 局部变量s

               System.out.println(this.s); // 内部类对象的属性s

               System.out.println(A.this.s); //  外层类对象属性s

           }

    }

}

结果:

333

222

111

 

内部类的修饰符

内部类与类中的字段、方法一样是外部类的成员,它前面也可以有访问控制符和其他修饰符

访问控制符:public protected 默认及private

注:外部类只能够用public修饰或者默认

final abstract

 

static修饰符

用static修饰内部类,表明该内部类实际是一种外部类,因为它与外部类实例无关。有人认为static是嵌套类,不是内部类。

static类在使用时:

1.实例化static类时,在new前面不需要用对象实例变量

2.static类中不能访问其外部类的非static的字段及方法,即只能访问static成员

3.static方法中不能访问非static的域及方法,也不能不带前缀地new一个非static内部类

示例:TetsInnerStatic.java

class TestInnerStatic

{

       public static void main(String[] args)

       {

              A.B a_b = new A().new B();  // ok

              A a = new A();

              A.B ab =  a.new B();



              Outer.Inner oi = new Outer.Inner();

              //Outer.Inner oi2 = Outer.new Inner();  //!!!error  

              //Outer.Inner oi3 = new Outer().new Inner(); //!!! error

       }

}



class A   

{

       private int x;

       void m(){

              new B();

       }

       static void sm(){

              //new B();  // error!!!!

       }

       class B

       {

              B(){ x=5; }

       }

}



class Outer  

{

       static class Inner

       {

       }

}

局部类

在一个方法中也可以定义类,这种类称为“方法中的内部类”或局部类

使用局部类

1.同局部变量一样,方法中的内部类

不能够用public、private、protected、static修饰,但可以用final或abstract修饰

2.可以访问其外部类的成员

3.不能够访问该方法的局部变量,除非是final局部变量

 

匿名类

匿名类是一种特殊的内部类。它没有类名,在定义类的同时就生成该对象的一个实例。一次性使用的类

class TestInnerAnonymous

{

       public static void main(String[] args)

       {

              Object obj = new Outer().makeTheInner(47);

              System.out.println("Hello World!" + obj.toString() );

       }

}



class Outer

{

       private int size = 5;

       public Object makeTheInner( int localVar )

       {

              final int finalLocalVar = 99;

              return new Object()  {

                     public String toString() {

                            return ( " InnerSize: " + size +

                                   " finalLocalVar: " + finalLocalVar

                            );

                     }

              };

       }

}

匿名类的使用

1.不取名字,直接用其父类或接口的名字

也就是说,该类是父类的子类,或者实现了一个接口

编译器生成xxxx$1之类的名字

2.类的定义同时就创建实例,即类的定义前面有一个new

new类名或接口名(){…}

不使用关键字class,也不使用extends及implements

3.在构造对象时使用父类的构造方法

不能够定义构造方法,因为它没有名字

如果new对象时,要带参数,则使用父类的构造方法

 

匿名类的应用

作为方法的参数

排序,给一个比较大小的接口

如:SortTest.java

import java.util.Arrays;

import java.util.Comparator;



class SortTest {

       public static void main(String[] args){

      

              Book[] books = new Book[10];

              for (int i=0; i<books.length; i++ ){

                     books[i] = new Book((int)(Math.random()*100));

              }

              dump(books);

              Arrays.<Book>sort( books, new Comparator<Book>(){

                     public int compare(Book b1, Book b2){

                            return b1.getPrice()-b2.getPrice();

                     }

              });

              dump(books);

       }

       static void dump( Book [] books ){

              for (int i=0; i<books.length; i++ ){

                     System.out.print(books[i]+" ");

              }

              System.out.println();

       }

}

class Book

{

       private int price;

       Book(int price){ this.price=price; }

       int getPrice(){ return price;}

       public String toString(){ return ""+price; }

}

猜你喜欢

转载自blog.csdn.net/qq_42968048/article/details/84669221