Android学习之View.OnClickListener()接口实现原理:匿名内部类

tech2022-12-19  118

文章目录

前言一、内部类是什么二、内部类的分类 1.非静态内部类2.静态内部类3.局部内部类4.匿名内部类总结

前言

在学习Android的过程中遇到了一个看不懂的地方,于是搜了一下,才发现是匿名内部类的用法,于是就顺便学习一下内部类。

下面是对View.OnClickListener接口的实现

mBtn1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) {//跳转到演示界面 Intent intent=new Intent(MainActivity.this,MainActivityTest1.class); startActivity(intent); } });

mBtn1为Button类,看一下其中的 setOnClickListener()方法里参数为View.OnClickListener

public void setOnClickListener(@Nullable View.OnClickListener l) { throw new RuntimeException("Stub!"); }

再找到View.OnClickListener,发现其为View类里定义的一个接口

public interface OnClickListener { void onClick(View var1); }

 

一、内部类是什么

一个类放在另一个类里的内部定义,这个定义在其他类内部的类就叫做内部类,包含内部类的类就叫做外部类。

二、内部类有哪些

1.非静态内部类

public class Outer {//外部类     private int a=0;     public void showInner() {         //System.out.println(Inner.a);编译报错,无法直接访问内部类的成员         System.out.println(new Inner().a);//正确,通过创建实例访问         new Inner().showOuter();//正确,通过创建实例访问     }     public class Inner{//非静态内部类         private int a=1;         //private static int a=1;---编译报错,非静态内部类不能定义静态成员         /*private static void name() {---编译报错                      }*/         private void showOuter(){//这个方法用以判断变量优先级             int a=2;             System.out.println("a="+a);//a=2             System.out.println("a="+this.a);//a=1             System.out.println("a="+Outer.this.a);//a=0         }     }     public static void main(String[] args) {         // TODO Auto-generated method stub         Outer outer=new Outer();         //Inner oInner=new Inner();编译报错,静态方法无法访问非静态内部类         outer.showInner();     } }

非静态内部类的构造器必须通过器外部类对象调用!!!

public class SubClass extends Outer.Inner {

    public SubClass(Outer out) {         // TODO Auto-generated constructor stub         out.super();     } }

2.静态内部类

外部类访问静态内部类:1.外部类静态方法可以通过(类名.成员)的形式访问静态内部类的成员和方法.2.外部类非静态方法通过(类名.成员)的形式访问静态内部类的静态成员和静态方法,只能通过实例访问静态内部类的非静态的成员和方法

静态内部类访问外部类:只能访问外部类的静态成员和方法

public class Outer {//外部类     private int a=0;     private static int b=0;     public void showInner() {         //System.out.println(Inner.a);//编译报错,无法直接访问内部类的非静态成员         System.out.println(Inner.b);//正确         System.out.println(new Inner().a);//正确,通过创建实例访问         //new Inner().showOuter();//正确,通过创建实例访问         Inner.name();//访问静态内部类的静态方法     }     private static class Inner{//静态内部类         private int a=1;         private static int b=1;         private static void name() {             //System.out.println(a);静态不能访问非静态             System.out.println("b="+b);         }         private void showOuter(){             int a=2;             System.out.println("a="+a);//a=2             System.out.println("a="+this.a);//a=1             //System.out.println("a="+Outer.this.a);             //静态内部类无法访问外部类的非静态成员             System.out.println("b="+Outer.b);         }     }     public static void main(String[] args) {         // TODO Auto-generated method stub         Inner inner=new Inner();//编译报错,外部类静态方法无法访问非静态内部类         System.out.println(inner.a);//外部类静态方法可以访问非静态内部类成员和方法         System.out.println(inner.b);         inner.name();         inner.showOuter();         } }

静态内部类的非静态内部类类似于外部类的成员

3.局部内部类:

放在方法里定义的内部类,作用域仅限于方法,没什么意义,很少用。

4.匿名内部类

适合创建那种只需要用一次的类,实现匿名内部类的结构如下:

new 实现的接口()| 父类构造器(参数) {     //匿名内部类的实体部分 }

匿名内部类必须继承一个父类或实现一个接口,但最多只能继承一个父类或实现一个接口(常用来实现接口)

规则:

1.匿名内部类不能是抽象类,因为系统在创建匿名内部类时,会立即创建匿名内部类的对象,因此不允许将匿名内部类定义为抽象类。

2.匿名内部类不能定义构造器。由于匿名内部类没有类名,所已无法定义构造器,但匿名内部类可以定义初始化块,可以通过实例初始化(此处需要去了解什么是实例初始化)来完成构造器需要完成的事情。

abstract class Fruit{     private String  name;     public abstract  double price();     public Fruit(String name)     {         this.name=name;     }     public String getName()     {         return name;     } } public class Shop {     public void test(Fruit fruit)     {         System.out.println(fruit.getName()+":"+fruit.price());     }     public static void main(String[] args) {         // TODO Auto-generated method stub         Shop shop=new Shop();         shop.test(new Fruit("apple") {//抽象类不是不能被实例化???请指教             @Override             public double price() {                 // TODO Auto-generated method stub                 return 100;             }         });     } }


总结

好好学习,天天向上!

最新回复(0)