java内部类总结

内部类是指在一个外部类的内部再定义一个类。
内部类作为外部类的一个成员,并且依附于外部类而存在的。
内部类可为静态,可用protected和private修饰。(而外部类不可以:外部类只能使用public和默认的)。

内部类分为:成员内部类、局部内部类、静态内部类、匿名内部类

几种内部类的共性:
A、内部类仍然是一个独立的类,在编译之后会内部类会被编译成独立的.class文件,但是前面冠以外部类的类命和$符号,比如Outer.class和Outer$Inner.class。
B、内部类不能用普通的方式访问。内部类是外部类的一个成员,因此内部类可以自由地访问外部类的成员变量,无论是否是private的。

成员内部类:

成员内部类:形式如下


1

2

3

class Outer {

    class Inner{}

}

 编译上述代码会产生两个文件:Outer.class和Outer$Inner.class。
成员内部类内不允许有任何静态声明!下面代码不能通过编译。
  


1

2

3

class Inner{

      static int a = 10;

  }

能够访问成员内部类的唯一途径就是通过外部类的对象!

下面看一个成员内部类的例子:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

public interface Contents {

    int value();

}

public interface Destination {

    String readLabel();

}

public class Goods {

    private class Content implements Contents {

        private int i = 11;

        public int value() {

            return i;

        }

    }

    protected class GDestination implements Destination {

        private String label;

        private GDestination(String whereTo) {

            label = whereTo;

        }

        public String readLabel() {

            return label;

        }

    }

    public Destination dest(String s) {

        return new GDestination(s);

    }

    public Contents cont() {

        return new Content();

    }

}

class TestGoods {

    public static void main(String[] args) {

        Goods p = new Goods();

        Contents c = p.cont();

        Destination d = p.dest("Beijing");

    }

}

  

内部类的第一个好处就体现出来了 隐藏你不想让别人知道的操作,也即封装性。
同时,我们也发现了在外部类作用范围之外得到内部类对象的第一个方法,那就是利用其外部类的方法创建并返回。上例中的cont()和dest()方法就是这么做的。那么还有没有别的方法呢?当然有,其语法格式如下:


1

2

outerObject=new outerClass(Constructor Parameters);

outerClass.innerClass innerObject=outerObject.new InnerClass(Constructor Parameters);

注意在创建非静态内部类对象时,一定要先创建起相应的外部类对象。至于原因: 非静态内部类对象有着指向其外部类对象的引用。

内部类的this引用:普通的类可以用this引用当前的对象,内部类也是如此。但是假若内部类想引用外部类当前的对象呢?用“外部类名”.this;的形式,如下例的Outer.this:


1

2

3

4

5

6

7

8

class Outer {

    class Inner{

        public void seeOuter(){

            System.out.println(this);

            System.out.println(Outer.this);

        }

    }

}

对于普通的类,可用的修饰符有final、abstract、strictfp、public和默认的包访问。
但是成员内部类更像一个成员变量和方法,他可用的修饰符有:final、abstract、public、private、protected、strictfp和static。
不过一旦用static修饰内部类,它就变成静态内部类了。 

静态内部类

和非静态内部类相比,区别就在于静态内部类没有了指向外部的引用。除此之外,在任何非静态内部类中,都不能有静态数据,静态方法或者又一个静态内部类(内部类的嵌套可以不止一层)。不过静态内部类中却可以拥有这一切。这也算是两者的第二个区别吧。


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

public class StaticInnerClassDemo {

    protected int protected_k = 2;

    public int public_n = 3;

    public static int public_static_j;

     

    static class InnerClass{

        void innerDisplay(){

            //只能访问外部类的静态变量和静态方法

            System.out.println(public_static_j);

        }

    }

    public static void main(String[] args) {

        new StaticInnerClassDemo();

        InnerClass inner=new InnerClass();

        inner.innerDisplay();

    }

}

局部内部类

Java内部类也可以是局部的,它可以定义在一个方法甚至一个代码块之内。


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

public class PartInnerClassDemo {

    private int private_m = 1;

    protected int protected_k = 2;

    public int public_n = 3;

 

    public void function() {

        final int num = 0;

        class InnerClass {

            public void innerDisplay() {

                System.out.println(private_m);

                System.out.println(protected_k);

                System.out.println(public_n);

                // 此处的num必须是final

                System.out.println(num);

            }

        }

        new InnerClass().innerDisplay();

    }

 

    public static void main(String[] args) {

        PartInnerClassDemo outer = new PartInnerClassDemo();

        outer.function();

    }

}

A、局部内部类只能在定义该内部类的方法内实例化,不可以在此方法外对其实例化。

B、局部内部类对象不能使用该内部类所在方法的非final局部变量。
因为方法的局部变量位于栈上,只存在于该方法的生命期内。当一个方法结束,其栈结构被删除,局部变量成为历史。但是该方法结束之后,在方法内创建的内部类对象可能仍然存在于堆中!例如,如果对它的引用被传递到其他某些代码,并存储在一个成员变量内。正因为不能保证局部变量的存活期和方法内部类对象的一样长,所以内部类对象不能使用它们。

局部内部类的修饰符:与成员内部类不同,局部内部类更像一个局部变量。可以用于修饰局部内部类的只有final和abstract。

静态方法内的局部内部类:
静态方法是没有this引用的,因此在静态方法内的内部类遭受同样的待遇,即:只能访问外部类的静态成员。

类匿名内部

  顾名思义,没有名字的内部类。表面上看起来它们似乎有名字,实际那不是它们的名字。

继承式的匿名内部类


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

class Car {

    public void drive(){

        System.out.println("Driving a car!");

    }

}

 

class Test{

