继承:面向对象三大特性之一
面向对象三大特征:封装,继承,多态
封装:面向对象三大特征之一 - 鹿先森JIAN - 博客园 (cnblogs.com)
继承的相关特性
B 类继承A类,则称A类为超类(superclass)、父类、基类,B 类则称为子类(subclass)、派生类、扩展类。
java 中的继承只支持单继承,不支持多继承(C++支持),这也是 java 体现简单性的一点,即 java 中不允许这样写代码:class B extends A,C{ }。
但可以间接继承,例如:class C extends B,class B extends A,这里的C 直接继承B,C 还间接继承A。 但这样的缺点是,它们的耦合度非常高,父类发生改变之后会马上影响到其子类。
java 中规定,子类继承父类,除构造方法和被private 修饰的数据不能继承外,剩下都可以继承。
隐式继承:java 中的类没有显示的继承任何类,则默认继承Object 类,Object 类是java 语言提供的根类(祖先类),也就是说,一个对象与生俱来就有Object 类型中所有的特征。
java 中继承的语法格式:
问题:属性封装,要求属性必须私有化,继承是私有化的不能继承,那么属性封装和继承存在矛盾吗?
答:不存在,属性封装要求属性私有化的同时还要提供公开的 get和 set方法,那么 get和 set是可以被继承的,所以继承和封装一起使用,不存在矛盾!
//银行账户类(父类、基类、超类) public class Account { //账号 private String actno; //余额 private double balance; //账号和余额的set 和get 方法 public String getActno() { return actno; } public void setActno(String actno) { this.actno = actno; } public double getBalance() { return balance; } public void setBalance(double balance) { this.balance = balance; } }
//信用账户类(子类、派生类、扩展类)
public class CreditAccount { //账号 private String actno; //余额 private double balance; //账号和余额的set 和get 方法 public String getActno() { return actno; } public void setActno(String actno) { this.actno = actno; } public double getBalance() { return balance; } public void setBalance(double balance) { this.balance = balance; } //信誉度(特有属性) private double credit; //信誉度的set 和get 方法 public double getCredit() { return credit; } public void setCredit(double credit) { this.credit = credit; } }
上面,“信用账户类”的蓝底代码跟“银行账户类”相同,修改为继承方式后就可以复用父类代码了,请看下面:
//信用账户类(继承父类 Acount) public class CreditAccount extends Account{ //信誉度(特有属性) private double credit; //信誉度的set 和get 方法 public double getCredit() { return credit; } public void setCredit(double credit) { this.credit = credit; } }
测试类:
执行结果:
111111111信用账户,余额9000.0元
注意:以上代码父类的属性都是私有的,子类是不能继承过来的,但是通过继承过来的共有setter、getter方法能够访问到父类的属性。
继承的作用中除了可以让代码复用之外,还有非常重要的两个作用,那就是有了继承之后才会衍生出方法的覆盖和多态机制。
继承相关构造方法注意事项
执行结果:
父类静态代码块
子类静态代码块
父类构造
子类构造
我们对以上的程序进行分析,子类H2 继承H1,new H2()执行的时候,会先进行类加载,先加载H2 的父类H1,所以H1 当中的静态代码块先执行,然后再执行H2 中的静态代码块。静态代码块执行结束之后,将会执行构造方法,Java 中有一条规则:子类构造方法执行前先执行父类的构造方法(学习 super 之后大家就知道了),所以先执行父类 H1的构造方法,最后执行子类H2 的构造方法。