Java中的继承使用extends关键字实现,形式为:class 子类 extends 父类{}
继承的优点:
- 子类可以直接对父类的操作继续使用,属于代码重用。
- 子类可以继续扩充属于自己的标准。
但是Java中的继承有一定的限制:
- Java不允许多重继承,但是允许多层继承。
- 子类在继承父类的时候严格来讲会继承父类中的所有操作,但是对于所有的私有操作属于隐式继承,对于所有的非私有操作属于显示继承。
- 在子类对象构造之前一定会默认调用父类的构造(默认使用无参构造),以保证父类的对象先实例化,然后再实例化子类对象(见下面例子)。
package project;
class A{
public A() {
System.out.println("A的构造方法!");
}
}
class B extends A{
public B() {
System.out.println("B的构造方法!");
}
}
public class Main {
public static void main(String[] args){
B b = new B();
}
}
运行结果:
由此可以明显看出父类的构造方法先被调用(毕竟有了爸爸才有儿子嘛,哈哈)
当父类中有无参构造的时候(即上例),默认在子类的构造中有一句“super()”,即
class B extends A{
public B() {
super(); //可加可不加
System.out.println("B的构造方法!");
}
}
但是如果父类中没有无参构造时,及必须使用“super()”(必须放在首行)来明确调用父类中的有参构造方法。即:
package project;
class A{
public A(String s) {
System.out.println("A的构造方法!");
}
}
class B extends A{
public B(String s) {
super(s); //父类中没有无参构造,所以必须要加,必须在首行
System.out.println("B的构造方法!");
}
}
public class Main {
public static void main(String[] args){
B b = new B("hello");
}
}
在继承中,如果在子类定义属性或方法的时候有可能与父类中的属性或方法同名,这就称之为覆写。
覆写的适用原则:
如果发现父类中的方法功能不足(不适用于子类),但是又必须使用这个方法名称的时候,就需要采用覆写这一概念实现。
问题:重载与覆写的区别:
区别 | 重载 | 覆写 |
发生范围 | 发生在一个类里面 | 发生在继承关系中 |
定义 | 方法名称,参数的类型及个数相同 | 方法名称,参数类型及个数,方法返回值相同 |
权限 | 没有权限限制 | 被覆写的方法不能拥有比父类更为严格的访问控制权限 |
继承与覆写的综合应用:
定义一个Array类,在这个类里面可以进行整形数组的操作,由外部传入数据,并能实现数据的保存和输出操作,然后在这个类的基础上派生出两个子类:
- 排序数组类:此类可以对数组的数据进行排序。
- 逆序数组类:此类可以对数组进行逆序操作。
package project;
class Array{ //数组类
private int[] data;
private int foot;
public Array(int len) { //构造
if(len > 0) {
this.data = new int[len];
}else {
this.data = new int[1];
}
}
public boolean add(int num) { //添加数据
if(this.foot < this.data.length) {
this.data[this.foot ++] = num;
return true;
}
return false;
}
public int[] getData() { //取得数据
return data;
}
}
class SortArray extends Array { //排序数组类
public SortArray(int len) {
super(len);
// TODO Auto-generated constructor stub
}
public int[] getData() { //覆写父类中的方法
java.util.Arrays.sort(super.getData()); //对数组排序
return super.getData();
}
}
class ReverseArray extends Array{ //逆转数组类
public ReverseArray(int len) {
super(len);
// TODO Auto-generated constructor stub
}
public int[] getData() { //覆写父类的方法
int center = super.getData().length / 2;
int head = 0 ;
int tail = super.getData().length - 1;
for(int i = 0 ; i < center ; i ++) { //逆转数组
int temp = super.getData()[head];
super.getData()[head] = super.getData()[tail];
super.getData()[tail] = temp ;
head++;
tail--;
}
return super.getData();
}
}
public class Main {
public static void main(String[] args){
SortArray arr1 = new SortArray(3);
arr1.add(15);
arr1.add(6);
arr1.add(10);
int[] temp = arr1.getData();
for(int i = 0 ;i < temp.length ; i++) {
System.out.print(temp[i] + " ");
}
System.out.println();
ReverseArray arr2 = new ReverseArray(3);
arr2.add(10);
arr2.add(20);
arr2.add(30);
temp = arr2.getData();
for(int i = 0 ;i < temp.length ; i++) {
System.out.print(temp[i] + " ");
}
}
}
运行截图: