一些知识点的整理以及面试题记录
每日任務(wù)
2018年3月2日
-Service-和-IntentService-的區(qū)別
鏈接
Service
Service是長(zhǎng)期運(yùn)行在后臺(tái)的應(yīng)用程序組件。 Service不是一個(gè)單獨(dú)的進(jìn)程,它和應(yīng)用程序在同一個(gè)進(jìn)程中,Service也不算是一個(gè)線程,它和線程沒有任何關(guān)系,所有它不能直接處理耗時(shí)操作。如果直接把耗時(shí)操作放在Service的onStartCommand()中,很容易引起ANR,如果有耗時(shí)操作就必須開啟一個(gè)單獨(dú)的線程來處理。 復(fù)制代碼IntentService
IntentService是繼承于Service并處理異步請(qǐng)求的一個(gè)類,在IntentService內(nèi)有一個(gè)工作線程來處理耗時(shí)操作,啟動(dòng)IntentService的方式和啟動(dòng)傳統(tǒng)Service一樣,同時(shí),當(dāng)任務(wù)執(zhí)行完后,IntentService會(huì)自動(dòng)停止,而不需要我們?nèi)ナ謩?dòng)控制。另外,可以啟動(dòng)IntentService多次,而每一個(gè)耗時(shí)操作都會(huì)以工作隊(duì)列的方式在IntentService的onHandlerIntent回調(diào)方法中執(zhí)行,并且,每次只會(huì)執(zhí)行一個(gè)工作線程,執(zhí)行完第一個(gè)再執(zhí)行第二個(gè),以此類推。 復(fù)制代碼2018年3月3日
閱讀記錄
- 閱讀:機(jī)器學(xué)習(xí)速成課程-降低損失 (Reducing Loss)
- 閱讀:精通比特幣-1.4入門:
復(fù)習(xí)點(diǎn)
- 閱讀:精通比特幣-HD協(xié)議:
- 閱讀:JVM——Java虛擬機(jī)架構(gòu) :heavy_check_mark:
- 閱讀:Kotlin Primer·第二章·基本語(yǔ)法
- 閱讀:Android面試一天一題(1 Day):heavy_check_mark:
- 閱讀:Android studio代碼格式規(guī)范
- 閱讀:Android進(jìn)階筆記09:Android開發(fā)經(jīng)驗(yàn)部分總結(jié):heavy_check_mark:
- 閱讀:借騰訊開源 VasDolly,談?wù)?Android 簽名和多渠道打包的原理!
- 閱讀:收集了50道基礎(chǔ)的java面試題
- 閱讀:Android開源框架源碼鑒賞:VirtualAPK
-堆和棧的區(qū)別
在這里輸入圖片標(biāo)題堆和棧的區(qū)別
重要復(fù)習(xí)點(diǎn)
1.png2.png3.png4.png待閱讀
視頻:Android-屏幕適配全攻略
2018年3月5日
重要復(fù)習(xí)點(diǎn)
- Android內(nèi)存泄漏--imageloader???
- android解決加載大圖片卡頓和oom問題。
尺寸壓縮之inSampleSize 為了防止加載圖片時(shí)內(nèi)存溢出,需要先計(jì)算采樣率,然后再去加載圖片。
-
算法一:圖片長(zhǎng)與目標(biāo)長(zhǎng)比,圖片寬與目標(biāo)寬比,取最大值。
-
算法二:取目標(biāo)長(zhǎng)寬的最大值來計(jì)算,這樣會(huì)減少過度的尺寸壓縮。
2018年3月6日
Android-壓縮大圖到容量超小的圖片
原文
壓縮圖片的寬高
/*** 計(jì)算圖片的壓縮比** @param options* @param reqWidth* @param reqHeight* @return*/public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {final int height = options.outHeight;final int width = options.outWidth;int inSampleSize = 1;//壓縮比if (height > reqHeight || width > reqWidth) {final int halfHeight = height / 2;final int halfWidth = width / 2;while ((halfHeight / inSampleSize) >= reqHeight && (halfWidth / inSampleSize) >= reqWidth) {inSampleSize*=2;}}return inSampleSize;} 復(fù)制代碼調(diào)用calculateInSampleSize計(jì)算壓縮比。并解碼原圖為Bitmap:
/*** @param imagePath* @param displayWidth* @param displayHeight* @return*/private Bitmap compress(String imagePath, int displayWidth, int displayHeight) {BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true;//只測(cè)量image 不加載到內(nèi)存。BitmapFactory.decodeFile(imagePath, options);//測(cè)量imageoptions.inPreferredConfig = Bitmap.Config.RGB_565;//設(shè)置565編碼格式,省內(nèi)存,options.inSampleSize = calculateInSampleSize(options, displayWidth, displayHeight);options.inJustDecodeBounds = false;Bitmap bitmap = BitmapFactory.decodeFile(imagePath, options);//按照Options配置去加載圖片到內(nèi)存return bitmap;} 復(fù)制代碼這里比較重要的inJustDecodeBounds字段,當(dāng)inJustDecodeBounds為true時(shí),調(diào)用BitmapFactory.decode時(shí)并沒有把圖片加載到內(nèi)存中去,只是去測(cè)量圖片的寬高,不不占用內(nèi)存,當(dāng)inSampleSize為false時(shí),調(diào)用BitmapFactory.decoe時(shí)就把圖片加載到內(nèi)存去了,所有獲取bitmap應(yīng)在inJustDecodeBounds為false后的BitmapFactory.decode去獲取。
設(shè)置編碼格式 android中默認(rèn)格式是ARG8888,我們解碼圖片一般用ARG565節(jié)省圖片加載到內(nèi)存的大小。
ALPHA_8 代表8位Alpha位圖 ARGB_4444 代表16位ARGB位圖 ARGB_8888 代表32位ARGB位圖 RGB_565 代表8位RGB位圖 復(fù)制代碼位圖位數(shù)越高代表其可以存儲(chǔ)的顏色信息越多,當(dāng)然圖像也就越逼真
圖片質(zhì)量壓縮
ByteArrayOutputStream out = new ByteArrayOutputStream();//字節(jié)流輸出 bitmap.compress(Bitmap.CompressFormat.JPEG,50,out);//壓縮成jpeg格式復(fù)制代碼compress中第一個(gè)參數(shù)是輸出文件的格式,在Bitmap枚舉類CompressFormat中定義,有JPEG,PNG PNG,WEBP,一般選擇JPEG,壓縮出來的容量小,WEBP很耗時(shí), 耗時(shí)時(shí)間比較:WEBP>PNG>JPEG, 壓縮大小:PNG>WEBP>JPEG. 第二個(gè)參數(shù)是壓縮的質(zhì)量比例,也就是壓縮像素的顯示色彩,當(dāng)100時(shí)表示不壓縮。當(dāng)為50時(shí)表示壓縮50%的質(zhì)量。設(shè)置這個(gè)參數(shù)可以有效的極大的縮小圖片的大小,可以按照自己的需求進(jìn)行設(shè)置, 但建議一般不要大于60.第三個(gè)參數(shù)就是想要寫入的圖片數(shù)據(jù)的字節(jié)流數(shù)組了。
字節(jié)流寫出文件
我們經(jīng)過上述步驟后,就拿到了字節(jié)流數(shù)據(jù)了,此時(shí)我們可以根據(jù)項(xiàng)目需求直接上傳字節(jié)流或者保存為本地圖片再上傳。
ByteArrayOutputStream out = new ByteArrayOutputStream();//字節(jié)流輸出bitmap.compress(Bitmap.CompressFormat.JPEG, 50, out);//壓縮成jpeg格式 壓縮像素質(zhì)量為50%String fileName = imagePath.substring(imagePath.lastIndexOf("/") + 1, imagePath.lastIndexOf("."));//獲取文件名File outFile = new File("/storage/emulated/0/photoPickTemp", fileName + "_temp.jpeg");//創(chuàng)建壓縮后的image文件try {if (!outFile.exists()) {//判斷文件是否存在if (outFile.createNewFile()) {//判斷創(chuàng)建新文件是否成功FileOutputStream fos = new FileOutputStream(outFile);byte[] bytes = out.toByteArray();//字節(jié)數(shù)組int count = bytes.length;fos.write(bytes, 0, count);fos.close();//關(guān)閉流out.close();}}} catch (Exception e) {e.printStackTrace();} 復(fù)制代碼獲取當(dāng)前屏幕寬高
工具類
封裝
public class ImageUtil {public ImageUtil(){}public static File compressImage(String imagePath,int displayWidth,int displayHeight){BitmapFactory.Options options=new BitmapFactory.Options();options.inJustDecodeBounds=true;//只測(cè)量image 不加載到內(nèi)存BitmapFactory.decodeFile(imagePath,options);//測(cè)量imageoptions.inPreferredConfig= Bitmap.Config.RGB_565;//設(shè)置565編碼格式 省內(nèi)存options.inSampleSize=calculateInSampleSize(options,displayWidth,displayHeight);//獲取壓縮比 根據(jù)當(dāng)前屏幕寬高去壓縮圖片options.inJustDecodeBounds=false;Bitmap bitmap=BitmapFactory.decodeFile(imagePath,options);//按照Options配置去加載圖片到內(nèi)存ByteArrayOutputStream out=new ByteArrayOutputStream();//字節(jié)流輸出bitmap.compress(Bitmap.CompressFormat.JPEG,50,out);//壓縮成JPEG格式 壓縮像素質(zhì)量為50%String fileName=imagePath.substring(imagePath.lastIndexOf("/")+1,imagePath.lastIndexOf("."));//獲取文件名稱File outFile=new File("/storage/emulated/0/PhotoPickTemp",fileName+"_temp.jpeg");//創(chuàng)建壓縮后的image文件try {if(!outFile.exists()){//判斷新文件是否存在if(outFile.createNewFile()){//判斷創(chuàng)建新文件是否成功FileOutputStream fos=new FileOutputStream(outFile);//創(chuàng)建一個(gè)文件輸出流byte[] bytes=out.toByteArray();//字節(jié)數(shù)組int count=bytes.length;//字節(jié)數(shù)組的長(zhǎng)度fos.write(bytes,0,count);//寫到文件中fos.close();//關(guān)閉流out.close();}}} catch (IOException e) {e.printStackTrace();}return outFile;}public static int calculateInSampleSize(BitmapFactory.Options options,int reqWidth,int reqHeight){//計(jì)算圖片的壓縮比final int height=options.outHeight;//圖片的高度final int width=options.outWidth;//圖片的寬度 單位1px 即像素點(diǎn)int inSampleSize=1;//壓縮比if(height>reqHeight||width>reqWidth){final int halfHeight=height/2;final int halfWidth=width/2;while ((halfHeight/inSampleSize)>=reqHeight&&(halfWidth/inSampleSize)>=reqWidth){inSampleSize*=2;}}return inSampleSize;} } 復(fù)制代碼Android-性能優(yōu)化
布局優(yōu)化
- 布局嵌套過深
- 使用合適的布局
- 列表控件優(yōu)化
- 使用include標(biāo)簽
- ViewStub延時(shí)加載
- 移除Activity默認(rèn)背景
線程優(yōu)化
ViewPager,ScrollView-嵌套ViewPager滑動(dòng)沖突解決
原文
Android事件分發(fā)機(jī)制
圖解 Android 事件分發(fā)機(jī)制
- 對(duì)于dispathTouchEvent,onTouchEvent,return true 是終結(jié)事件傳遞。return false 是回溯到父View的onTouchEvent方法。
- ViewGroup想把自己分發(fā)給自己的onTouchEvent,需要攔截器onInterecptTouchEvent方法return true把事件攔截下來。
- ViewGroup的攔截器默認(rèn)是不攔截的。所以super.onInterecptTouchEvent()= return true;
- View沒有攔截器,為了讓View可以把事件分發(fā)給自己的onTouchEvent,View的dispatchTouchEvent默認(rèn)實(shí)現(xiàn)(super)就是把事件分發(fā)給自己的onTouchEvent
ViewGroup和View的dispatchTouchEvent是做事件分發(fā),那么這個(gè)事件分發(fā)可能分發(fā)出去的四個(gè)目標(biāo)。
java鎖的種類以及辨析
自旋鎖
采用讓當(dāng)前線程不停地在循環(huán)體內(nèi)執(zhí)行實(shí)現(xiàn)的。當(dāng)循環(huán)條件被其他線程改變時(shí),才進(jìn)入臨界區(qū)
阻塞鎖(synchronized)
可重入鎖(遞歸鎖)
指的是同一線程外層函數(shù)獲得鎖之后,內(nèi)層遞歸函數(shù)仍然有獲取該鎖的代碼,但不受影響。 可重入鎖最大的作用是避免死鎖。
互斥鎖的優(yōu)缺點(diǎn): - 優(yōu)點(diǎn):能有效防止因多線程搶奪資源造成數(shù)據(jù)安全的問題 - 缺點(diǎn):需要消耗大量的CPU資源。互斥鎖的使用前提:多條線程搶奪同一塊資源。** 自旋鎖更適合做一些較短的操作 ** 復(fù)制代碼ANR
ANR
應(yīng)用程序無響應(yīng)。
為什么會(huì)產(chǎn)生ANR
-
5s內(nèi)無法響應(yīng)用戶輸入事件(例如鍵盤輸入,觸摸屏幕等)
-
BroadcastReceiver在10s內(nèi)無法結(jié)束
造成以上兩種情況的首要原因就是在主線程(UI線程)里面做了太多的阻塞耗時(shí)操作,例如:文件讀寫,數(shù)據(jù)庫(kù)讀寫,網(wǎng)絡(luò)查詢。
如何避免ANR
不要在主線程里面做繁重的操作
ANR的處理
開辟單獨(dú)的子線程來處理耗時(shí)阻塞事物。
I/O阻塞一般就是文件讀寫或者數(shù)據(jù)庫(kù)操作執(zhí)行在主線程了,也可以通過開辟子線程的方式異步執(zhí)行。
增大VM內(nèi)存,使用largeHeap屬性,排查內(nèi)存泄露
RxJava
給 Android 開發(fā)者的 RxJava 詳解-flatMap():
2018年3月8日
Android-安裝文件(APK)瘦身
2018年3月9日
Android應(yīng)用程序啟動(dòng)過程源代碼分析
Step 1. Launcher.startActivitySafely
在Android系統(tǒng)中,應(yīng)用程序是由launch啟動(dòng)起來的,其實(shí),launch本身也是一個(gè)應(yīng)用程序,其他的應(yīng)用程序安裝后,就會(huì)launcher的界面上出現(xiàn)一個(gè)相應(yīng)的圖標(biāo)。點(diǎn)擊這個(gè)圖標(biāo),launcher就會(huì)對(duì)應(yīng)的應(yīng)用程序啟動(dòng)起來。 復(fù)制代碼Android2017-2018最新面試題(3-5年經(jīng)驗(yàn)個(gè)人面試經(jīng)歷)
面試題(固定答案不解答,自己可以找到)
大圖加載控件
大圖加載控件
2018年3月12日
Android插件化與熱修復(fù)
DynamicApk-攜程
- 支持類的加載
- 用代理的方式加載Activity
- 反射方式加載資源
沒有像DroidPlugin那樣是資源獨(dú)立的,而是采用同一套資源,用資源名稱去區(qū)分不同的資源,針對(duì)資源的id也做修改,Activity的加載方式是采用代理的方式讓系統(tǒng)識(shí)別的。
文章地址
github地址
DroidPlugin-360手機(jī)助手
原理:利用Android一個(gè)進(jìn)程可以運(yùn)行多個(gè)apk的機(jī)制,通過API欺騙讓系統(tǒng)認(rèn)為只有宿主app存在,同時(shí)通過預(yù)先占坑來創(chuàng)造插件app的運(yùn)行環(huán)境,最后通過動(dòng)態(tài)代理實(shí)現(xiàn)函數(shù)hook,Binder代理繞過部分系統(tǒng)服務(wù)限制,從而實(shí)現(xiàn)應(yīng)用的組件化。
- DroidPlugin這個(gè)是跟360安全的產(chǎn)品密切相關(guān)的,也非常適合360手機(jī)助手。 DroidPlugin的目標(biāo)是使任何一個(gè)app都可以在DroidPlugin的宿主應(yīng)用中直接運(yùn)行。而不是將app安裝到手機(jī)中,再去體驗(yàn)app。
- DroidPlugin中使用了大量的hook相關(guān)技術(shù),特別是在Activity的注冊(cè)上,做了預(yù)先注冊(cè)一些Activity,然后在新的Activity啟動(dòng)時(shí)欺騙系統(tǒng)是預(yù)先注冊(cè)過的Activity。 DroidPlugin最精華的就是hook技術(shù)。
GitHub地址
HotFix-QQ空間熱補(bǔ)丁技術(shù)
主要技術(shù)是:系統(tǒng)在安裝app的時(shí)候會(huì)在類加載器中加載apk中的默認(rèn)classes.dex文件。這個(gè)類加載器可以加載后續(xù)的補(bǔ)丁Dex文件,而且可以調(diào)整Dex文件的加載順序,這樣就可以用同名的類去替換掉原始的含有bug的類,已達(dá)到修復(fù)bug的目的。
AndFix-阿里支付寶
- AndFix的原理是方法的替換,把有bug的方法替換成補(bǔ)丁文件中的方法,在Native層使用指針替換的方式替換bug的方法,已達(dá)到修復(fù)bug的目的。
Alibaba-AndFix Bug熱修復(fù)框架原理及源碼解析
Tinker-微信
在客戶端將補(bǔ)丁文件和app原始文件進(jìn)行合并,用客戶端的存儲(chǔ)空間換取網(wǎng)絡(luò)傳輸?shù)牧髁亢蚢pp的運(yùn)行效率。Tinker目前開源支持的比較好,網(wǎng)上資料相對(duì)多一些,在編譯時(shí)通過新舊兩個(gè)Dex文件生成差異的patch.dex文件,在app中將差異的patch.dex文件重新跟原始安裝包的原始的Dex文件生成新的Dex文件。這個(gè)過程會(huì)耗費(fèi)app的運(yùn)行時(shí)間和內(nèi)存,所以Tinker將其單獨(dú)放在一個(gè)后臺(tái)進(jìn)程:patch中。為了將補(bǔ)丁包盡量的小,Tinker自研了DexDiff算法,他深度利用Dex的格式來減少差異文件的大小。
2018年3月13日
Java基礎(chǔ)
java中==和equals和hashCode的區(qū)別
==
結(jié)果是:true,false,true
對(duì)象類型的比較,比較的是地址(引用),而非值本身,也是就是說他們實(shí)際存儲(chǔ)的內(nèi)存地址不同。
equals
比較兩個(gè)對(duì)象的引用是否相等,即 是否指向同一個(gè)對(duì)象。
總結(jié)
對(duì)于==,如果作用于基本數(shù)據(jù)類型,則直接比較其存儲(chǔ)的“值”是否相等,如果作用于引用類型的變量,則比較的是所指向的對(duì)象的地址。
對(duì)于 equals 方法,注意:equals不能作用于基本數(shù)據(jù)類型,如果沒有對(duì)equals進(jìn)行重寫,則比較的是 引用類所指向的地址。如果重寫了,比較的就是對(duì)象的內(nèi)容。
hashCode
用來鑒定兩個(gè)對(duì)象是否相等,Object類中的hashCode方法返回對(duì)象在內(nèi)存中地址轉(zhuǎn)換成的一個(gè)int值,所以如果沒有重寫hashCode方法,任何對(duì)象的hashCode方法是不相等的。
設(shè)計(jì)hashCode()時(shí)最重要的因素就是:無論何時(shí),對(duì)同一個(gè)對(duì)象調(diào)用hashCode都應(yīng)該產(chǎn)生同一個(gè)值。
如果重寫了equals方法就必須要重寫hashCode方法,以便用戶將對(duì)象插入到散列表中。
equals相等的兩個(gè)對(duì)象,hashCode一定相等,equals不相等的兩個(gè)對(duì)象,卻并不能證明他們的hashCode不相等。
equals方法不相等的兩個(gè)對(duì)象,hashCode有可能相等,
在每個(gè)覆蓋了equals方法的類中,也必須覆蓋hashCode方法,如果不這樣做的話,就會(huì)違反Object.hashCode的通用約定。從而導(dǎo)致該類無法結(jié)合所有基于散列的集合一起正常運(yùn)作。
int、char、long 各占多少字節(jié)數(shù)
-
byte 是 字節(jié)
-
bit 是 位
1 byte = 8 bit
- char在java中是2個(gè)字節(jié),java采用unicode,2個(gè)字節(jié)來表示一個(gè)字符
- short 2個(gè)字節(jié)
- int 4個(gè)字節(jié)
- long 8個(gè)字節(jié)
- float 4個(gè)字節(jié)
- double 8個(gè)字節(jié)
int 與 integer 區(qū)別
記錄-
2.4 比特幣挖礦
2018 BAT等大廠最全面試題集錦
6.4.1 圖靈非完備性
2018年3月14日
String、StringBuffer、StringBuilder區(qū)別
- String :字符串常量(線程安全)
字符串是不變的,他們的值在創(chuàng)造后就不能改變。 字符串緩沖區(qū)支持可變字符串。因?yàn)樽址畬?duì)象是不可變的,所以他們可以共享。
總結(jié)歸納了String的兩個(gè)最重要的特點(diǎn):
-
StringBuilder:字符串變量(非線程安全)
-
StringBuffer:字符串變量(線程安全)
是一個(gè)容器,最終會(huì)通過toString方法變成字符串。
String與StringBuffer區(qū)別
- 主要區(qū)別:在修改時(shí)對(duì)象自身是否可變
String在修改時(shí)不會(huì)改變對(duì)象自身。每次對(duì)String類型進(jìn)行改變的時(shí)候其實(shí)都等同于生成了一個(gè)新的String對(duì)象,然后將指針指向了新的String對(duì)象,所以經(jīng)常改變內(nèi)容的字符串最好不要用String。
StringBuffer在修改時(shí)會(huì)改變對(duì)象自身。每次結(jié)果都會(huì)對(duì)StringBuffer對(duì)象本身進(jìn)行操作,而不是生成新的對(duì)象,改改變對(duì)象引用,所以一般情況下我們推薦使用StringBuffer,特別是字符串對(duì)象經(jīng)常改變的情況下,StringBuffer的主要操作是append和insert方法
- StringBuffer對(duì)象和String對(duì)象之間的互轉(zhuǎn):
總結(jié)
- 如果要操作少量的數(shù)據(jù)用String
- (多線程下)經(jīng)常需要對(duì)一個(gè)字符串進(jìn)行修改,例如追加、插入和刪除等操作,使用StringBuffer更加適合一些。
StringBuffer與StringBuilder區(qū)別
- StringBuilder是可變的對(duì)象,是5.0新增的 此類提供一個(gè)與StringBuffer兼容的API,但不保證同步,該類被設(shè)計(jì)用作StringBuffer的一個(gè)簡(jiǎn)易替換,用在字符串緩沖區(qū)被單個(gè)線程使用的時(shí)候(這種情況很普遍)
- 線程安全性:
- String、StringBuilder、StringBuffer速度區(qū)別
- 特殊情況, String > StringBuffer
總結(jié)
對(duì)java多態(tài)的理解
- 什么是多態(tài)
- 多態(tài)的好處:
java中多態(tài)的實(shí)現(xiàn)方式:接口實(shí)現(xiàn),繼承父類進(jìn)行方法的重寫,同一個(gè)類中方法重載。
多態(tài)的三要素:1.繼承。2.重寫。3.父類引用指向子類對(duì)象
package objectandclass; class A { public void show(D obj){ System.out.println("A and D"); } public void show(A obj){ System.out.println ("A and A"); } } class B extends A{ public void show(B obj){ System.out.println("B and B"); } public void show(A obj){ System.out.println("B and A"); } } class C extends B{} class D extends B{} A a1 = new A(); A a2 = new B(); B b = new B(); C c = new C(); D d = new D(); a1.show(b); //A and Aa1.show(c); //A and Aa1.show(d); //A and Da2.show(b); //B and Aa2.show(c); //B and Aa2.show(d); //A and Db.show(b); //B and Bb.show(c); //B and Bb.show(d); //A and D 復(fù)制代碼2018年3月15日
什么是內(nèi)部類?內(nèi)部類的作用
定義
就是定義在另外一個(gè)類里面的類,與之對(duì)應(yīng),包含內(nèi)部類的類被稱為外部類。
作用
2018年3月16日
抽象類和接口
- 抽象類:對(duì)一類事物的抽象
定義: 如果一個(gè)類中沒有包含足夠多的信息來描述一個(gè)具體的對(duì)象,這樣的類就是抽象類。
- 接口:對(duì)某一行為的抽象
定義: 接口在java中是一個(gè)抽象類型,是抽象方法的集合。一個(gè)類通過實(shí)現(xiàn)接口的方式,從而繼承接口中的抽象方法。
抽象類的意義:
區(qū)別總結(jié):
抽象類是對(duì)事物的抽象,接口是對(duì)行為的抽象;抽象類是對(duì)整個(gè)類的抽象,包括行為,屬性;接口是對(duì)類的行為(局部)進(jìn)行抽象。
設(shè)計(jì)抽象類是自下而上的過程,我子類需要,所以我定義抽象類;設(shè)計(jì)接口是自上而下的過程,我接口規(guī)范某一行為,我某類需要這個(gè)行為,我某類實(shí)現(xiàn)某接口。
核心區(qū)別:
調(diào)用者使用的動(dòng)機(jī)不同,實(shí)現(xiàn)接口 為了使用其他規(guī)范的某一個(gè)行為;繼承抽象類是為了使用這個(gè)類的屬性和行為 復(fù)制代碼總結(jié)
使用場(chǎng)景
再設(shè)計(jì)類時(shí),如果有些方法我們能確定,而有些方法不能確定,這時(shí)候就可以定義成抽象類。抽象類的應(yīng)用場(chǎng)景非常多,例如模板方法模式就是抽象類的一個(gè)應(yīng)用,JDK中inputStream和outputStream也是抽象類的一個(gè)應(yīng)用,這兩個(gè)類定義了如何讀寫數(shù)據(jù)的方法,而沒有定義從哪里去讀,具體從哪里讀是由具體的實(shí)現(xiàn)子類確定。
我們?cè)诙x相互調(diào)用規(guī)則時(shí),可以使用接口,面向接口進(jìn)行編程的好處,就是能極大地降低軟件系統(tǒng)的耦合性,接口的定義按照接口進(jìn)行調(diào)用,而實(shí)現(xiàn)者去實(shí)現(xiàn)接口。 在JDK中存在很多針對(duì)接口的編程,例如用于我們比較兩個(gè)對(duì)象的Comparable接口就是一個(gè)典型的案例,我們?cè)谧远x對(duì)象時(shí),如果實(shí)現(xiàn)了該接口,那么我們把對(duì)象保存到treeset集合中,treeset將針對(duì)接口調(diào)用對(duì)象的compareTo方法。
2018年3月19日
加載大圖、Rxjava、面經(jīng)
高效加載大圖
給 Android 開發(fā)者的 RxJava 詳解---2) 變換的原理:lift()
一年經(jīng)驗(yàn)-有贊面經(jīng)--RxJava的flatMap和Map的作用
總結(jié)
以上是生活随笔為你收集整理的一些知识点的整理以及面试题记录的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: WebVie打开woffice文档
- 下一篇: Python任务调度模块 – APSch