Java 学习笔记(8)——匿名对象与内部类

通常在编写代码时可能会遇到这样的场景——在某些时候,我须要定义并某个类,可是只会使用这一次,或者是某个类对象只会使用一次,为它们专门取名可能会显的很麻烦。为了应对这种状况,Java中容许使用匿名对象和匿名内部类的方式来解决这个矛盾
java

匿名对象

普通的类对象在使用时会定义一个类类型的变量,用来保存new出来的类所在的地址。而匿名类取消掉了这个变量,这个地址由编译器来处理,而且在new出来以后,它占用的内存会有JVM自动回收掉。后续没法再使用了。
例如函数

public class Student{
    public void classBegin(){
        System.out.println("good morning teacher!");
    }
}

new Student().classBegin();

匿名对象最经常使用的方式是做为函数的参数,好比上述的打印语句 "good morning teacher!" 它就是一个匿名对象,因为字符串是以对象的形式存储的,因此这里实际上就是一个没有使用对象引用的匿名对象。this

固然也能够将匿名对象做为函数的返回值。设计

内部类

内部类的种类:成员内部类、静态内部类、局部内部类、匿名内部类code

成员内部类

java中容许在一个类中定义另外一个类。例如对象

public class Car{
    public class Engine{
        
    }
}

上述例子在Car这个类中定义了一个Engine类,那么Car就是外部类,而Engine就是内部类。接口

使用内部类须要注意:外部类是包含内部类的,因此内部类能够看到外部类的全部属性和方法,包括private方法。可是反过来则不行;内存

使用内部类主要有两种方式:字符串

  • 在外部类中使用内部类的成员(间接使用)。这种方法通常是在外部类的方法中建立内部类的对象,并调用对象的方法
  • 直接使用:根据上面的定义,能够这样使用 `Car.Engine eng = new Car().new Engine()

好比下面的例子编译器

public class Car{
    public class Engine{
        public void start(){
            System.out.println("引擎启动");
        }
    }

    //间接调用
    public void start(){
        System.out.println("打火");
        new Engine().start();
    }

    public static void main(String[] args){
        new Car().start();

        //直接调用
        Car.Engine engine = new Car().new Engine();
        engine.start(); 
    }
}

当外部类和内部类的成员发生命名冲突的时候在内部类中可使用 外部类.this.成员变量 来访问外部类的成员
好比说

public class Car{
    public String type = "奥迪";
    public class Engine{
        public String type = "奥迪引擎";
        public void start(){
            System.out.println("引擎启动");
        }
        
        public void carType(){
            System.out.println(Car.this.type);
        }
    }

    //间接调用
    public void start(){
        System.out.println("打火");
        new Engine().start();
    }

    public static void main(String[] args){
        Car car = new Car();
        //直接调用
        Car.Engine engine = new Car().new Engine();
        engine.start();
        engine.carType();
        
    }
}

局部内部类

内部类不光能够直接定义在外部类中做为成员内部类,也能够定义在方法中,做为局部内部类

局部内部类也叫区域内嵌类,局部内部类与成员内部类相似,不过,区域内嵌类是定义在一个方法中的内嵌类

主要特定有:

  • 局部内部类只能在对应方法中访问,在方法外无效
  • 不能使用private,protected,public修饰符。
  • 不能包含静态成员
  • 局部内部类若是想要访问方法中的局部变量时,局部变量必须是常量。由于局部变量时分配在栈中,而局部内部类是分配在堆中的,有可能出现这样的状况,外部类的方法执行完了,内存被回收了,可是局部内部类可能还在,因此在访问局部变量时,作了一个拷贝将局部变量拷贝到局部内部类所在的堆中。为了保证数据的完整性,因此这里被拷贝的变量不容许再作修改。
public class carShow(){
    public void showCar(){
        final float price = 10000000f;
        final String type = "奔驰";

        class Car(){
            public void show(){
                System.out.println("这个车是" + type + ",售价:" + price);
            }
        }
    }
}

静态内部类

内部类若是使用static声明,则此内部类就称为静态内部类。它能够经过 外部类 . 内部类 的方式来访问。因为静态内部类是与对象无关的,在使用静态类的成员时是不须要建立对象的。因此若是想要在静态内部类中来访问外部类的成员变量,必须经过外部类的对象实例来访问。

public class Company {
    String companyNam;
    static String country;
    static class Clear{
        String name;
        public Clear() {
        }
        
        public Clear(String name) {
            super();
            this.name = name;
        }

        public void work(String name){
            String na = new Company().companyNam="联想";
            country="中国";
            System.out.println(name+"为"+na+"打扫卫生,该公司属于"+country);
        }
    }
}

匿名内部类

若是一个内部类在整个操做中只使用一次的话,就能够定义为匿名内部类。匿名内部类也就是没有名字的内部类,这是java为了方便咱们编写程序而设计的一个机制,由于有时候有的内部类只须要建立一个它的对象就能够了,之后再不会用到这个类,这时候使用匿名内部类就比较合适。

匿名内部类,通常都伴随着接口一块儿使用好比

public interface USB{
    public abstract void open();
    public abstract void close();
}

public class Demo{
    public static void main(String[] args){
        USB usb = new USB(){
            public void open(){}
            public void close(){}
        }

        usb.open();
        usb.close();

        //使用匿名内部类的匿名对象的方式
        USB usb = new USB(){
            public void open(){}
            public void close(){}
        }.open();
    }
}

在Demo这个类的main方法中建立了一个局部的内部类,这个内部类没有名字,也就是建立了一个匿名内部类。

相关文章
相关标签/搜索