Java 和 Android 子类重写父类方法

一、前言:

  1. 在 java 中,子类 重写父类方法,子类中的 super() 方法会先调用父类方法,然后再调用自身;重写的方法,必须被调用,不然不会执行,super() 方法也可以注释掉,不会调用父类方法。

  2. 在 Android 中,子类重写父类方法(BaseActivity),子类中的 super() 方法会先调用父类方法,然后再调用自身;重写的方法,必须被Activity 生命周期调用,不然不会执行, super() 方法也可以注释掉,不会调用父类方法,Activity 中重写的生命周期方法不可以去掉super(),去掉会报错“Overriding method should call super.onDestroy less”。

二、Java 子类重写父类的方法八大规则:

1. 重写规则之一:

重写方法不能比被重写方法限制有更严格的访问级别。

但是可以更广泛,比如父类方法是包访问权限,子类的重写方法是public访问权限。有个人曾经这样说:父类为protected的,子类重写时一定要用public;我觉得这个观点不能是绝对的,只要满足子类的访问权限不比父类低就行了。

比如:Object类有个toString()方法,开始重写这个方法的时候我们总容易忘记public修饰符,编译器当然不会放过任何教训我们的机会。出错的原因就是:没有加任何访问修饰符的方法具有包访问权限,包访问权限比public当然要严格了,所以编译器会报错的。

2. 重写规则之二:

参数列表必须与被重写方法的相同。

重写有个孪生的弟弟叫重载,也就是后面要出场的。如果子类方法的参数与父类对应的方法不同,那么就是你认错人了,那是重载,不是重写。

3. 重写规则之三:

返回类型必须与被重写方法的返回类型相同。

父类方法A:void eat(){} 子类方法B:int eat(){}两者虽然参数相同,可是返回类型不同,所以不是重写。

父类方法A:int eat(){} 子类方法B:long eat(){}返回类型虽然兼容父类,但是不同就是不同,所以不是重写。

4. 重写规则之四:

重写方法不能抛出新的异常或者比被重写方法声明的检查异常更广的检查异常。但是可以抛出更少,更有限或者不抛出异常。

注意:这种限制只是针对检查异常,至于运行时异常RuntimeException及其子类不再这个限制之中。

5. 重写规则之五:

不能重写被标识为final的方法。

6. 重写规则之六:

如果一个方法不能被继承,则不能重写它。如private方法

比较典型的就是父类的private方法。下例会产生一个有趣的现象。

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.");  
   }  
}  

这段代码是能通过编译的。表面上看来违反了第六条规则,但实际上那是一点巧合。Animal类的eat()方法不能被继承,因此Horse类中的eat()方法是一个全新的方法,不是重写也不是重载,只是一个只属于Horse类的全新的方法!这点让很多人迷惑了,但是也不是那么难以理解。

7. 重写规则之七:

子类不能用 静态方法重写父类的非静态方法

编绎无法通过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. 重写规则之八:

子类不能用非静态方法重写父类的静态方法

编绎报错: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()");
        //默认不注册,子类重写
        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);
        }
    }

    /**
     * 接收到分发到事件
     *
     * @param event 事件
     */
    protected void receiveEvent(Event event) {

    }

    /**
     * 接受到分发的粘性事件
     *
     * @param event 粘性事件
     */
    protected void receiveStickyEvent(Event event) {

    }


    /**
     * 是否注册事件分发
     *
     * 可以在子类中重写isRegisterEventBus()
     * @return true 注册;false 不注册,默认不注册
     */
    protected boolean isRegisteredEventBus() {
        Log.d("LUO","BaseActivity=========isRegisteredEventBus()");
        return false;
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d("LUO","BaseActivity=========onDestroy()");
        //默认不注册,子类重写
        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. 结果分析:

  1. 进入TwoActivity中启动顺序:
// 1. 先走BaseActivity中的onCreate()
LUO: BaseActivity=========onCreate()
//2. 调用TwoActivity中的isRegisteredEventBus()方法,没有启动TwoActivity
LUO: TwoActivity=========isRegisteredEventBus()
//3. 启动TwoActivity中的onCreate()
LUO: TwoActivity=========onCreate()
//4. 在show()中,调用 super.show(),再调用父类show()
LUO: BaseActivity=========show()
//5.在TwoActivity中的onCreate()方法中调用show()
LUO: TwoActivity=========show()
  1. 关闭TwoActivity
// 1. 先关闭父类的onStop()
LUO: BaseActivity=========onStop()
// 2.再关闭子类的onStop()
LUO: TwoActivity=========onStop()
// 3.先关闭父类的onDestroy
LUO: BaseActivity=========onDestroy()
//4.关闭的时候,调用TwoActivity中的isRegisteredEventBus()
LUO: TwoActivity=========isRegisteredEventBus()
//再关闭子类的onDestroy()
LUO: TwoActivity=========onDestroy()

4. 总结:

  1. 重写的方法,一定是先走父类,再走子类( 注意 super()一定不能忘了写);
  2. 其它 Activity2 调用本Activity1 的方法,跟本 Activity1生命周期没有关系;
  3. 本Activity1中重写的方法,只有被生命周期方法调用,才会执行;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。