• Java 内部类


    内部类

      · 内部类可以是静态static的,也可用public,default,protected和private修饰

      · 内部类是一个编译时的概念,一旦编译成功就会成为完全不同的两类。如下编译完成后出现Computer.class和Computer$CPU.class两类。
         所以内部类的成员变量或方法名可以和外部类的相同。

    使用内部类的好处:

      · 解决多重继承的问题,当一个类需要实现两个父类,可以使用内部类实现其中一个类。

      · 使用内部类可以非常方便的编写事件驱动程序,可用内部类实现接口方法

      · 如果某个类与实现的接口中拥有同名同参的函数,可用内部类实现接口,这样外部类和内部类同时存在相同名称和参数列表的函数

    1. 成员内部类

      · 成员内部类不能含有static的变量和方法。因为成员内部类需要先创建了外部类,才能创建它自己的

      · 成员内部类要引用外部类对象时,使用Computer.this来表示外部类对象。外部类要访问内部类的所有成员变量/方法,则需要通过内部类的对象来获取new CPU().timeout

    class Computer {
        private int timeout = 100;
        
        public void work(int timeout) {
            new CPU().process(timeout);
        }
        
        public CPU getCPU() {
            return new CPU();
        }
        
        public class CPU {
            public int timeout = 200;
            
            public void process(int timeout) {
                System.out.println("局部变量: " + timeout);
                if(timeout == 300){
                    System.out.println("内部类变量: " + this.timeout);
                    System.out.println("外部类变量: " + Computer.this.timeout);
                }
            }
        }
    
    }
    
    public class Test {
        public static void main(String[] args) {
            Computer cp = new Computer();
            System.out.println("a. 使用外部类对象cp 直接调用外部类方法");
            cp.work(300);
            
            System.out.println("b. cp.new 获取内部类对象,并调用内部类方法 ");
            Computer.CPU cpu1 = cp.new CPU();    // 如果CPU类是private的, 那么该语句会发生错误,在Computer外部无法获取到内部类CPU,只能在Computer中操作CPU类
            cpu1.process(400);
            
            System.out.println("c. cp.getCPU()获取内部类对象,并调用内部类方法 ");
            Computer.CPU cpu2 = cp.getCPU();    
            cpu2.process(500);
        }
    }

    运行结果

    a. 使用外部类对象cp 直接调用外部类方法
      局部变量: 300
      内部类变量: 200
      外部类变量: 100
    b. cp.new 获取内部类对象,并调用内部类方法
      局部变量: 400
    c. cp.getCPU()获取内部类对象,并调用内部类方法
      局部变量: 500

    2. 局部内部类

      局部内部类,是指内部类定义在方法和作用域内。局部内部类也像别的类一样进行编译,但只是作用域不同而已,只在该方法或条件的作用域内才能使用,退出这些作用域后无法引用的。

    class Computer {
        
        public void work(boolean flag) {
            
            class IntelCPU implements CPU{
                public void process() {
                    System.out.println("内部类IntelCPU 定义在方法内");
                }
            }
            new IntelCPU().process();
            
            if(flag){
                class AMDCPU implements CPU{
                    public void process() {
                        System.out.println("内部类AMDCPU 定义在作用域内");
                    }
                }
                new AMDCPU().process();
            }
        }
    }
    
    interface CPU{
        public void process();
    }
    
    public class Test {
        public static void main(String[] args) {
            Computer cp = new Computer();
            cp.work(true);
        }
    }

    运行结果

        内部类IntelCPU 定义在方法内
        内部类AMDCPU 定义在作用域内

    3. 匿名内部类
    class Computer {
        
        public CPU getCPU() {
            return new CPU(){
                public void process() {
                    System.out.println("匿名内部类");
                }
            };
        }
    }
    
    abstract class CPU{
        public abstract void process();
    }
    
    public class Test {
        public static void main(String[] args) {
            Computer cp = new Computer();
            cp.getCPU().process();
        }
    }

     

    匿名内部类,局部内部类的方法和作用域中使用的外部变量必须是 final 的,因为内部类会自动拷贝外部变量的引用,用 final修饰该引用可避免:
      a) 外部方法修改引用,而导致内部类得到的引用值不一致
      b) 内部类修改引用,而导致外部方法的参数值在修改前和修改后不一致。

    class Computer {
    
        public CPU getCPU(final int timeout, int type) {  // timeout变量在匿名内部类中使用,应设为final类型
            
            return new CPU(timeout, type) {
                private int timeout_ = timeout;  // 匿名内部类的成员变量不能和外部传递的参数名一样
                public int getTimeOut() {
                    return timeout_;
                }
            };
        }
    }
    
    abstract class CPU {
        CPU(int timeout, int type) {
        }
        public abstract int getTimeOut();
    }
    
    public class Test {
        public static void main(String[] args) {
            Computer cp = new Computer();
            CPU cpu = cp.getCPU(100, 1);
            System.out.println(cpu.getTimeOut());
        }
    }
    
    
     
    4. 嵌套内部类
        · 嵌套内部类就是修饰为static的内部类,不需要内部类对象和外部类对象之间的联系。我们可以直接引用Computer.CPU,即不需要创建外部类,也不需要创建内部类。
        · 普通内部类不能有static数据和static属性,也不能包含嵌套类,但嵌套类可以。而嵌套类不能声明为private,一般声明为public。
    class Computer {
        
        public static class CPU{
            public void process() {
                System.out.println("嵌套内部类");
            }
        }
    }
    
    public class Test {
        public static void main(String[] args) {
            Computer.CPU cpu = new Computer.CPU();
            cpu.process();
        }
    }
  • 相关阅读:
    [原] 秋叶原随景
    ReportViewer不连接数据库,自定义DataSet导出到报表
    【程序人生】一个程序员对学弟学妹建议(转)
    c#钩子学习笔记(一)
    解决关于多客户端操作数据库并发问题
    SQL Server 存储过程
    有关抽奖的一个算法
    c#发送邮件含附件
    CrystalReport不连接数据库,自定义DataSet导出到水晶报表
    c#钩子学习笔记(二)
  • 原文地址:https://www.cnblogs.com/anxiao/p/6739794.html
Copyright © 2020-2023  润新知