zoukankan      html  css  js  c++  java
  • Java 学习笔记(8)——匿名对象与内部类

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

    匿名对象

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

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

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

    当然也可以将匿名对象作为函数的返回值。

    内部类

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

    成员内部类

    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方法中创建了一个局部的内部类,这个内部类没有名字,也就是创建了一个匿名内部类。


  • 相关阅读:
    dropdownlist绑定和选中
    uploadify ,前端页面获取值,json,ajax
    sql 列设置默认值,语法查询知识点积累
    两个string数组对应比较
    镜像下载-收藏下
    我用shell写了个mud游戏:武林群侠传
    【shell】十分钟轻松入门;如果没入门,您吐口口水再走吧!
    【命令详解001】top
    那些未曾忘怀的
    mysql慢查询分析工具比较与实战
  • 原文地址:https://www.cnblogs.com/lanuage/p/10994885.html
Copyright © 2011-2022 走看看