0.前言
上一篇文章(Java知识6)我们讲解了继承、多态等知识点
今天我们讲两个重点:抽象类和接口若想要了解“类”的主要知识,可以去看前面的文章
《[Java]开发安卓,你得掌握的Java知识5》
《[Java]开发安卓,你得掌握的Java知识4》
《[Java]开发安卓,你得掌握的Java知识3》由于最终目的是要开发安卓app,
因此这里使用的IDE是AS(Android Studio)
(不会使用的可以参考下面这篇文章中的例子)
《[Java]开发安卓,你得掌握的Java知识2》
1.本文主要内容简介
抽象类
接口的概念、用法、思路
一个实际的例子(思路、代码)
2.基础知识讲解
2.1什么是抽象类
抽象类就是一个模板
抽象类有两种理解方式(算是两种用法):
(1)某种类需要规定出一些规则,规定出子类要去实现什么属性、方法,发挥一种统筹的作用(2)继承这模板,可以理解为能获得额外的能力(属性、方法),
让继承该模板(抽象类)的类获得某些额外的属性、方法
(比如人高空坠落会直接摔死,要是带了降落伞就能够缓慢降落)使用方法:首先定义一个抽象类,然后用其他类去继承它,以获得它的一些属性、方法
定义方法:abstract public 类名
public abstract class Activity {
}
要点:
抽象类里面也会分抽象方法,和方法,方法也用abstract修饰
抽象方法不能实现,只能声明,如:
public abstract void onCreate();
抽象类的普通方法要实现
继承抽象类的子类,必须实现抽象方法,但可以不管普通方法
public abstract class Activity {
//抽象方法
public abstract void onCreate();
//普通方法
public void addChilds(View v){
this.viewList.add(v);
}
}
public class MainActivity extends Activity{
@Override
public void onCreate(){
System.out.println("hello");
}
}
2.2什么是接口
从概念上来讲,
接口就是一种,需要使用者必须遵守的规则从程序员编写代码角度来讲
接口就是让两种类能联系起来的工具为什么要用接口?
①有时候需要遵守上层指定的规则
②需要联系两种类
基本定义方法:
public interface OnClickListener{
//定义一个内部接口,只有一个onClick方法
void onClick("有参数,但暂时别管");
}
public class Test implements OnClickListener{
@Override
public void onClick("有参数,但暂时别管") {
//具体实现
}
}
这样Test类就会实现这个接口了,但是只知道这些还远远不够
接口为什么可以联系两种类?
我的见解是:
因为其中一个类实现了接口,第二个类看到了就会去调用
因此两个类实现了联系简单一些来讲,定义了一个接口后,之后会出现:
①类A:实现接口的
②类B:调用类A中已经实现好的接口的方法(其实就是接口回调)
一个实现,一个调用,然后两个类就会有所联系接口在哪个类里面实现呢?
在“知道这个接口该如何实现的类”里面
即"知道到底会发生什么的那个类"里面实现
- 如果还对接口的概念很模糊,我们不妨想象一下场景:
A住在一间没有窗户、门,只有墙的房子里,然后他在墙上凿了一个洞,B每天都将指定大小的食物通过这个洞来给他送食物
在这里,A就是实现接口的类,B就是负责回调的类,指定大小就是规则,而那个洞,就是接口
public class View {
OnClickListener listener ;
public void getTouchEvent(){
//接口回调
listener.onClick(this);
}
}
interface OnClickListener{
//定义一个内部接口,只有一个onClick方法
void onClick(View v);
}
public class MainActivity implements OnClickListener{
View v = new View();
public MainActivity() {
v.listener = this;
}
public void touch(){
//发消息说我做好了
v.getTouchEvent();
}
@Override
public void onClick(View v) {
System.out.println("hello");
}
}
}
- 分析一下:
(1)View类中定义了一个接口变量listener,
一个方法用于调用接口的方法(从MainActivity的touch函数找到了View类中的方法,该方法又跑回去调用接口,即接口回调)(2)接口中只定义了一个未实现的方法onClick
(3)MainActivity中,将自身的引用付给了View类中那个接口变量,并且在类的最后定义了onClick具体怎么做(接口的实现)
(4)View类中的接口变量listener只要将它用实现接口的类(MainActivity)的对象的引用赋值(这里体现为this),就可以通过listener调用在MainActivity中实现的接口的方法onClick
==================================分割线==================================
2.3接口的编写思路
先考虑你的接口需要联系哪两个类
这两个类一个负责实现(类A),一个负责调用(类B)
在"知道到底会发生什么的那个类"里面实现接口
在负责调用的类中声明一个接口变量
然后将这个实现接口的类的对象的引用赋值给接口变量
在负责调用的类(B)中,
通过接口变量调用负责实现的类(A)已经实现好的接口的方法
3.知识实际运用
我们模拟Android中,主界面里添加按钮以及按钮的点击事件
其中接口变量要用MainActivity的对象的引用赋值这一点没有表现出来,但是这一点反而是极其重要的
==================================分割线==================================
- 首先我们定义一个抽象类Activity
public abstract class Activity {
//用来存放所有控件
public List viewList = new ArrayList<>();
public abstract void onCreate();
public abstract void onDestory();
public void addChilds(View v){
this.viewList.add(v);
}
}
其中List用来存放所有的View变量(即存放所有的控件)
抽象方法onCreate与onDestory需要继承类来具体实现
==================================分割线==================================
接下来我们看View类,View类有两个属性:边框颜色与背景颜色
public String backgroundColor;
public String boderColor;
由于我们要使用的接口与View有关,因此可以考虑直接定义为内部接口(当然定义为外部的其实也行)
public interface OnClickListener
getTouchEvent方法是用来接收消息用的。
因为我们只是模拟点击事件,所以通过MainActivity的Touch方法调用View类里面的getTouchEvent方法,可以模拟点击
public class View {
public String backgroundColor;
public String boderColor;
OnClickListener listener ;
//B请求完成的任务
public interface OnClickListener{
//定义一个内部接口,只有一个onClick方法
void onClick(View v);
}
//接受A发送过来的消息并且拆开
public void getTouchEvent(){
//接口回调
listener.onClick(this);
}
- Button类继承自View类,复杂的内容都在View中实现了,因此Button内容比较简单(属性+构造函数):
public class Button extends View {
public String title;
public String titleColor;
public Button(String title, String titleColor) {
this.title = title;
this.titleColor = titleColor;
}
}
==================================分割线==================================
- 最后我们来看MainActivity类,它继承与Activity这个抽象类,还要实现接口,因此标题就比较长:
public class MainActivity extends Activity implements View.OnClickListener
- 继承抽象类的继承类必须实现抽象方法:`
Button btn = new Button("开始","Black");
@Override
public void onCreate() {
System.out.println("界面被加载了");
btn.listener = this;
imageView.listener = this;
addChilds(btn);
addChilds(imageView);
}
@Override
public void onDestory() {
System.out.println("界面被销毁了");
}
- 这里的btn.listener = this;是十分重要的,就是在网上随便都能搜到的接口回调的概念中所写的:
把实现接口的对象的引用(MainActivity里的this)赋值给接口变量(listener),就能通过这个接口变量调用已经实现的接口的方法:
@Override
public void onClick(View v) {
System.out.println("按钮被点击了");
}
- 在View中进行回调(调用这个实现好的方法):
public void getTouchEvent(){
//接口回调
listener.onClick(this);
}
- 在MainActivity里模拟点击:(即调用View中的getTouchEvent)
public void touch(){
//发消息说我做好了
btn.getTouchEvent();
imageView.getTouchEvent();
}
==================================分割线==================================
- 最终,MainActivity代码如下:
public class MainActivity extends Activity implements View.OnClickListener{
Button btn = new Button("开始","Black");
public MainActivity() {
onCreate();
}
//用来模拟点击事件(A发送消息给B)
public void touch(){
//发消息说我做好了
btn.getTouchEvent();
imageView.getTouchEvent();
}
@Override
public void onCreate() {
System.out.println("界面被加载了");
btn.listener = this;
addChilds(btn);
}
@Override
public void onDestory() {
}
//发送给B的消息,告诉B是如何完成的
@Override
public void onClick(View v) {
System.out.println("按钮被点击了");
}
}
4.总结
(1)本文讲述了Java语言中十分重要的两个知识点:抽象类、接口
这两个知识点都是概念简单,但实际运用却十分有难度,尤其是接口,容易将人们绕晕。不过反复观看上文中的诸多例子,应该能对理解有所帮助。
(2)鉴于这两个知识点不容易理解透彻,建议大家要多一些去实践练习,从实践中寻找规律、方法,通过自己、别人的程序来总结出自己的一套理解体系,这样才能达到更好的效果