0.前言
上一篇文章(Java知識(shí)6)我們講解了繼承、多態(tài)等知識(shí)點(diǎn)
今天我們講兩個(gè)重點(diǎn):抽象類和接口若想要了解“類”的主要知識(shí)输拇,可以去看前面的文章
《[Java]開發(fā)安卓摘符,你得掌握的Java知識(shí)5》
《[Java]開發(fā)安卓,你得掌握的Java知識(shí)4》
《[Java]開發(fā)安卓策吠,你得掌握的Java知識(shí)3》由于最終目的是要開發(fā)安卓app逛裤,
因此這里使用的IDE是AS(Android Studio)
(不會(huì)使用的可以參考下面這篇文章中的例子)
《[Java]開發(fā)安卓,你得掌握的Java知識(shí)2》
1.本文主要內(nèi)容簡(jiǎn)介
抽象類
接口的概念猴抹、用法带族、思路
一個(gè)實(shí)際的例子(思路、代碼)
2.基礎(chǔ)知識(shí)講解
2.1什么是抽象類
抽象類就是一個(gè)模板
抽象類有兩種理解方式(算是兩種用法):
(1)某種類需要規(guī)定出一些規(guī)則蟀给,規(guī)定出子類要去實(shí)現(xiàn)什么屬性蝙砌、方法,發(fā)揮一種統(tǒng)籌的作用(2)繼承這模板跋理,可以理解為能獲得額外的能力(屬性择克、方法),
讓繼承該模板(抽象類)的類獲得某些額外的屬性前普、方法
(比如人高空墜落會(huì)直接摔死肚邢,要是帶了降落傘就能夠緩慢降落)使用方法:首先定義一個(gè)抽象類,然后用其他類去繼承它拭卿,以獲得它的一些屬性骡湖、方法
定義方法:abstract public 類名
public abstract class Activity {
}
要點(diǎn):
抽象類里面也會(huì)分抽象方法,和方法峻厚,方法也用abstract修飾
抽象方法不能實(shí)現(xiàn)响蕴,只能聲明,如:
public abstract void onCreate();
抽象類的普通方法要實(shí)現(xiàn)
繼承抽象類的子類惠桃,必須實(shí)現(xiàn)抽象方法浦夷,但可以不管普通方法
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什么是接口
從概念上來講懊渡,
接口就是一種,需要使用者必須遵守的規(guī)則從程序員編寫代碼角度來講
接口就是讓兩種類能聯(lián)系起來的工具為什么要用接口军拟?
①有時(shí)候需要遵守上層指定的規(guī)則
②需要聯(lián)系兩種類
基本定義方法:
public interface OnClickListener{
//定義一個(gè)內(nèi)部接口剃执,只有一個(gè)onClick方法
void onClick("有參數(shù),但暫時(shí)別管");
}
public class Test implements OnClickListener{
@Override
public void onClick("有參數(shù)懈息,但暫時(shí)別管") {
//具體實(shí)現(xiàn)
}
}
這樣Test類就會(huì)實(shí)現(xiàn)這個(gè)接口了肾档,但是只知道這些還遠(yuǎn)遠(yuǎn)不夠
接口為什么可以聯(lián)系兩種類?
我的見解是:
因?yàn)?strong>其中一個(gè)類實(shí)現(xiàn)了接口辫继,第二個(gè)類看到了就會(huì)去調(diào)用
因此兩個(gè)類實(shí)現(xiàn)了聯(lián)系簡(jiǎn)單一些來講怒见,定義了一個(gè)接口后,之后會(huì)出現(xiàn):
①類A:實(shí)現(xiàn)接口的
②類B:調(diào)用類A中已經(jīng)實(shí)現(xiàn)好的接口的方法(其實(shí)就是接口回調(diào))
一個(gè)實(shí)現(xiàn)姑宽,一個(gè)調(diào)用遣耍,然后兩個(gè)類就會(huì)有所聯(lián)系接口在哪個(gè)類里面實(shí)現(xiàn)呢?
在“知道這個(gè)接口該如何實(shí)現(xiàn)的類”里面
即"知道到底會(huì)發(fā)生什么的那個(gè)類"里面實(shí)現(xiàn)
- 如果還對(duì)接口的概念很模糊炮车,我們不妨想象一下場(chǎng)景:
A住在一間沒有窗戶舵变、門,只有墻的房子里瘦穆,然后他在墻上鑿了一個(gè)洞纪隙,B每天都將指定大小的食物通過這個(gè)洞來給他送食物
在這里,A就是實(shí)現(xiàn)接口的類扛或,B就是負(fù)責(zé)回調(diào)的類绵咱,指定大小就是規(guī)則,而那個(gè)洞熙兔,就是接口
public class View {
OnClickListener listener ;
public void getTouchEvent(){
//接口回調(diào)
listener.onClick(this);
}
}
interface OnClickListener{
//定義一個(gè)內(nèi)部接口悲伶,只有一個(gè)onClick方法
void onClick(View v);
}
public class MainActivity implements OnClickListener{
View v = new View();
public MainActivity() {
v.listener = this;
}
public void touch(){
//發(fā)消息說我做好了
v.getTouchEvent();
}
@Override
public void onClick(View v) {
System.out.println("hello");
}
}
}
- 分析一下:
(1)View類中定義了一個(gè)接口變量listener,
一個(gè)方法用于調(diào)用接口的方法(從MainActivity的touch函數(shù)找到了View類中的方法住涉,該方法又跑回去調(diào)用接口麸锉,即接口回調(diào))(2)接口中只定義了一個(gè)未實(shí)現(xiàn)的方法onClick
(3)MainActivity中,將自身的引用付給了View類中那個(gè)接口變量秆吵,并且在類的最后定義了onClick具體怎么做(接口的實(shí)現(xiàn))
(4)View類中的接口變量listener只要將它用實(shí)現(xiàn)接口的類(MainActivity)的對(duì)象的引用賦值(這里體現(xiàn)為this)淮椰,就可以通過listener調(diào)用在MainActivity中實(shí)現(xiàn)的接口的方法onClick
==================================分割線==================================
2.3接口的編寫思路
先考慮你的接口需要聯(lián)系哪兩個(gè)類
這兩個(gè)類一個(gè)負(fù)責(zé)實(shí)現(xiàn)(類A),一個(gè)負(fù)責(zé)調(diào)用(類B)
在"知道到底會(huì)發(fā)生什么的那個(gè)類"里面實(shí)現(xiàn)接口
在負(fù)責(zé)調(diào)用的類中聲明一個(gè)接口變量
然后將這個(gè)實(shí)現(xiàn)接口的類的對(duì)象的引用賦值給接口變量
在負(fù)責(zé)調(diào)用的類(B)中纳寂,
通過接口變量調(diào)用負(fù)責(zé)實(shí)現(xiàn)的類(A)已經(jīng)實(shí)現(xiàn)好的接口的方法
3.知識(shí)實(shí)際運(yùn)用
我們模擬Android中,主界面里添加按鈕以及按鈕的點(diǎn)擊事件
其中接口變量要用MainActivity的對(duì)象的引用賦值這一點(diǎn)沒有表現(xiàn)出來泻拦,但是這一點(diǎn)反而是極其重要的
==================================分割線==================================
- 首先我們定義一個(gè)抽象類Activity
public abstract class Activity {
//用來存放所有控件
public List<View> viewList = new ArrayList<>();
public abstract void onCreate();
public abstract void onDestory();
public void addChilds(View v){
this.viewList.add(v);
}
}
其中List用來存放所有的View變量(即存放所有的控件)
抽象方法onCreate與onDestory需要繼承類來具體實(shí)現(xiàn)
==================================分割線==================================
接下來我們看View類毙芜,View類有兩個(gè)屬性:邊框顏色與背景顏色
public String backgroundColor;
public String boderColor;
由于我們要使用的接口與View有關(guān),因此可以考慮直接定義為內(nèi)部接口(當(dāng)然定義為外部的其實(shí)也行)
public interface OnClickListener
getTouchEvent方法是用來接收消息用的争拐。
因?yàn)槲覀冎皇悄M點(diǎn)擊事件腋粥,所以通過MainActivity的Touch方法調(diào)用View類里面的getTouchEvent方法晦雨,可以模擬點(diǎn)擊
public class View {
public String backgroundColor;
public String boderColor;
OnClickListener listener ;
//B請(qǐng)求完成的任務(wù)
public interface OnClickListener{
//定義一個(gè)內(nèi)部接口,只有一個(gè)onClick方法
void onClick(View v);
}
//接受A發(fā)送過來的消息并且拆開
public void getTouchEvent(){
//接口回調(diào)
listener.onClick(this);
}
- Button類繼承自View類隘冲,復(fù)雜的內(nèi)容都在View中實(shí)現(xiàn)了闹瞧,因此Button內(nèi)容比較簡(jiǎn)單(屬性+構(gòu)造函數(shù)):
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這個(gè)抽象類展辞,還要實(shí)現(xiàn)接口奥邮,因此標(biāo)題就比較長(zhǎng):
public class MainActivity extends Activity implements View.OnClickListener
- 繼承抽象類的繼承類必須實(shí)現(xiàn)抽象方法:`
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;是十分重要的,就是在網(wǎng)上隨便都能搜到的接口回調(diào)的概念中所寫的:
把實(shí)現(xiàn)接口的對(duì)象的引用(MainActivity里的this)賦值給接口變量(listener)罗珍,就能通過這個(gè)接口變量調(diào)用已經(jīng)實(shí)現(xiàn)的接口的方法:
@Override
public void onClick(View v) {
System.out.println("按鈕被點(diǎn)擊了");
}
- 在View中進(jìn)行回調(diào)(調(diào)用這個(gè)實(shí)現(xiàn)好的方法):
public void getTouchEvent(){
//接口回調(diào)
listener.onClick(this);
}
- 在MainActivity里模擬點(diǎn)擊:(即調(diào)用View中的getTouchEvent)
public void touch(){
//發(fā)消息說我做好了
btn.getTouchEvent();
imageView.getTouchEvent();
}
==================================分割線==================================
- 最終洽腺,MainActivity代碼如下:
public class MainActivity extends Activity implements View.OnClickListener{
Button btn = new Button("開始","Black");
public MainActivity() {
onCreate();
}
//用來模擬點(diǎn)擊事件(A發(fā)送消息給B)
public void touch(){
//發(fā)消息說我做好了
btn.getTouchEvent();
imageView.getTouchEvent();
}
@Override
public void onCreate() {
System.out.println("界面被加載了");
btn.listener = this;
addChilds(btn);
}
@Override
public void onDestory() {
}
//發(fā)送給B的消息,告訴B是如何完成的
@Override
public void onClick(View v) {
System.out.println("按鈕被點(diǎn)擊了");
}
}
4.總結(jié)
(1)本文講述了Java語言中十分重要的兩個(gè)知識(shí)點(diǎn):抽象類覆旱、接口
這兩個(gè)知識(shí)點(diǎn)都是概念簡(jiǎn)單蘸朋,但實(shí)際運(yùn)用卻十分有難度,尤其是接口扣唱,容易將人們繞暈藕坯。不過反復(fù)觀看上文中的諸多例子,應(yīng)該能對(duì)理解有所幫助噪沙。
(2)鑒于這兩個(gè)知識(shí)點(diǎn)不容易理解透徹堕担,建議大家要多一些去實(shí)踐練習(xí),從實(shí)踐中尋找規(guī)律曲聂、方法霹购,通過自己、別人的程序來總結(jié)出自己的一套理解體系朋腋,這樣才能達(dá)到更好的效果