zoukankan      html  css  js  c++  java
  • 内部类

    把一个类放在一个类内部定义,这个定义在其他类内部的类就被称为内部类。

    1. 内部类作用如下:

      1)内部类提供了更好的封装,把内部类应藏在外部类之内,不允许同一个包内的其他类访问该类。假设该类在脱离了某个类之外没有任何意义,可以将该类定义在依赖的类里。

      2)内部类成员可以直接访问外部的私有数据,因为内部类被当成外部类的成员,同一个类的成员之间可以互相访问。

      3)匿名内部类适合用于创建那些仅需要一次使用的类。

    2. 非静态内部类:

      先创建外部类对象,再通过外部类对象创建内部类。Java不允许在非静态内部类重定义静态成员,静态方法,也不能有静态初始化块。

    public class OutClass {
        private String a;
        private static String name;
        public void f(){}
        public static void fn(){}
        class InClass{
            private String b;
            public InClass(){
                b=a;
                b=name;
                f();
                fn();
            }
        }
        public static void main(String[] args) {
            OutClass.InClass inClass = new OutClass().new InClass();
        }
    }

    3. 静态内部类:
      如果用static来修饰一个内部类,它就属于这个外部类本身,而不属于某个外部类实例。根据静态成员不能访问非静态成员原则,静态内部类也不能访问外部类的非静态成员。

    public class OutClass {
        private int a;
        private static String name;
        public OutClass(){}
        public void  f() {}
        public static void fn(){}
        public static class InClass{
            private int b;
            private static String c;
            public InClass(){            
                //b=a; //不能访问外部类的非静态变量
                c=name;
                //f(); //不能使用外部类的非静态方法
                fn();
            }
        }
        public static void main(String[] args) {
            OutClass.InClass inClass =new InClass();
        }    
    }

    4.接口内部类:

      接口内部类默认使用public staic修饰符。

    5. 局部内部类:

      如果把一个内部类放在方法里定义,这个类就是一个局部内部类。对于局部成员,使用static修饰毫无意义,所以局部内部类不能用static修饰

    public class Test {
        public static void main(String[] args) {
            abstract class InnerBase{
               int a;
               public abstract void fn();
            }
            class Inner extends InnerBase{
                public  void fn(){}
            }
            InnerBase inner = new Inner();
        }
    
    }

    6.匿名内部类
      匿名类适合创建那种只需要一次使用的类。你明年内部类必须集成一个父类或实现一个接口。必须实现父类或接口的所有抽象方法。

      如果匿名内部类想要访问外部类的变量,则必须使用final修饰符来修饰外部类的局部变量。

    public class Test {
        interface Product{
            public String getName();
        }
        public abstract class Pro{
            public abstract void printName();
        }
        public static void main(String[] args) {
            System.out.println(new Product(){
                    {
                        System.out.println("实现接口的匿名内部类初始化!");
                    }
                    public String getName(){
                        return "computer";
                    }
                }.getName());
            
            final String nameString = "Keyboard";
            new Test().new Pro(){
                    {
                        System.out.println("继承类的匿名内部类初始化!");
                    }
                    public void printName(){
                        System.out.println(nameString);;
                    }
                }.printName();      
        }
    }

     7.闭包和回调:

    闭包是一种能被调用的对象,它保存了创建它的作用域信息。非静态内部类不仅记录了外部类的详细信息,还保留了一个创建非静态内部类对象引用,还可直接调用外部类的private成员,因此可以把非静态内部类当成面向对象领域的闭包。

    以下代码为实际应用:

    public class test {
        public abstract class Teachable{
            abstract void work();
        }
        public class Programmer{    
            public void work(){
                System.out.println("coding");
            }
        }
        public class TeachableProgrammer extends Programmer{
            private void teach() {
                System.out.println("teaching");
                
            }
            private class Closure extends Teachable{
    
                @Override
                public void work() {
                    teach();
                }            
            }
            
            public Teachable getCallBackReference(){
                return new Closure();
            }
        }
        public static void main(String[] args) {
            TeachableProgrammer tProgrammer = new test().new TeachableProgrammer();
            tProgrammer.work();
            tProgrammer.getCallBackReference().work();
            
        }
    }

    以上内容来自学习《疯狂JAVA讲义》

  • 相关阅读:
    PHP array_intersect_uassoc
    PHP array_intersect_key
    PHP array_intersect_assoc
    PHP array_flip
    PHP array_filter
    PHP array_fill
    PHP array_fill_keys
    Android4.0-Fragment框架实现方式剖析
    Fragment 生命周期
    WebView
  • 原文地址:https://www.cnblogs.com/wxlovewx/p/5231215.html
Copyright © 2011-2022 走看看