Java继承和组合

 为了保证父类有良好的封装性,不会被子类随意修改,设计父类通常应该遵循以下规则:

1、尽量隐藏父类的内部数据,尽量把父类的所有成员变量设置为 private 访问类型,不要让子类直接访问父类的成员变量;

2、不要让子类可以随意访问和修改父类方法,父类中仅为辅助其他工具的方法,应该使用private 访问控制符修饰,让子类无法访问该方法;如果父类中的方法需要被外部类调用,则必须设置为  public 修饰,但不希望子类重写该方法,可以使用final修饰符来修饰该方法;如果希望父类的某个方法被子类重写,但不希望被其他类自由访问,则可以使用protected来修饰该方法。

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

package test_Java;

class Base {
    public Base()
    {
        test();
    }
    public void test()//1
    {
        System.out.println("将被子类重写的方法");
    }
    
}
public class Sub {
    private String name;
    public void test()//2
    {
        System.out.println("子类重写父类的方法, "+"其name字符串的长度"+name.length());
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Sub s = new Sub();
        
        s.test();//空指针异常
    }
}

产生空指针异常的原因:当系统试图创建Sub对象时,同样会先执行其父类构造器,如果父类构造器调用了被其子类重写的方法,则变成调用被子类重写后的方法,当创建Sub对象时,会先执行Base类中的Base构造器,而Base构造器中调用test()方法-----并不是1而是2,此时的Sub对象的name实例变量是null,因此将引发空指针异常。

到底何时需要从父类派生出新的子类,具备以下条件:

  • 子类需要额外增加属性,不仅仅是属性值的改变。
  • 子类需要增加自己独有的行为方式,

如果只是出于类复用的目的,并不一定需要使用继承,完全可以使用组合来实现。

class Animal{
    private void beat()
    {
        System.out.println("心脏跳动。。。");
    }
    public void breath()
    {
        beat();
        System.out.println("吸一口气,吐一口气,呼吸中。。。");
    }
}
class Bird{
    private Animal a;
    public Bird(Animal a)
    {
        this.a=a;
    }
    public void Breath()
    {
        a.breath();
    }
    public void fly()
    {
        System.out.println("i can fly.");
    }
}
public class CompositeTest {
    public static void main(String [] args)
    {
        Animal a = new Animal();
        Bird b = new Bird(a);
        b.Breath();
        b.fly();
        
    }
}

总之继承要表达的是一种“是(is a)”的关系,而组合表达的是“有(has a)”的关系。

转载于:https://www.cnblogs.com/wft1990/p/7992706.html

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值