使用继承的注意点

来源:互联网 发布:淘宝店页面背景图 编辑:程序博客网 时间:2024/05/14 09:32

继承是实现复用的重要手段,但继承带来了一个最大的坏处:破坏封装。

子类扩展父类时,子类可以从父类继承得到成员变量和方法,如果访问权限允许,子类可以直接访问父类的成员变量和方法,相当于子类可以直接复用父类的成员变量和方法,确实非常方便。

继承带来高度复用的同时,也带来了一个严重的问题:继承严重地破坏了父类的封装性。前面介绍封装时提到:每个类都应该封装它内部信息和实现细节,而只暴露必要的方法给其他类使用。但是在继承关系中,子类可以直接访问父类的成员变量(内部信息)和方法,从而导致了子类可以随意篡改父类的方法。

为了保证父类具有良好的封装性,不会被子类随意改变,设计父类通常应该遵循如下规则。
尽量隐藏父类的内部数据。尽量把父类的所有成员变量都设置成private访问类型,不要让子类直接访问父类的成员变量。

不要让子类可以随意访问、修改父类的方法。父类中那些仅为辅助其他的工作方法,应该用private访问控制符修饰,让子类无法访问该方法,可以使用final修饰符(该修饰符后面会有更详细的介绍)来修饰该方法:如果希望父类的某个方法被子类重写,但不希望被其他类自由访问,则可以使用protected来修饰该方法

尽量不要在父类构造器中调用将要被子类重写的方法

package com.suqian.test;class Base{    public Base()    {        test();    }    public void test()//①    {        System.out.println("将被子类重写的方法");    }}public class Sub extends Base{    private String name;    public void test() //②    {        System.out.println("子类重写父类的方法," + "其name字符串长度" + name.length());    }    public static void main(String[] args) {        //下面代码会引发空指针异常        Sub s = new Sub();    }}

运行结结果:

Exception in thread "main" java.lang.NullPointerException

因为当试图创建Sub对象时,系统同样会先执行父类构造器,如果父类构造器调用了其被子类重写的构造器,则变成被子类重写后的方法。

当创建Sub对象时,会先执行Base类中的Base构造器,而Base构造器中调用的test()方法是被子类重写的②号构造器,此时Sub对象的name实例变量时null,因此引发空指针异常。

如果想把某些类设置成最终类,即不能被当成父类继承,则可以是final修饰这个类。
除此之外,使用private修饰这个类的所有构造器,从而保证子类无法调用该类的构造器,也就无法继承该类。

而对于很多人来演,何时使用继承关系是一个难以把握的问题。
到底何时需要从父类派生新的子类呢?

不仅要保证从子类是一种特殊父类,而且需要具备以下两个条件之一。
①子类需要额外增加属性,而不仅仅是属性值的改变。例如从Person类派生处于Student子类,Person类里没有提供grade(年级属性)。

②子类需要增加自己独有的行为方式(包括增加新的方法或重写父类方法)。例如从Person类派生出Teacher类,其中Teacher类需要增加一个teaching()方法。

0 0
原创粉丝点击