    public static void main(String[] args) {

        Car car = new Car(){

            public void drive(){

                System.out.println("Driving another car!");

            }

        };

        car.drive();

    }

}

结果输出了:Driving another car! Car引用变量不是引用Car对象,而是Car匿名子类的对象。
建立匿名内部类的关键点是重写父类的一个或多个方法。再强调一下,是重写父类的方法,而不是创建新的方法。因为用父类的引用不可能调用父类本身没有的方法!创建新的方法是多余的。简言之,参考多态。

接口式的匿名内部类


1

2

3

4

5

6

7

8

9

10

11

12

13

14

interface  Vehicle {

      public void drive();

  }

   

  class Test{

      public static void main(String[] args) {

          Vehicle v = new Vehicle(){

              public void drive(){

                  System.out.println("Driving a car!");

              }

          };

          v.drive();

      }

  }

 上面的代码很怪,好像是在实例化一个接口。事实并非如此,接口式的匿名内部类是实现了一个接口的匿名类。而且只能实现一个接口。 

参数式的匿名内部类


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

class Bar{

    void doStuff(Foo f){}

}

 

interface Foo{

    void foo();

}

 

class Test{

    static void go(){

        Bar b = new Bar();

        b.doStuff(new Foo(){

            public void foo(){

                System.out.println("foofy");

            }

        });

    }

}

时间: 2024-10-31 22:06:12

java内部类总结的相关文章

Java内部类this$0字段产生的一个小bug

首先查看下面一段代码,我指出了问题代码的所在,读者先自己思考一下这段代码会有什么问题. 这是用clone方法完整拷贝一个二项堆(BinomialHeap)结构的代码.二项堆中包含一个内部类BinomialHeapEntry,这个内部类的对象即二项堆中的每一个结点,除了包含结点对应的关键字外,还记录父节点parent,下一个兄弟结点sibling和第一个孩子结点child三个指针.二项堆的根表通过每棵二项树根节点的sibling指针链接. cloneBinomialTree(BinomialHea

Java内部类的继承(全)_java

下面通过实例代码给大家分享下有关JAVA内部类的继承,具体详解如下: Java内部类的构造器必须连接到指向其外围类对象的引用(构造内部类必须给它一个外部类对象的引用,内部类依赖于外部类对象),所以在继承内部类的时候,需要在导出类的构造器中手动加入对基类构造器的调用. 因为,在导出类实例化时,并不存在一个外围类对象,以让导出类的实例去连接到它. 所以,我们需要创建一个外围类,然后用一个特定的语法来表明内部类与外围类的关系. 在下例子中,需要给导出类InheritInner一个来自内部类的外围类中的

java-本人新手求教 关于Java内部类的问题 请大神看图

问题描述 本人新手求教 关于Java内部类的问题 请大神看图 解决方案 就是将 entry 这个对象 加入到 entrys这个数组中去 , 每次夹的时候 都会 count 加1 解决方案二: 这个呢也不是内部类的问题,,就是entrys数组中放入entry对象,,count++就是count先赋值再自增 解决方案三: 将实例entry赋值给entry数组.具体不知道你具体想问什么? 解决方案四: 这个不是内部类的问题,是在一个类中定义了方法,然后把entry 的值赋给entrys 数组j进行前+

java内部类-java实验题 内部类的定义与使用

问题描述 java实验题 内部类的定义与使用 定义一个Cube类,其中包含一个变量height,一个方法:计算立方体的体积(带形参,形参为面积).并在其内部定义一个Rectangle类,其中包含两个变量width和height,一个方法:计算底面积. 解决方案 class Cube { private double height; Cube() {} Cube(double height) { this.height = height; } public double volume(double

java内部类实例化错误

问题描述 java内部类实例化错误 请帮我看看下面出错的原因是什么?(粗体字部分) 为什么静态方法里不能直接调用内部类,成员方法却可以? package com.zcl5; class Quetion1 { class ATM { int myMoney = 100; int viewMoney(){ return myMoney; } void outMoney(int money){ myMoney=myMoney-money; } } public void m1(){ ATM atm=n

java 内部类-java方法中定义的局部内部类问题

问题描述 java方法中定义的局部内部类问题 在方法中定义的内部类为什么只能访问方法中的final类型局部变量? package com.study; interface OutInterface2{ //定义一个接口 } class OuterClass3 { public OutInterface2 doit(final String x){//doit方法参数为final类型 //在doit()方法中定义一个内部类 class InnerClass2 implements OutInter

java内部类 引用外部类对象this问题

问题描述 java内部类 引用外部类对象this问题 在内部类里,想引用外部类的对象,为什么是外部类.this而不是外部类加引用变量,还有.操作应该是成员操作符吧,这样this不就成了外部类成员了 解决方案 你好,实际上我们代指当前类对象的this是个简写形式,完整的形式就是 类名字.this,举个例子来说吧 class OuterClass { private String outAttribute = "我是外部类属性"; public void printOutAttribute

java 内部类-关于Java内部类的问题

问题描述 关于Java内部类的问题 这段代码的内存运行状态是怎样的 那个this是什么情况 为什么也指向Inner呢 解决方案 字太小,看不清你的代码.另外你的标签同时提到java和javascript,这是两种截然不同的语言. 解决方案二: 前一段时间在CSDN论坛回答的一个问题,觉得蛮有意思的,决定拿出来在这里记录一下.?问题的提出:?该例子程序涉及到了三个class文件,分别是Contents.java,Destination.java,Parcel10.java.其中的Contents.

uml中如何表示java内部类

问题描述 uml中如何表示java内部类 解决方案 见http://www.uml.org.cn/oobject/20111271.asp解决方案二:上面的两个回答非常不错,非常感谢.解决方案三:看这个http://blog.csdn.net/lord_is_layuping/article/details/7247847 有图有真相