• JAVA内部类


    一、定义
    放在一个类的内部的类我们就叫内部类。
    二、 作用
    1.内部类可以很好的实现隐藏
    一般的非内部类,是不允许有 private 与protected权限的,但内部类可以
    2.内部类拥有外围类的所有元素的访问权限
    3.可是实现多重继承
    4.可以避免修改接口而实现同一个类中两种同名方法的调用。
    三、例子
    1.实现隐藏
    平时我们对类的访问权限,都是通过类前面的访问修饰符来限制的,一般的非内部类,是不允许有 private 与protected权限的,但内部类可以,所以我们能通过内部类来隐藏我们的信息。可以看下面的例子:

    interface InterfaceTest
    {
        void test();
    }
    class Example {
        //内部类,访问修饰符是private
        private class InsideClass implements InterfaceTest
        {
             public void test()
             {
                 System.out.println("这是一个测试");
             }
        }
        public InterfaceTest getIn()
        {
            return new InsideClass();
        }
    }
    public class TestExample {
    
         public static void main(String args[])
         {
            Example a=new Example();
            //从这段代码里面我只知道Example的getIn()方法能返回一个InterfaceTest实例
            //但我并不知道这个实例是这么实现的。而且由于InsideClass 是private的,
            //所以我们如果不看代码的话根本看不到这个具体类的名字,所以说它可以很好的实现隐藏。
            InterfaceTest a1=a.getIn();
            a1.test();
         }
    }

    2.可以无条件地访问外围类的所有元素,静态内部类除外,匿名内部类除外,静态内部类只能访问外部类的静态成员变量,而匿名内部类只能访问用final修饰的变量。
    3.可以实现多重继承
    它是内部类存在的最大理由之一。正是由于他的存在使得Java的继承机制更加完善。大家都知道Java只能继承一个类,它的多重继承在我们没有学习内部类之前是用接口来实现的。但使用接口有时候有很多不方便的地方。比如我们实现一个接口就必须实现它里面的所有方法。而有了内部类就不一样了。它可以使我们的类继承多个具体类或抽象类。大家看下面的例子:

    class Example1 {
    
       public String name()
       {
           return "liutao";
       }
    }
    class Example2 {
    
        public int age()
        {
            return 25;
        }
    } 
    public class MainExample
    {
       private class test1 extends Example1
        {
            public String name()
            {
              return super.name();
            }
        }
        private class test2 extends Example2
        {
           public int age()
           {
             return super.age();
           }
        }
       public String name()
        {
        return new test1().name();
       }
       public int age()
       {
           return new test2().age();
       }
       public static void main(String args[])
       {
           MainExample mi=new MainExample();
           System.out.println("姓名:"+mi.name());
           System.out.println("年龄:"+mi.age());
       }
    }

    类三里面分别实现了两个内部类 test1,和test2 ,test1类又继承了Example1,test2继承了Example2,这样我们的类三MainExample就拥有了Example1和Example2的方法和属性,也就间接地实现了多继承。
    四、避免修改接口而实现同一个类中两种同名方法的调用。
    大家假想一下如果,你的类要继承一个类,还要实现一个接口,可是你发觉你继承的类和接口里面有两个同名的方法怎么办?你怎么区分它们??这就需要我们的内部类了。看下面的代码:

    interface Incrementable
    {
        void increment();
    }
    public class MyIncrement {
         //自己的方法
        public void increment()
        {
          System.out.println("Other increment()");
        }
        static void f(MyIncrement f)
        {
            f.increment();
        }
    }

    两个increment方法都是一样的,在看下面这个类要继承这两个类,如果不用内部类:

    public class Callee2 extends MyIncrement implements Incrementable
    {
          public void increment()
          {
                //代码,想问一下大家increment()这个方法是属于覆盖     MyIncrement这里的方法呢?
                //还是Incrementable这里的方法。我怎么能调到MyIncrement这里的方法?显然这是不好区分的。
                //而我们如果用内部类就很好解决这一问题了
           }
    }

    使用内部类:

    interface Incrementable
    {
     void increment();
    }
    class MyIncrement {
    
        public void increment()
        {
          System.out.println("Other increment()");
        }
        static void f(MyIncrement f)
        {
            f.increment();
        }
    
    }
    public class Callee2 extends MyIncrement
    {
        private int i=0;
        private void incr()
        {
           i++;
           System.out.println(i);
        }
        private class Closure implements Incrementable
        {
          public void increment()
          {
            incr();
          }
        }
        Incrementable getCallbackReference()
        {
            return new Closure();
        }
    }

    我们可以用内部类来实现接口,这样就不会与外围类的方法冲突了。

  • 相关阅读:
    linux文件锁flock【转】
    无尽的悲伤
    go的临时对象池--sync.Pool
    golang 小知识-持续更新中
    【转】Go Channels
    Golang文件名命名规则
    Parquet存储格式
    预装的Office2016,文件图标表显示以及新建失败问题解决 方法
    Gamma编码及Delta编码概述
    java web开发环境配置系列(二)安装tomcat
  • 原文地址:https://www.cnblogs.com/sunp823/p/5601404.html
Copyright © 2020-2023  润新知