public class Sub extends Base{
...
}
定义:
一个类Sub通过extends关键字继承了另一个类Base,我们称Sub为子类,Base为父类。那么子类就继承了父类的属性和方法。(此处的继承需遵循以下原则)
原则:
- Java不支持多继承,一个类只能直接继承一个父类,但是可以间接继承多个父类。如果一个类没有使用extends关键字继承任何类,那么这个类直接继承java.lang.Object类。如果一个类使用extends直接继承了另一个类,那么这个类间接继承java.lang.Object类。
- 当子类Sub和父类Base位于同一个包中时,Sub类继承了Base类中public、protected和默认访问级别的成员变量和成员方法。
- 当子类Sub和父类Base位于不同的包中时,Sub类继承了Base类中public、protected访问级别的成员变量和成员方法。
下面介绍两个关于继承的重要概念:方法重载和方法覆盖
方法重载
指在同一个类中,声明一个与已有方法名相同,方法参数、个数和顺序至少有一项不同的方法。我们假设一下,如果一个类中同时声明两个方法名、参数类型、个数和顺序都相同的方法,很显然,Java编译是无法通过的。如果编译通过,当我们调用该方法时,栈中的指针无法定位到方法区中的方法字节码。所以同一个类中的两个方法不可能完全一样。因此方法重载必须满足以下条件:
- 方法名相同。
- 方法的参数类型、个数、顺序至少有一项不相同。
- 方法的返回类型可以不相同。
- 方法的修饰符可以不相同。
public class Sample{
public void amethod(int i, String s){};
public void amethod(String s, int i){} //重载方法
public int amethod(int i, String s){return 0;} //方法重复
private int amethod(int i, String str){} //方法重复
public void Amethod(int i, String s){} //新方法
abstract void amethod(int i); //非抽象类,定义抽象方法
}
abstract public class Sample{
public static void main(String[] s){}
abstract public void main(String s, int i); //重载方法
public final static int main(String[] s){} //方法重复
private void main(int i, String str){} //重载方法
public void main(String s)throws Exception{} //重载方法
}
方法覆盖
指在一个类和其直接继承或间接继承的父类之间,子类声明与父类方法完全相同的方法(返回类型、方法名、参数类型、个数和顺序都相同)。称之为子类覆盖了父类的方法。
- 子类方法的名称、参数类型、个数、顺序和返回类型必须与父类方法的名称、参数类型、个数、顺序和返回类型完全一致。
- 子类方法不能缩小父类方法的访问权限。
- 子类方法不能抛出比父类方法更多的异常,子类方法抛出的异常必须和父类方法抛出的异常相同,或者子类方法抛出的异常类是父类方法抛出的异常类的子类。
- 方法覆盖只能存在于子类和父类之间。在同一个类中方法只能被重载,不能被覆盖。
- 父类的静态方法不能被子类覆盖为非静态方法。
- 子类可以定义与父类的静态方法同名的静态方法,以便在子类中隐藏父类的静态方法。
- 父类的非静态方法不能被子类覆盖为静态方法。
- 父类的私有方法不能被子类覆盖。
- 父类的抽象方法可以被子类通过两种途经覆盖:一是子类实现父类的抽象方法;二是子类重新声明父类的抽象方法。
- 父类的非抽象方法可以被覆盖为抽象方法。
方法覆盖与方法重载的异同
共同点:
- 都要求方法同名。
- 都可以用于抽象方法和非抽象方法之间。
不同点:
- 方法覆盖要求参数类型、个数和顺序必须一致,而方法重载要求参数类型、个数和顺序必须不一致。
- 方法覆盖要求返回类型必须一致,而方法重载对此不做限制。
- 方法覆盖只能用于子类覆盖父类的方法,方法重载用于同一个类的所有方法(包括从父类中继承而来的方法)。
- 方法覆盖对方法的访问权限和抛出的异常有特殊要求,而方法重载在这方面没有任何限制。
- 父类的一个方法只能被子类覆盖一次,而一个方法在所在类中可以被重载多次。