一、前言:
在 java 中乖坠,子類 重寫父類方法搀突,子類中的 super() 方法會先調(diào)用父類方法,然后再調(diào)用自身熊泵;重寫的方法仰迁,必須被調(diào)用,不然不會執(zhí)行顽分,super() 方法也可以注釋掉徐许,不會調(diào)用父類方法。
在 Android 中卒蘸,子類重寫父類方法(BaseActivity)雌隅,子類中的 super() 方法會先調(diào)用父類方法,然后再調(diào)用自身缸沃;重寫的方法恰起,必須被Activity 生命周期調(diào)用,不然不會執(zhí)行趾牧, super() 方法也可以注釋掉检盼,不會調(diào)用父類方法,Activity 中重寫的生命周期方法不可以去掉super()翘单,去掉會報錯“Overriding method should call super.onDestroy less”梯皿。
二、Java 子類重寫父類的方法八大規(guī)則:
1. 重寫規(guī)則之一:
重寫方法不能比被重寫方法限制有更嚴(yán)格的訪問級別县恕。
但是可以更廣泛,比如父類方法是包訪問權(quán)限剂桥,子類的重寫方法是public訪問權(quán)限忠烛。有個人曾經(jīng)這樣說:父類為protected的,子類重寫時一定要用public权逗;我覺得這個觀點不能是絕對的美尸,只要滿足子類的訪問權(quán)限不比父類低就行了冤议。
比如:Object類有個toString()方法,開始重寫這個方法的時候我們總?cè)菀淄沺ublic修飾符师坎,編譯器當(dāng)然不會放過任何教訓(xùn)我們的機會恕酸。出錯的原因就是:沒有加任何訪問修飾符的方法具有包訪問權(quán)限,包訪問權(quán)限比public當(dāng)然要嚴(yán)格了胯陋,所以編譯器會報錯的蕊温。
2. 重寫規(guī)則之二:
參數(shù)列表必須與被重寫方法的相同。
重寫有個孿生的弟弟叫重載遏乔,也就是后面要出場的义矛。如果子類方法的參數(shù)與父類對應(yīng)的方法不同,那么就是你認(rèn)錯人了盟萨,那是重載凉翻,不是重寫。
3. 重寫規(guī)則之三:
返回類型必須與被重寫方法的返回類型相同捻激。
父類方法A:void eat(){} 子類方法B:int eat(){}兩者雖然參數(shù)相同制轰,可是返回類型不同,所以不是重寫胞谭。
父類方法A:int eat(){} 子類方法B:long eat(){}返回類型雖然兼容父類垃杖,但是不同就是不同,所以不是重寫韭赘。
4. 重寫規(guī)則之四:
重寫方法不能拋出新的異乘醣酰或者比被重寫方法聲明的檢查異常更廣的檢查異常。但是可以拋出更少泉瞻,更有限或者不拋出異常脉漏。
注意:這種限制只是針對檢查異常,至于運行時異常RuntimeException及其子類不再這個限制之中袖牙。
5. 重寫規(guī)則之五:
不能重寫被標(biāo)識為final的方法侧巨。
6. 重寫規(guī)則之六:
如果一個方法不能被繼承,則不能重寫它鞭达。如private方法
比較典型的就是父類的private方法司忱。下例會產(chǎn)生一個有趣的現(xiàn)象。
public class Test {
public static void main (String[] args) {
//Animal h = new Horse();
Horse h = new Horse();
h.eat();
}
}
class Animal {
private void eat(){
System.out.println ("Animal is eating.");
}
}
class Horse extends Animal{
public void eat(){
System.out.println ("Horse is eating.");
}
}
這段代碼是能通過編譯的畴蹭。表面上看來違反了第六條規(guī)則坦仍,但實際上那是一點巧合。Animal類的eat()方法不能被繼承叨襟,因此Horse類中的eat()方法是一個全新的方法繁扎,不是重寫也不是重載,只是一個只屬于Horse類的全新的方法!這點讓很多人迷惑了梳玫,但是也不是那么難以理解爹梁。
7. 重寫規(guī)則之七:
子類不能用 靜態(tài)方法重寫父類的非靜態(tài)方法
編繹無法通過this static method cannot hide the instance mehtodfrom
class A {
protected int method1(int a, int b) {
return 0;
}
}
public class Test1 extends A {
private int method1(int a, long b) {
return 0;
}
//this static method cannot hide the instance mehtod from A
static public int method1(int a, int b) {
return 0;
}
}
8. 重寫規(guī)則之八:
子類不能用非靜態(tài)方法重寫父類的靜態(tài)方法
編繹報錯:thisinstance method cannot override the static mehtod fromA
class A {
protected static int method1(int a, int b) {
return 0;
}
}
public class Test1 extends A {
private int method1(int a, long b) {
return 0;
}
//this static method cannot hide the instance mehtod from A
//this instance method cannot override the static mehtod from A
public int method1(int a, int b) {
return 0;
}
}
三、Android 重寫 BaseActivity:
1. BaseActivity類:
public class BaseActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("LUO","BaseActivity=========onCreate()");
//默認(rèn)不注冊提澎,子類重寫
if (isRegisteredEventBus()) {
//注冊
EventBusUtil.register(this);
}
}
@Override
protected void onStop() {
super.onStop();
Log.d("LUO", "BaseActivity=========onStop()");
}
/**
* 可以在子類中重寫onStickyEventBusCome()
*
* @param event
*/
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEventBusCome(Event event) {
Log.d("LUO","BaseActivity=========onEventBusCome()");
if (event != null) {
receiveEvent(event);
}
}
/**
* 可以在子類中重寫onStickyEventBusCome()
*
* @param event
*/
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
public void onStickyEventBusCome(Event event) {
if (event != null) {
receiveStickyEvent(event);
}
}
/**
* 接收到分發(fā)到事件
*
* @param event 事件
*/
protected void receiveEvent(Event event) {
}
/**
* 接受到分發(fā)的粘性事件
*
* @param event 粘性事件
*/
protected void receiveStickyEvent(Event event) {
}
/**
* 是否注冊事件分發(fā)
*
* 可以在子類中重寫isRegisterEventBus()
* @return true 注冊姚垃;false 不注冊,默認(rèn)不注冊
*/
protected boolean isRegisteredEventBus() {
Log.d("LUO","BaseActivity=========isRegisteredEventBus()");
return false;
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d("LUO","BaseActivity=========onDestroy()");
//默認(rèn)不注冊盼忌,子類重寫
if (isRegisteredEventBus()) {
//反注冊
EventBusUtil.unregister(this);
}
}
public void show(){
Log.d("LUO","BaseActivity=========show()");
}
}
2. TwoActivity類:
public class TwoActivity extends BaseActivity {
private Button button1;
private Button button2;
private TextView tv1;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_two);
button1 = findViewById(R.id.button1);
button2 = findViewById(R.id.button2);
tv1 = findViewById(R.id.tv1);
Log.d("LUO","TwoActivity=========onCreate()");
show();
init();
}
private void init() {
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EventBusUtil.sendEvent(new Event(EventCode.B,"中國必將能夠崛起积糯!"));
finish();
}
});
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ThirdActivity.launch(TwoActivity.this);
}
});
}
public static void launch(Context mContext) {
Intent intent = new Intent(mContext,TwoActivity.class);
mContext.startActivity(intent);
}
/**
* 接受事件
* @param event
*/
@Override
public void onEventBusCome(Event event) {
Log.d("LUO","TwoActivity=========onEventBusCome()");
switch (event.getCode()) {
case EventCode.A:
Log.d("EventBus", "接收到A類型的Event");
break;
case EventCode.B:
Log.d("EventBus", "接收到B類型的Event"+event.getData());
break;
case EventCode.C:
User user = (User) event.getData();
Log.d("EventBus", "接收到B類型的Event,攜帶User"+user);
break;
case EventCode.D:
News news = (News) event.getData();
Log.d("EventBus", "接收到D類型的Event碴犬,攜帶News"+news);
break;
default:
}
}
@Override
protected void onStop() {
super.onStop();
Log.d("LUO","TwoActivity=========onStop()");
}
@Override
protected boolean isRegisteredEventBus() {
Log.d("LUO","TwoActivity=========isRegisteredEventBus()");
return true;
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d("LUO","TwoActivity=========onDestroy()");
}
@Override
public void show() {
super.show();
Log.d("LUO","TwoActivity=========show()");
}
}
3. 結(jié)果分析:
- 進(jìn)入TwoActivity中啟動順序:
// 1. 先走BaseActivity中的onCreate()
LUO: BaseActivity=========onCreate()
//2. 調(diào)用TwoActivity中的isRegisteredEventBus()方法絮宁,沒有啟動TwoActivity
LUO: TwoActivity=========isRegisteredEventBus()
//3. 啟動TwoActivity中的onCreate()
LUO: TwoActivity=========onCreate()
//4. 在show()中,調(diào)用 super.show()服协,再調(diào)用父類show()
LUO: BaseActivity=========show()
//5.在TwoActivity中的onCreate()方法中調(diào)用show()
LUO: TwoActivity=========show()
- 關(guān)閉TwoActivity
// 1. 先關(guān)閉父類的onStop()
LUO: BaseActivity=========onStop()
// 2.再關(guān)閉子類的onStop()
LUO: TwoActivity=========onStop()
// 3.先關(guān)閉父類的onDestroy
LUO: BaseActivity=========onDestroy()
//4.關(guān)閉的時候绍昂,調(diào)用TwoActivity中的isRegisteredEventBus()
LUO: TwoActivity=========isRegisteredEventBus()
//再關(guān)閉子類的onDestroy()
LUO: TwoActivity=========onDestroy()
4. 總結(jié):
- 重寫的方法,一定是先走父類偿荷,再走子類( 注意 super()一定不能忘了寫)窘游;
- 其它 Activity2 調(diào)用本Activity1 的方法,跟本 Activity1生命周期沒有關(guān)系跳纳;
- 本Activity1中重寫的方法忍饰,只有被生命周期方法調(diào)用,才會執(zhí)行寺庄;