------- android培训、java培训、期待与您交流! ----------
前面的博文中,我们提到java的数据类型包括基本数据类型和引用类型,而引用类型又
分别包括类类型,数组类型,接口类型。在这三种类型当中,类类型是我们将要常常用到
的类型。本篇博文将重点讲述在类类型里面的一种体系机制——继承。
我们知道程序的编写通常耗时费力,对于程序员来讲,尽可能地节省代码量,减少冗余
代码,是一件很有益的事情。而java当中类的继承机制则是复用代码的有力手段之一。
通常,继承只发生在两个类之间,并且通过关键字extends来申明这种关系,以下为基本格
式。
public class Sub extends Base{}
上述代码表明了Sub类继承了Base类。那么问题来了,Sub到底继承了Base类中的一些什么
呢?我们知道,一个类中,不仅有属性,还有方法,而且这些属性以及方法的访问权限不尽相
同,而这种继承还应该考虑到sub类与base类是否属于同一个包。所以:
(1)当Sub与Base位于同一个包中,Sub类继承了Base类中public,protected以及默认访问级别
的属性与方法。
(2)当Sub与Base不位于同一个包中时,则继承了public和protected访问级别的属性与方法。
对于继承关系,我们还应该注意以下几点:
(1)java中不支持多继承关系,一个类可以有多个子类,但只能有一个父类。以下代码将编译
失败。
public class Sub extends Base1,Base2...{}<pre class="java" name="code">public class Sub extends Base1,Base2...{
}//编译失败
(2)java中有一个预定义的类object类,java中规定,所有的类都直接或者间接继承object类。
在了解了java中的继承关系之后,我们将继续学习另外一个知识点,方法的覆盖。java中继承
关系,事实上,更确切地说,它是一种向上抽取的过程而产生的一种关系,举个例子,当我们
发现了所有动物的都具备吃,运动,繁殖,等等共性之后,我们自然而然的抽取出动物这个抽象
类,这个抽象类当中就包含着吃,运动,繁殖等等这些抽象方法。猫属于动物,所以猫继承了
动物类。自然地,猫也继承了吃这个功能,但很显然的是猫吃的东西与其他动物是有区别的,
所以猫实现吃的方式如果只是单单继承了动物的吃,则问题的描述将不会与现实一致,而动物
吃的功能也不可能仅仅提供给猫,这个时候,猫需要做的一件事情就是复写吃这个功能,java
中用来实现的机制就是方法的覆盖。
下面分别介绍方法覆盖所要注意的问题:
(1)子类方法与父类方法的名称,方法参数,返回类型必须一致。
class A {
public int show(){
system.out.prinln("我是A类");
return 0;
}
}
class B extends A{
public void show(){
system.out.prinln("我是B类");
}//编译失败,返回类型与父类不一致
}
(2)子方法不能缩小父方法的访问权限
<span style="font-size:12px;">class A {
public int show(){
system.out.prinln("我是A类");
return 0;
}
}
class B extends A{
int show(){
system.out.prinln("我是B类");
return 0;
}//编译失败,访问权限为默认级别,父类方法权限被缩小
}</span>
(3)子方法不能比父方法抛出更多异常。
(4)方法的覆盖只能存在于子类以及父类之间,同一个类中方法只能被重载,不能被覆盖。
(5)父类的静态方法不能被子类覆盖为非静态方法。
<span style="font-size:12px;">class A {
public static int show(){
system.out.prinln("我是A类");
return 0;
}
}
class B extends A{
int show(){
system.out.prinln("我是B类");
return 0;
}//编译失败,父类的静态方法被覆盖为非静态,static关键字为静态
}</span>
(6)父类的非静态方法不能被子类覆盖为静态方法。
<span style="font-size:12px;">class A {
public int show(){
system.out.prinln("我是A类");
return 0;
}
}
class B extends A{
static int show(){
system.out.prinln("我是B类");
return 0;
}//编译失败,父类的非静态方法被覆盖为静态
}</span>
(7)父类的抽象方法不能被子类覆盖,但是在子类中可以定义同名同参返回类型一致的方法,
以下代码编译通过:
<span style="font-size:12px;">class A {
private int show(){
system.out.prinln("我是A类");
return 0;
}//private关键字为私有类型,不可被覆盖。
}
class B extends A{
public int show(){
system.out.prinln("我是B类");
return 0;
}//编译通过,但不覆盖父类方法。
}</span>
(8)父类的抽象方法,被子类覆盖时,有两种途径,一是子类实现父类方法,二是子类
重新申明此方法。