文章目录
1. 再谈接口
1.1 定义接口
定义接口的一般格式如下:
[public] interface 接口名 [extends 父接口名]{
[public] [static] [final] 数据类型 常量名 = 常量;//常量声明
[public] [abstract] 返回类型 方法名(参数列表);//抽象方法声明
}
- 接口可以抽象出重要的行为标准,该行为标准用抽象方法来表示。接口中只有常量和抽象方法;
- 接口中的变量自动都是
public
,static
,final
,可以省略 ; - 接口中的方法自动为
public abstract
,可以省略; - 接口编译后也产生class文件;
- 接口中没有构造方法。 也就不能通过
new
构建接口的对象,只能像抽象类一样标示数据类型; - 接口也具有继承性,可以继承父接口的所有属性和方法。
实现接口类的的格式形如:
class Test implements Printable,Addable{
@Override
void getValue(int x){
//...
}
}
1.2 接口回调
可以把实现某一接口的类创建的对象的赋值给该接口声明的接口变量中,即接口变量存放实现该接口的类的对象的引用,从而接口变量就可以回调类实现的接口方法。
接口回调是实现多态的关键技术。若干个不同的类通过实现同一接口,从而具有相同名称的方法,但方法的具体内容 (实现) 不同。
例如:
Com com;//声明接口对象, Com是一接口
ImpleCom obj= new ImpleCom();//实现接口的类对象
com = obj; //接口回调
1.3 将接口作为参数
如果一个方法的参数是接口类型,则可以将任何实现该接口的类的实例的引用传递给该接口参数,那么接口参数就可以回调类实现的接口方法。例如,在1.2中若有方法的参数是Com
接口类型,则调用该方法时,可将obj
作为参数。
再例如,对于View
类的方法public void setOnClickListener(OnClickListener l)
,其接受一个OnClickListener
接口类型的参数l
,于是调用该方法时,可将某OnClickListener
的实现类对象作为参数。下面代码中,由于MainActivity
通过实现onClick()
方法实现了OnClickListener
接口,于是该类的实例对象this
可作为setOnClickListener(OnClickListener l)
的参数。
1.4 匿名类
-
Java 中可以实现一个类中包含另外一个类,且不需要提供任何的类名直接实例化。匿名类没有名字,以不可能用匿名类声明对象,但可以直接用匿名类创建一个对象。不能被第二次使用,只能在创建时用
new
语句来声明它们。匿名类可以继承类的方法也可以重写类的方法;不可以声明static
成员变量和static
方法。 -
匿名类的主要用途就是向方法的参数传值,并且可以使代码更加简洁。
-
匿名类的应用主要体现在与类有关的匿名类和与接口有关的匿名类。
与类有关的匿名类:
class AnoTest{
int num=10;
void Show() {
System.out.println("Function in super,num="+num+";Calculate()="+Calculate());
}
int Calculate() {
return num*num;
}
}
public class AnoClass {
public static void main(String[] args) {
AnoTest ano1 = new AnoTest();
AnoTest ano2 = new AnoTest(){
//匿名类可以继承父类的方法,也可以重写父类的方法
void Show() {
num=20;
System.out.println("Function in extends,num="+num+";Calculate()="+Calculate());
}
};
ano1.Show();
ano2.Show();
System.out.println(ano1.getClass());
System.out.println(ano2.getClass());
}
}
//Function in super,num=10;Calculate()=100
//Function in extends,num=20;Calculate()=400
//class demo.AnoTest
//class demo.AnoClass$1
1.5 接口的理解
Collection工具类的各个接口
2. Android事件的监听
2.1 事件监听机制
事件监听机制中由事件源,事件,事件监听器三类对象组成。
处理流程如下:
- 为某个事件源(组件)设置一个监听器,用于监听用户操作
- 用户的操作,触发了事件源的监听器
- 生成了对应的事件对象
- 将这个事件源对象作为参数传给事件监听器
- 事件监听器对事件对象进行判断,执行对应的事件处理器(对应事件的处理方法)
2.2 监听器接口
对于一个监听器,其必须满足处理该事件的能力,即实现对应接口。例如,单击事件(Click)的监听器必须实现OnClickListener接口,该接口规定了监听器必须提供onClick()
方法及方法的规格。于是,在View类的各个组件的注册监听器方法中(如setOnClickListener()
),传递的参数均为实现对应接口的类对象。
3. 监听器的几种注册方法
- 使用内部匿名类,形如
button.setOnClickListener(new OnClickListener(){...});
,在匿名类中实现onClick()
方法; - 将活动作为事件监听器,Activity实现接口,形如
public class MainActivity extends Activity implements OnClickListener{...}
,在MainActivity
中定义onClick()
方法; - 直接绑定到标签,在活动中定义一个事件处理方法,然后在对应xml布局文件中为组件设置触发事件:如设置属性:
onclick = "myclick"
,表示将该组件的单击事件的监听器注册为myclick()
方法。(不具有普适性,只有单击Click事件有对应属性,如长按LongClick则没有。)
4. 实例: 为Button组件实现并注册监听器
本实例中,对于4个Button组件,分别使用3.中的3中方法注册监听器。
4.1 java文件: MainActivity.java
public class MainActivity extends AppCompatActivity implements OnClickListener {
Button btn1, btn2, btn3, btn4;
EditText editTxt1, editTxt2;
TextView txt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn1 = findViewById(R.id.button);
btn2 = findViewById(R.id.button2);
btn3 = findViewById(R.id.button3);
btn4 = findViewById(R.id.button4);
editTxt1 = findViewById(R.id.editTextNumber);
editTxt2 = findViewById(R.id.editTextNumber2);
txt = findViewById(R.id.textView);
btn1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
int a = Integer.parseInt(editTxt1.getText().toString());
int b = Integer.parseInt(editTxt2.getText().toString());
int ans = a * b;
txt.setText("Ans(Multi): " + ans);
}
});
btn2.setOnClickListener(this);
btn3.setOnClickListener(this);
}
@Override
public void onClick(View v) {
int a = Integer.parseInt(editTxt1.getText().toString());
int b = Integer.parseInt(editTxt2.getText().toString());
int ans;
switch (v.getId()) {
case R.id.button2:
ans = a + b;
txt.setText("Ans(Add): " + ans);
break;
case R.id.button3:
ans = a - b;
txt.setText("Ans(Sub): " + ans);
break;
default:
break;
}
}
public void myButtonClick(View v) {
int a = Integer.parseInt(editTxt1.getText().toString());
int b = Integer.parseInt(editTxt2.getText().toString());
String ans = "Ans(Link): " + a + b;
txt.setText(ans);
}
}
4.2 布局文件: activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.458"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.46" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.208"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.631" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button2"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.725"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.631" />
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button3"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.208"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.767" />
<Button
android:id="@+id/button4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="myButtonClick"
android:text="Button4"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.725"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.767" />
<EditText
android:id="@+id/editTextNumber"
android:layout_width="132dp"
android:layout_height="56dp"
android:ems="10"
android:hint="Num1..."
android:inputType="number"
android:minHeight="48dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.113"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.22" />
<EditText
android:id="@+id/editTextNumber2"
android:layout_width="132dp"
android:layout_height="56dp"
android:ems="10"
android:hint="Num2..."
android:inputType="number"
android:minHeight="48dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.785"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.22" />
</androidx.constraintlayout.widget.ConstraintLayout>
参考链接:
[1]匿名类 - https://www.cnblogs.com/progor/p/8644634.html
[2]匿名类 - https://www.runoob.com/java/java-anonymous-class.html
[3]将接口作为参数 - https://blog.csdn.net/blackmanren/article/details/9252437
[4]将接口作为参数 - https://www.jianshu.com/p/9acc1ff3a5b6
[5]事件监听 - https://www.runoob.com/w3cnote/android-tutorial-listen-event-handle.html
[6]注册监听器三种方法 - https://blog.csdn.net/qq_43175022/article/details/106562090
[7]注册监听器三种方法2 - https://blog.csdn.net/rongwenbin/article/details/90767720