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了

  • 相关阅读:
    python 并发编程 多线程 event
    python 并发编程 多线程 定时器
    python 并发编程 多线程 信号量
    linux top 查看CPU命令
    python 并发编程 多线程 GIL与多线程
    python 并发编程 多线程 死锁现象与递归锁
    python 并发编程 多线程 GIL与Lock
    python GIL全局解释器锁与互斥锁 目录
    python 并发编程 多线程 GIL全局解释器锁基本概念
    执行python程序 出现三部曲
  • 原文地址:https://www.cnblogs.com/lijunamneg/p/2893161.html
Copyright © 2011-2022 走看看