目录
一、继承
继承的意义:继承使得整个程序框架具有一定的弹性,在程序中复用一些已经定义完整的类可以减少开发周期,也可以提高软件的可维护性和扩展性。
接下来介绍Java继承的特性
1.1 Java继承一父对多子,一子对一父,且纵深到顶
一个子类最多只有一个父类(不同于C和C++),而且没有类可以成为自己的超类,即不能继承自己。但一个父类可以有多个子类。
子类会一直向上,继承父类中、爷爷类,无限祖先类中非private修饰符的成员,包括变量、方法、内部类,直到不再有继承的顶部。
实例:在不同的包testA,testB,testC下分别新建类文件A.java、B.java、C.java,然后用B继承A,C继承B。
package testA;
public class A {
private String strA = "这是一个A的private变量";
public String getStrA() {return strA;}
public void setStrA(String strA) {this.strA = strA;}
}
package testB;
import testA.A;
public class B extends A{
private String strB = "这是一个A的private变量";
public String getStrB() {return strB;}
public void setStrB(String strB) {this.strB = strB;}
}
package testC;
import testB.B;
public class C extends B{
private String strC = "这是一个C的private变量";
public String getStrC() {return strC;}
public void setStrC(String strC) {this.strC = strC;}
public static void main(String[] args) { C c = new C();
c.setStrA("父类A方法被子类C给调用了");
c.setStrB("父类B方法被子类C给调用了");
c.setStrC("子类C调用了自己的方法");
}
}
1.2 重写(overwrite)与重构(over)
继承并不只是扩展祖先类的功能,还可以【重写】(还可以称为【覆盖】)祖先类的方法。
【重写】:重写一般是在项目测试前,发现父类的方法不适用于子类,要重新创建这样一个方法,可能原本一个形参,变成三个形参,原本是private,现在是public。
就是在子类中将【父类的成员方法名】保留,重写内容可以包括:
- 成员方法的参数类型与个数
- 成员方法的方法体内容
- 成员方法的权限修饰符
- 成员方法的返回值
package testA;
public class A {
public void func() {System.out.println("这是A类public方法");}
}
package testB;
import testA.A;
public class B extends A{
protected int func(int b) {System.out.println("这是B类的public方法"+b);return b;}
}
package testC;
import testB.B;
public class C extends B{
private String c func(String c) {System.out.println("这是C类的public方法"+c);return c;}
}
【重构】:在不改变代码外在行为(原本接受的参数不变,返回值不变)的前提下,对代码做出修改,以改进程序的内部结构。重构是一种经千锤百炼形成的有条不紊的程序整理方法,可以最大限度地减小整理过程中引入错误的概率。本质上说,重构就是在代码写好之后改进它的设计。
重构保留【父类的成员方法名、成员方法的参数类型与个数、成员方法的权限修饰符、成员方法的返回值】,只修改成员【方法的方法体内容】。
package testA;
public class A {
public void func1() {System.out.println("这是A类public方法");}
}
package testB;
import testA.A;
public class B extends A{
public void func1() {System.out.println("这是B类的public方法");}
}
package testC;
import testB.B;
public class C extends B{
public void func1() {System.out.println("这是C类的public方法");}
}
1.3 构造函数的继承
如果父类中,没有明确定义的无参构造函数,即只有默认构造函数,则子类可以任意建立构造函数。
新建子类对象过程:在调用子类的构造函数时,会自动调用父类的默认构造函数。
package testA;
public class A {
}
package testB;
import testA.A;
public class B extends A{
protected B(String b) {System.out.println("这是B类的有参构造函数");}
protected B(char c) {System.out.println("这是B类的另一个有参构造函数");}
}
如果父类A中,有明确定义的无参构造函数,则子类可以任意建立构造函数。