Java 学习笔记-内部类

<div class="iteye-blog-content-contain" style="font-size: 14px">
       首先什么是内部类(Oracle网站上称之为Nested class.)?
       所谓Java内部类即在另一个类的内部定义的类(declared within another class), 内部类分为静态内部类(static nested class )和非静态内部类(non-static nested class)。很容易理解不须代码示例。
       静态内部类:行为上静态内部类等同于外部类(another top-level class),因此static nested class不能直接访问outer class 实例的变量和方法,但可以访问 outer class 的静态变量和方法。此外static nested class可以直接通过outer class 的类名访问,如:OuterClass.StaticNestedClass. 代码示例

public class StaticNestedClassExample {

    /*
     * an instance variable
     */
    private String outerString;

    /*
     * a class variable
     */
    private static String outerStaicString;

    /*
     * an instance method
     */
    public String outerMethod() {
        return "";
    }

    /*
     * a class method
     */
    public static String outerStaticMethod() {
        return "";
    }

    /*
     * static nested class
     */
    public static class StaticNestedClass {

        private String innerString;

        private static String innerStaticString;

        public void innerMethod() {
            this.innerString = outerString;// Compiling error. can not refer directly to outer class instance variables
                                           // and methods
            outerMethod();// Compiling error. can not refer directly to outer class instance variables and methods

            this.innerString = outerStaicString;// OK
            outerStaticMethod();// OK

            StaticNestedClass outerClass = new StaticNestedClass();
            outerClass.outerMethod();// outerMethod can be accessed by an OuterClass instance.
            innerStaticString = outerClass.outerString;// outerString can be accessed by an OuterClass instance.
        }

        public static void innerStaticMethod() {
            innerStaticString = outString; // Compiling error.
            innerStaticString = outerStaicString;// OK
            outerMethod();// Compiling error.
            outerStaticMethod();// OK

            StaticNestedClass outerClass = new StaticNestedClass();
            outerClass.outerMethod();// outerMethod can be accessed by an OuterClass instance.
            innerStaticString = outerClass.outerString;// outerString can be accessed by an OuterClass instance.
        }
    }

    public static void main(String... args) {
        StaticNestedClass nestObject2 = new StaticNestedClass();
        StaticNestedClass nestObject1 = new StaticNestedClassExample.StaticNestedClass();
    }
}

 
        接下来描述一下对非静态内部类non-static nested class的理解,常用的non-static nested class,我把它分为三种:General,Local,Asynomous.
       General的内部类也就是在top-level 的类中定义另一个类,类似与成员变量。
       Local 的内部类通常是在top-level 的方法中定义一个类,当然这个类是有名字的,而且不能用public来修饰。
       而Aysnomous内部类与Local唯一不同的就是没有名字,匿名类常用于实现接口。
    看代码:

package nested.classes.inner;

import java.util.List;

public class InnerClassExample {

    public class GneralInnerClass { // General

    }

    public void outerMethod() {
        class LocalInnerClass { // Local

        }
    }

    public void outerMethod2() {// Anonymous
        new Runnable() {
            @Override
            public void run() {
            }
        };
    }
}

 
以上是理解内部类定义以及相关概念的描述。
        接下来,我们为什么要用内部类呢?
        为什么使用内部类呢,个人还真不能说个一青二白,如果真要说,我认为主要是用来对类的封装使用以及逻辑上的组装,另外就是可以让代码易读易维护,还有在CSDN 看到说使用内部类可以实现所谓的多继承http://blog.csdn.net/yu422560654/article/details/7466260,也就是说outer class已经继承了一个类如果想在这个outer class A中继承或使用另一个outer class B 的方法,可以在这个outer class A里面实现一个内部类来继承outer class B。举几个之所以使用内部类原因的例子来帮助理解吧:


/

*
* Why use nested classes?
* There are several compelling reasons for using nested classes,among them:
* 
* 1. It is a way of logically grouping classes that 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. 
*/
public class LogicalGrouping {

    public static void validatePhoneNumber(String number) {

        class PhoneNumber {
            private String formattedPhoneNumber = null;

            static final int standardLength = 11;

            final static String regularExpression = "[^0-9]";

            PhoneNumber(String number) {
                String currentNumber = number.replaceAll(regularExpression, "");
                if (currentNumber.length() == standardLength) {
                    formattedPhoneNumber = currentNumber;
                } else {
                    formattedPhoneNumber = null;
                }
            }
            public String getNumber() {
                return formattedPhoneNumber;
            }
        }
        if (null == new PhoneNumber(number).getNumber()) {
            System.out.println("Invalid Number");
        } else {
            System.out.println("OK.");
        }
    }
    public static void main(String[] args) {
        validatePhoneNumber("1810-1109-123");
    }
}

 
在这个例子中,假设有个一个utility class 其中有个校验手机号的方法,而且这个类中的PhoneNumber 类只对这个utility class 有用,所以我们就用内部类的形式把这个校验逻辑写在一起,可以这样理解吧?再来一段代码:


/**
* Why use nested classes? There are several compelling reasons for using       * nested classes,among them:
* 
* 2.Increased 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.
*/
public class CorruptOfficial {//贪官
    private String privateCoffer;//小金库
    private class Concubine {//情妇
        Concubine() {
            System.out.println(privateCoffer);
        }
    }
}

 
这个例子可以说很形象,一个类A要访问另一类B的成员变量b,但是B的成员变量是不能让其他类访问的,所以只能声明为private,但是A需要访问,怎么办呢?把A声明称B的内部类。这样可以把类A隐藏起来。
例子中,贪官的小金库是不允许任何人访问的,但是贪官的小三可以,这种情况下只能把小三声明为贪官的内部类了,而且可以把小三隐藏的很好,不为公众所知!!
       关于使用内部类可以让代码易读以维护的例子就偷懒不写了。
Others
   1 静态内部类不能直接访问外部类的非静态成员变量或者方法,但是可以访问外部类的静态变量和方法
   2.非静态内部类不能声明静态的成员变量和方法,除了常量表达式。例如:

public class CorruptOfficial {
    private String privateCoffer;

    private class Concubine {
        static private String fighting;//compile error;
       final static private String finalFighting = "Fighting";//OK

       static void serve(){} //Compile error
        Concubine() {
            System.out.println(privateCoffer);
        }
    }
}

 
   3.如果需要访问外部类的实例成员变量和方法则将内部类声明为non-static,不需要则可以声明为static

   其实在工作中,内部类很少使用,至少我很少使用,只是稍微弄懂一下。

 </div>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值