zoukankan      html  css  js  c++  java
  • JAVA内部类介绍

    原则:在拥有外部类对象之前是不可能创建内部类对象的。
    因为内部类对象会暗暗地连接到创建它的外部类对象上。但是注意嵌套类(静态内部类)是不需要对外部类对象的引用。

    内部类的使用1:(向上转型)

    interface Destination{
        String readLabel();
    }
    
    interface Contents{
        int value();
    }
    
    class Parce{
        public class Testnew{
            public Parce outer(){
                return Parce.this;//外部类的.this用法
            }
        }
        
        protected class PDestination implements Destination{
            private String label;
            private PDestination(String str){
                label = str;
            }
            public String readLabel(){
                return label;
            }
        }
        
        //private 说明了在Parce类外部是无法访问内部类PContents
        private class PContents implements Contents{
            private int i = 5;
            public int value(){return i;}
        }
        
        public Destination getDestination(String str){
            return new PDestination(str);
        }
        
        public Contents getContents(){
            return new PContents();
        }
    }
    
    public class Test
    {
        public static void main(String[] str){
            Parce p = new Parce();
            Contents c = p.getContents();
            Destination d= p.getDestination("test");
            
            //在外部访问public的内部类,必须有外部类实例
            Parce.Testnew t = p.new Testnew(); //OK
            //p.TestNew t = p.new TestNew();//ERROR
            //Parce.Testnew t = p.new Parce.Testnew();//ERROR  
        }
    }

    方法和作用域的内部类:(局部内部类)

    interface Destination{
        String readLabel();
    }
    
    class Parce{
        //方法中的内部类
        /*
         PDestination类是getDestination方法中的一部分,而不是Parce类中的一部分。
         所以在getDestination之外是无法访问PDestination类的。
         都是这并不意味一旦getDestination方法执行完毕,PDestination就不可用了。
         */
        public Destination getDestination(String str){
            class PDestination implements Destination{
                private String label;
                private PDestination(String str){
                    label = str;
                }
                public String readLabel(){
                    return label;
                }
            }
            
            return new PDestination(str);
        }
        
        //作用域中的内部类
        private void intertest(boolean b){
            /* 
             IntertestA类嵌入if语句的作用域内,并不是说该类的创建时有条件的,它实际上和
             别的类一起编译过了
            */
            if (b){
                class IntertestA{
                    private String id;
                    IntertestA(String s){id = s;}
                    String getID(){return id;}
                }
            
                IntertestA it = new  IntertestA("hello");
                String s = it.getID();
            }
            //IntertestA it = new  IntertestA("hello");//ERROR
            //超出了IntertestA类的作用范围
        }
        
        public void test() {intertest(true);}
    }
    
    public class Test{
        public static void main(String[] str){
            Parce p = new Parce();
            Destination d = p.getDestination("test");
            p.test();
        }
    }

    匿名内部类

    interface Contents{
        int value();
    }
    
    class Parce{
        public Contents getContents(){
            return new Contents(){//匿名内部类:创建一个继承于Contents的匿名类的对象
                private int i = 5;
                public int value(){return i;}
            };
        }
    }
    public class Test{
        public static void main(String[] str){
            Parce p = new Parce();
            Contents c = p.getContents();
        }
    }

    实际上上面的匿名内部类结构等价于:

    class Parce{
        class MyContents implements Contents{
            private int i = 5;
            public int value(){return i;}
        }
    
        public Contents getContents(){
            return new MyContents();
        }
    }

    匿名内部类初始化操作怎么处理
    因为没有名字,所以不可能有构造器,所以我们利用实例初始化来做到和构造器相同的效果。

    abstract class Base{
        public Base(int i){
            System.out.println("Base:i = " + i);
        }
        
        public abstract void f();
    }
    
    class Base1{
    }
    
    public class Test{
        //i只是传递给匿名内部类的基类的构造器,没有在匿名内部类中使用,所以i不用时final
        //如果在匿名内部类中使用参数就必须是final
        public static Base getBase(int i){
            return new Base(i){//匿名内部类
                {//内部类的实例初始化
                    System.out.println("inside instance Base");
                }
                
                public void f(){
                    System.out.println("Test f fun");
                }
            };        
        }
        
        //如果在匿名内部类中使用参数就必须是final来修饰传入的参数
        public Base1 testBase1(final int i){
            return new Base1(){
                private int j =i;
                public int getLabel(){return j;}
            };
        }
        public static void main(String[] str){
            Base b = getBase(47);
            b.f();
        }
    }

    //
    输出:
    Base:i = 47
    inside instance Base
    Test f fun

    嵌套类(static内部类)和普通内部类区别
    (1) 普通内部类隐式地保存了一个引用,指向创建它的外围对象(特殊的this引用),而嵌套类没有
    (2) 要创建嵌套类的对象,并不需要其外围类的对象
    (3) 不能从嵌套类的对象中访问非static的外围类对象
    (4) 普通内部类不能有static数据和字段,但是嵌套类可以有。

    内部类使用的必要性
    1每个内部类都能独立继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。相对外围类继承接口,共享性好很多。
    2接口解决了部分问题,而内部类有效的实现了”多重继承”

    特性
    1. 内部类可以有多个实例,每个实例都有自己的状态信息,并且与外围类对象的信息相互独立。
    2. 在单个外围类中,可以让多个内部类以不同的方式实现同一个接口或继承同一个类
    3. 创建内部类对象的时刻并不依赖外部类对象的创立。
    4. 内部类没令人迷惑的”is-a”关系


    使用局部内部类替代匿名内部类的情况
    1.需要一个已命名的构造器或者需重载构造器,而匿名内部类只能实例初始化
    2.需要不止一个该内部类的对象

    内部类标示符:
    一个类就会产生一个.class文件。
    Test.class //Test类
    Test$1.class //匿名内部类会产生一个简单的数字作为标示符
    Parce$Pdestination.class //局部内部类直接在$后面加上类名就Ok了

  • 相关阅读:
    一个苏州IT人的5年挨踢经历经历篇(之二)
    【Java】Collection 集合框架概述
    【Java】Collection子接口:其二 Set 组接口
    【Java】【常用类】Calendar 日历类
    【郝斌C ST】01
    【Java】【常用类】Date 日期类
    【Java】Enumeration Class 枚举类
    【Java】Properties 配置信息类
    【Java】Generic 泛型
    【Java】Annotation 注解
  • 原文地址:https://www.cnblogs.com/lijunamneg/p/2893161.html
Copyright © 2011-2022 走看看