zoukankan      html  css  js  c++  java
  • 关于接口配合匿名内部类使用的问题讲究

    匿名内部类也就是没有名字的内部类,正因为没有名字,所以匿名内部类只能使用一次,

    它通常用来简化代码编写,但使用匿名内部类还有个前提条件:必须继承一个父类或实现一个接口。

    使用匿名内部类的注意事项:

    匿名内部类也就是没有名字的内部类

    正因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码编写

    但使用匿名内部类还有个前提条件:必须继承一个父类或实现一个接口

    以上方式就是接口配合匿名内部类来使用。

    在java中匿名内部类我们可以使用使用lamda表达式来写。

    匿名内部类可以实现一个接口的对象,注意是接口的对象,直接实现接口的抽象方法(所有),然后使用,因为没有经过“类”这一环节,所以叫匿名类,即认为这一对象属于某个不具名的类,这样的过程自然就不能用这个“不具名的类”再产生其他对象,故只能产生这一个对象。

     函数式接口,首先是一个接口,然后接口里只有一个抽象方法,其他随意,抽象方法只能有一个。这时可以用lambda表达式来创建函数式接口,lambda表达式负责实现那个唯一的抽象方法。

    下面是一个总结 很好的一篇文章:

    https://www.cnblogs.com/xiao-chuan/p/6014752.html

    内部类的分类和使用
    1、成员内部类: 即作为外部类的一个成员存在,与外部类的属性、方法并列。注意:成员内部类中不能定义静态变量,但可以访问外部类的所有成员。值得注意的是成员内部类编译成功后会生成的两个不同的类(.class)
    成员内部类的优点:
    1)、内部类作为外部类的成员,可以访问外部类的私有成员或属性。(即使将外部类声明为PRIVATE,但是对于处于其内部的内部类还是可见的。)
    2)、用内部类定义在外部类中不可访问的属性。这样就在外部类中实现了比外部类的private还要小的访问权限。
     
    复制代码
    package one;
    
    public class Outer{
        private static int outer_i = 1;
        private int k=20;
        public static void outer1(){
           //...
        }
        
        //成员内部类
        class Inner{
            int j=100;//内部类中外部类的实例变量可以共存
            int inner_i=1;
            void inner1(){
               System.out.println(outer_i);//外部类的变量如果和内部类的变量没有同名的,则可以直接用变量名访问外部类的变量
               System.out.println(j);//在内部类中访问内部类自己的变量直接用变量名
               System.out.println(this.j);//也可以在内部类中用"this.变量名"来访问内部类变量
               //访问外部类中与内部类同名的实例变量可用"外部类名.this.变量名"。
               System.out.println(k);//外部类的变量如果和内部类的变量没有同名的,则可以直接用变量名访问外部类的变量
               outer1();
            }
        }
        //外部类的非静态方法访问成员内部类
        public void outer2(){
           Inner inner = new Inner();
           inner.inner1();
        }
        //外部类的静态方法访问成员内部类,与在外部类外部访问成员内部类一样
        public static void outer3(){
           Outer out = new Outer();//step1 建立外部类对象
           Inner inner=out.new Inner();//step2 根据外部类对象建立内部类对象
           inner.inner1();//step3 访问内部类的方法
        }
        public static void main(String[] args){
            outer3();
        }
    }
    复制代码
     
    
    2、局部内部类: 即在方法中定义的内部类,与局部变量类似,在局部内部类前不加修饰符public或private,其范围为定义它的代码块。
    
     
    
    public class Outer {
    
        public void say(){
            System.out.println("关门说真话!");
        }
    }
    复制代码
    public class Test {
    
        public void ting(){
            class MiMi extends Outer{//定义一个局部的内部类,继承Outer方法
                //……
            }
            
            new MiMi().say();//调用局部内部类中继承的say方法
            
            System.out.println("别人都不知道");
        }
        
        public static void main(String[] args) {
            new Test().ting();
        }
    }
    复制代码
     
    
    3、静态内部类: 静态内部类定义在类中,任何方法外,用static定义。注意:静态内部类中可以定义静态或者非静态的成员
    
    复制代码
    package three;
    
    public class StaticTest {  
        private static String name="abc";
        private String sex="男";
        
        static class Person{
            private String age = "18";//内部私有成员
            public String heigth = "180";//内部类公有成员
            public void display(){
                //System.out.println(sex);//报错,不能直接访问外部类的非静态成员
                System.out.println(name);//只能直接访问外部类的静态成员
                System.out.println(age);//访问本内部类成员。
            }  
        }
        
        public void testone(){
            Person person = new Person();
            person.display();
            //System.out.println(heigth);//报错,是因为不可以直接访问内部类私有成员
            //System.out.println(age);//报错,是因为不可以直接访问内部类公有成员
            System.out.println(person.age);//可以访问内部类的私有成员
            System.out.println(person.heigth);//可以访问内部类的公有成员
        } 
        
        public void testtwo(){
            StaticTest st = new StaticTest();
            System.out.println(name);
            System.out.println(sex);
            //System.out.println(age);//不可以直接访问内部类的成员
            //System.out.println(heigth);//不可以直接访问内部类的成员
        }
        
        public static void main(String[] args) { 
            //调用StaticTest
            StaticTest staticTest = new StaticTest();  
            staticTest.testone(); 
            staticTest.testtwo();
        }  
    }  
    复制代码
     
    4、匿名内部类: 匿名内部类是在抽象类和接口的基础之上发展起来的。匿名内部类如果继承自接口,必须实现指定接口的方法,且无参数 。匿名内部类如果继承自类,参数必须按父类的构造函数的参数传递
    匿名内部类的特点:
    1),一个类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的事先或是覆盖。
    2),只是为了获得一个对象实例,不需要知道其实际类型。
    3),类名没有意义,也就是不需要使用到。
    复制代码
    package three;
    
    abstract class parent {
    
    public abstract void like();
    }
    
    public class Demo {
        public static void main(String[] args) {
            parent pt = new parent(){
                public void like(){
                    System.out.println("吃饭睡觉打豆豆。。。");
                }
            };
            pt.like();
        }
    }
    复制代码
     
    匿名类与内部的联系与区别:
     
    按所在位置可以分为两大类:
          1、在类的方法中
                特点:
                a、可以访问宿主类的所有元素 ;
                b、保存宿主类对象的引用,创建对象时必须有宿主类对象;
                c、 不能有静态数据;
     继续划分:
                A、本地内部类;
                B、匿名内部类
     两者的区别在于本地内部类有构造方法,而匿名内部类只能实例初始化;
          2、在类或接口作用域中;
                A、普通内部类
                B、静态内部类
     
     
    
    

      

    补充理解:

    1.什么是类,类可以理解为一个对象。(那么各位友友们思考,我们为什么需要一个对象?因为我们需要这个对象去完成某中事情)
    
    2.什么是内部类呢?内部类就是在类的内部创建一个类,为什么我们要在类的内部创建一个类呢?不直接在类的外面直接创建另一个类呢?何必这么麻烦(因为我定义的这个内部类仅仅在本类中是有用的,其他的类使用完全没有意义,所以我就定义在一个类的内部仅仅供给这个类来使用。)
    
    3.什么是匿名内部类呢?就更有意思了,就是所我定义的这个类在本类里面我就都认为他是没有意义的,因为我只需要提供给本类中的一个方法来使用,其他方法不需要使用嘛。(所以我们就不在类的内部定义了,直接在一个方法中的返回符(;)之前我们就给他new ()并写出来,这样这个类就仅仅提供给这个方法使用)
    
    
    什么时候使用匿名内部类,什么时候使用匿名内部类呢?
    
    就是定义的这个类如果提供给两个或者两个以上的方法使用时就是用内部类、如果仅仅提供给一个方法使用时可以使用匿名内部类
    

      总结:

    内部类总结:
    1.内部类作为外部类的一个特殊的成员来看待,因此它有类成员的封闭等级:private ,protected,默认(friendly),public 它有类成员的修饰符:   static,final,abstract
    2.非静态内部类nested inner class,内部类隐含有一个外部类的指针this,因此,它可以访问外部类的一切资源(当然包括private)外部类访问内部类的成员,先要取得内部类的对象,并且取决于内部类成员的封装等级。非静态内部类不能包含任何static成员.
    3.静态内部类:static inner class,不再包含外部类的this指针,并且在外部类装载时初始化. 静态内部类只能访问外部类static成员. 外部类访问静态内部类的成员:static成员:类名.成员;非static成员:对象.成员
    4.对于方法中的内部类或块中内部类只能访问块中或方法中的final变量。

     

  • 相关阅读:
    Linux 下判断磁盘是ssd还是hdd
    Ceph rgw COR测试
    nfs 挂载选项
    【Linux命令】dmsetup--device mapper 管理工具(更底层的管理工具)
    Device Mapper 存储介绍
    easyui combotree 默认 初始化时就选中
    EasyUI 添加tab页(iframe方式)(转)
    EasyUI DataGrid 配置参数
    EasyUI 后台接受DataGrid传来的参数
    (转)combogrid的代码实例
  • 原文地址:https://www.cnblogs.com/fengli9998/p/9766391.html
Copyright © 2011-2022 走看看