2007年3月21日星期三

重拾java(3):继承

❁java不支持多继承

❁子类不能访问父类中声明为private的类成员

❁java与C++中均一样,父类引用不能访问仅在子类中定义的函数或变量:
public class t2 {
public static void main(String args[]) {
F p = new S();
int i = p.s; // wrong
}
}

class F {
int f;
}

class S extends F {
int s;
}
❁super()必须永远是一个子类构造函数内执行的第一条语句。如下面的程序将会报错:
class S extends F {
int s;
S() {
int u;
super(); // Wrong! Constructor
call must be the first
statement in a constructor
int k;
}
}

因为构造函数按派生顺序,从超类到子类被调用。

❁如下程序例1。父类中的变量虽被覆盖,但p仍访问的是父类变量。而父类中的方法却被覆盖,因此p.pr()访问的是子类函数,类似于C++中的虚函数。这一点非常奇怪。因为在C++中,不管是变量还是函数,它们都是统一的,要覆盖就都会被覆盖,像这种动态的函数调用必须通过virtual来声明。另:C++中类中变量不能为virtual,只能是函数才可以用virtual修饰。这也许是java中要如此分开对待的原因吧。
public class t2 {
public static void main(String args[]) {
F p = new S();
System.out.println(p.i); // 1 父亲中的变量
p.pr(); // In S... 儿子的方法
}
}

class F {
int f;
int i;
F() {
;
}
void pr()
{ System.out.println("In F..."); }
}

class S extends F {
int s;
int i;
S() {
super.i = 1;
i = 2;
}
void pr()
{ System.out.println("In S..."); }
}

例2:
public class t2 {
public static void main(String args[]) {
F p1 = new S();
System.out.println(p1.i); // 1

S p2 = new S();
System.out.println(p2.i); // 2
}
}
class F {
int f;
int i;
F() {
;
}
}
class S extends F {
int s;
int i;
S() {
super.i = 1;
i = 2;
}
}
❁抽象abstract:
子类必须实现父类中所有的抽象函数。
包含一个或多个抽象方法的任何类也必须被声明为抽象的。
不能声明抽象构造函数或抽象静态方法。
抽象类虽不可被实例化,但可以被用来创建对象引用。
同C++中virtual类似,abstract不能用来修饰类中变量,而只能是函数。

没有评论: