??xml version="1.0" encoding="utf-8" standalone="yes"?>久久中文视频,最新国产精品视频,国产一区二区三区不卡视频网站http://www.aygfsteel.com/NewMoring/articles/268600.html清晨清晨Sat, 02 May 2009 04:38:00 GMThttp://www.aygfsteel.com/NewMoring/articles/268600.htmlhttp://www.aygfsteel.com/NewMoring/comments/268600.htmlhttp://www.aygfsteel.com/NewMoring/articles/268600.html#Feedback0http://www.aygfsteel.com/NewMoring/comments/commentRss/268600.htmlhttp://www.aygfsteel.com/NewMoring/services/trackbacks/268600.html一个新对象的初始化的最l步骤是去调用对象的构造方法?

构造方法必L以下条Ӟ

l. Ҏ(gu)名必McdU完全相匚wQ?

2. 不要声明q回cdQ?

3. 不能被static、final、synchronized、abstract、native修饰?

下列代码中的构造方法都是合法的?

public class Xyz {

public Xyz() { // No-arg constructor

// set up the object.

}

public Xyz(int x) { //int-arg constructor

// set up the object using the parameter x.

}

}

5.2.2 重蝲构造方?

如果有一个类带有几个构造方法,那么也许会想复制其中一个构造方法的某些操作到另一个构造方法中。可以通过使用关键字this作ؓ一个方法调用来辑ֈq个目的。不能通过Ҏ(gu)名直接调用构造方法?

public class Employee {

private String name;

private int salary;

public Employee(String n, int s) {

name = n;

salary = s;

}

public Employee(String n) {

this(n, 0);

}

public Employee() {

this( " Unknown " );

}

}

在第二个构造方法中Q有一个字W串参数Q调用this(n,0)控制权传递到构造方法的另一个版本,即采用了一个String参数和一个int参数的构造方法?

在第三个构造方法中Q它没有参数Q调用this("Unknownn")控制权传递到构造方法的另一个版本,即采用了一个String参数的构造方法?

对于this的Q何调用,如果出现在Q何构造方法中Q必M为第一个语句?

5.2.3 ~省构造方?

~省构造方法是没有参数的构造方法,你可以显式定义类的缺省构造方法?

Z保证每个c至有一个构造方法,如果定义的类中一个构造方法也没有写,Java自动提供一个缺省构造方法。该构造方法没有参敎ͼ用public 修饰Q而且Ҏ(gu)体ؓI。格式如下:

public ClassName(){}

只要cM昑ּ定义了一个或多个构造方法,而且所有显式定义的构造方法都带参敎ͼ那么失ȝ省构造方法?

举例如下Q?

public class Sample1{}

public class Sample2

{

public Sample2(int a){System.out.println("My Constructor");}

}

public class Sample3

{

public Sample3(){System.out.println("My Default Constructor");}

}

可以调用Sample1的缺省构造方法来创徏Sample1对象?

Sample1 s=new Sample1();

Sample2cȝ~省构造方法失效,因此以下的创建Sample2对象的方法编译会出错?

Sample2 s=new Sample2();

正确的创建方法是Q?

Sample2 s=new Sample2(0);

Sample3cd义了自己的缺省构造方法,因此以下语句是合法的?

Sample3 s=new Sample3();

5.2.4 子类调用父类的构造方?

父类的构造方法不能被子类l承。子cM能直接通过Ҏ(gu)名调用父cȝ一个构造方法,而是要通过super关键字调用父cȝ一个构造方法,super语句必须位于子类构造方法的W一行?

例如Q?

/**

* Son.java

*/

class GrandPa

{

protected GrandPa()

{

System.out.println("default GrandPa");

}

public GrandPa(String name)

{

System.out.println(name);

}

}

class Father extends GrandPa

{

protected Father()

{

System.out.println("default Father");

}

public Father(String grandPaName,String fatherName)

{

super(grandPaName);

System.out.println(fatherName);

}

}

public class Son extends Father

{

public Son()

{

System.out.println("default Son");

}

public Son(String grandPaName,String fatherName,String sonName)

{

super(grandPaName,fatherName);

System.out.println(sonName);

}

public static void main(String args[])

{

Son s1=new Son();

Son s2= new Son("My GrandPa", "My Father", "My Son");

}

}

执行语句Q?

Son s2=new Son("My GrandPa", "My Father", "My Son");

会输出如下l果Q?

My GrandPa

My Father

My Son

当子cȝ某个构造方法没有调用父cȝ一个构造方法,通过q个构造方法创建子cd象时Q会自动先调用父cȝ~省构造方法。对于多U承,执行~省构造方法的序是从最上层的类开始?

对于以上的代码执行语句Son s1=new Son();

会输出如下l果Q?

default GrandPa

default Father

default Son

当子cȝ某个构造方法没有调用父cȝ一个构造方法,而父cd没有提供~省构造方法时Q将会出现编译错误?

例如Q修改一下Son.java文g。去掉GrandPacM昑ּ定义的缺省构造方法:

protected GrandPa()

{

System.out.println("default GrandPa");

}

q样QGrandPacM失M~省构造方法,q时Q在~译Fathercȝ~省构造方法时Q因为找不到GrandPacȝ~省构造方法而出错?

子类的某个构造方法没有通过super语句调用父类的构造方法,而是通过this语句调用了另一个构造方法,而在另一个构造方法中通过super语句调用了父cȝ构造方法,q种情况下,父类的缺省构造方法不会被调用?

例如Q?

class A

{

A(int i){}

}

class B extends A

{

B(){this(0);}

B(int i){super(i);}

}

对于new B()语句依ơ执行如下方法:

1QA(int) 2QB(int) 3QB()

5.2.5 构造方法的作用?

构造方法只能被所在类的其他构造方法或子类的构造方法调用,或在用new语句创徏cȝ实例时被调用。引用类型的变量不能讉K对象的构造方法?

对于以下代码Q请读者自己分析某些语句编译出错的原因?

class Base

{

public Base(int i,int j){}

public Base(int i){

this(i,0); //CORRECT

Base(i,0); //ERROR

}

}

class Sub extends Base

{

public Sub(int i,int j)

{

super(i,0); //CORRECT

}

void method1(int i,int j)

{

this(i,j); //ERROR

Sub(i,j); //ERROR

}

void method2(int i,int j)

{

super(i,j); //ERROR

}

void method3(int i,int j)

{

Base sQnew Base(0,0); //CORRECT

s.Base(0,0); //ERROR

}

}

5.2.6 构造方法不能被l承

构造方法可以被子类的构造方法调用,但不能被子类l承?

例如Q?

class A

{

A(int i){};

A(){}

}

class B extends A{}

class C extends B

{

C(){

super.super(0); //COMPILE ERROR

A(0); //COMPILE ERROR

}

}

׃cBq没有承类A的构造方法A(int i)Q所以在构造方法C()中调用类A的构造方法是非法的?

5.2.7 考察要点

l 识别合法的构造方法;

2 构造方法可以被重蝲Q一个构造方法可以通过this关键字调用另一个构造方法,this语句必须位于构造方法的W一行;

3 当一个类中没有定义Q何构造方法,Java自动提供一个缺省构造方法;

4 子类通过super关键字调用父cȝ一个构造方法;

5 当子cȝ某个构造方法没有通过super关键字调用父cȝ构造方法,通过q个构造方法创建子cd象时Q会自动先调用父cȝ~省构造方?

6 构造方法不能被static、final、synchronized、abstract、native修饰Q但可以被public、private、protected修饰Q?

7 构造方法不是类的成员方法;

8 构造方法不能被l承?

5.2.8 试题解析

1QWhich line contains a constructor in this class definition?

public class Counter { // (a)

int current, step;

public Counter(int startValue, int stepValue) { // (b)

set(startValue);

setStepValue(stepValue);

}

public int get() { return current; } // (c)

public void set(int value) { current = value; } // (d)

public void setStepValue(int stepValue) { step = stepValue; } // (e)

}

a) Code marked with (a) is a constructor

b) Code marked with (b) is a constructor

c) Code marked with (c) is a constructor

d) Code marked with (d) is a constructor

e) Code marked with (e) is a Constructor

{案Qb

解析Q类的构造方法必遵循以下规则:Ҏ(gu)名和cd名,无返回倹{一个方法同时满两个条gQJava~译器就会将其当作类的构造方法。一个方法如果只满其中的一个条Ӟ会~译出错Q被认ؓ是不合法的方法声明?

2QWhich of the following can be applied to constructors:

a) final

b) static

c) synchronized

d) native

e) None of these.

{案Qe

解析Q构造方法不能被子类l承Q所以用final修饰没有意义。构造方法用于创Z个新的对象,不能作ؓcȝ静态方法,所以用static修饰没有意义。此外,Java语言不支持native或synchronized的构造方法?

3QWhat will happen when you attempt to compile and run the following code .

public class Hope{

public static void main(String argv[]){

Hope h = new Hope();

}

protected Hope(){

for(int i =0; i <10; i ++){

System.out.println(i);

}

}

}

a) Compilation error: Constructors cannot be declared protected

b) Run time error: Constructors cannot be declared protected

c) Compilation and running with output 0 to 10

d) Compilation and running with output 0 to 9

{案Qd

解析Q构造方法可以被public、protected、private修饰?

4QWhat will happen if you try to compile and execute B´s main() method?

class A {

int i;

A(int i) {

this.i = i * 2;

}

}

class B extends A {

public static void main(String[] args) {

B b = new B(2);

}

B(int i) {

System.out.println(i);

}

}

Select the one right answer.

a) The instance variable i is set to 4

b) The instance variable i is set to 2

c) The instance variable i is set to 0

d) This code will not compile

{案Qd

解析Q由于类B的构造方法B(int i)中没有调用父cȝ构造方法,而父cM又没有缺省构造方法,D~译错误?

5QWhat happens when you try to compile and run the following program?

class Mystery {

String s;

public static void main(String[] args) {

Mystery m = new Mystery();

m.go();

}

void Mystery() {

s = "constructor";

}

void go() {

System.out.println(s);

}

}

Select the one right answer.

a) this code will not compile

b) this code compiles but throws an exception at runtime

c) this code runs but nothing appears in the standard output

d) this code runs and "constructor" in the standard output

e) this code runs and writes "null" in the standard output

{案Qe

解析Q这道题中故意设|了一个陷阱,定义了一个貌似构造方法的Mystery()Ҏ(gu)。由于它被声明了q回cdQ所以其实不是构造方法。new Mystery()语句其实调用的是cMystery的缺省构造方法?

6QYes or No?

Statement1) If you create a non-default derived constructor and don´t call the base class constructor Qthe compiler will call the default base class constructor automatically. (Assume that the default constructor is defined for the base class).

Statement2) What about if it is not defined?

Statement3) What about the case of a default derived constructor, does the compiler

call the default base class constructor

a) Yes ,No,Yes

b) Yes,No,No

{案Qa

解析Q子cȝ构造方法中如果没有调用父类的构造方法,E序q行时会自动先调用父cȝ~省构造方法(包括自动提供的缺省构造方法或昑ּ定义的缺省构造方法)。如果父cL有缺省构造方法,会~译出错?

7QGiven the following code how could you invoke the Base constructor that will print out the string "base constructor";

class Base{

Base(int i){

System.out.println("base constructor");

}

Base(){

}

}

public class Sup extends Base{

public static void main(String argv[]){

Sup s= new Sup();

//One

}

Sup()

{

//Two

}

public void derived()

{

//Three

}

}

a) On the line After //One put Base(10);

b) On the line After //One put super(10);

c) On the line After //Two put super(10);

d) On the line After //Three put super(10);

{案Qc

解析Q构造方法只能被所在类的其他构造方法或子类的构造方法调用。所以在//one?/three处调用构造方法都是非法的?

8QTrue or False.

The Class class has no public constructor.

a) True

b) False

{案Qa

解析QClasscL有公共构造方法,所以Classcȝ对象不能在程序中通过构造方法创建。当Java虚拟载某个类Q假如类名是ClassSampleQ的时候,会自动调用JVM的类装蝲器的defineClass()Ҏ(gu)Q这个方法会创徏和某个类ClassSample相关的Classcȝ对象。ObjectcL个方法getClass()Q它q回一个Classcȝ对象。所以,所有的Java对象都可以通过Ҏ(gu)getClass()获得它的Classcȝ对象。例如:

ClassSample sQnew ClassSample();

System.out.println(s.getClass().getName());

会打印ClassSample?

9QWhich statements concerning the following code are true?

class A {

public A() {}

public A(int i) { this(); }

}

class B extends A {

public boolean B(String msg) { return false; }

}

class C extends B {

private C() { super(); }

public C(String msg) { this(); }

public C(int i) {}

}

a) The code will fail to compile.

b) The constructor in A that takes an int as an argument will never be called as a result of constructing an object of class B or C.

c) Class C has three constructors.

d) Objects of class B cannot be constructed.

e) At most one of the constructors of each class is called as a result of constructing an object of class C.

{案QbQc

解析Q在cB中定义的Ҏ(gu)B()有返回|所以它不是构造方法。类B只有一个缺省构造方法,所以创建类B或类C的对象时Q会先调用类B的缺省构造方法,而类B的缺省构造方法会先调用类C的缺省构造方法,cA的构造方法A(int i)永远不会被调用。选项e是不正确的,new C("hello")语句调用类C的两个构造方法C()和C(String msg)?

10QWhich of the following code fragments are legal?

a) class MusicWork {

MusicWork(String s) {

System.out.println("The name of this work is" + s);

}

}

class ClassicalWork extends MusicWork {

ClassicalWork(String s, String composer) {

System.out.println("The composer is " + composer);

}

}

b) class MusicWork {

MusicWork(String s) {

System.out.println("The name of this work is" + s);

}

}

class ClassicalWork extends MusicWork {

ClassicalWork(String s, String composer) {

super(s);

System.out.println("The composer is " + composer);

}

}

c) class MusicWork {

MusicWork(String s) {

System.out.println("The name of this work is" + s);

}

}

class ClassicalWork extends MusicWork {

ClassicalWork(String s, String composer) {

System.out.println("This is a work of classical music");

System.out.println("The composer is " + composer);

super(s);

}

}

d) class MusicWork {

MusicWork() {

System.out.println("This is a work of music");

}

MusicWork(String name) {

this();

System.out.println("The name of this work is" + name);

}

}

e) class MusicWork {

MusicWork() {

System.out.println("This is a work of music");

}

MusicWork(String name) {

this();

System.out.println("The name of this work is" + name);

}

MusicWork(String composer) {

this();

System.out.println("The composer of this work is" + composer);

}

}

f) class MusicWork {

MusicWork() {

System.out.println("This is a work of music");

}

MusicWork(String name) {

System.out.println("The name of this work is" + name);

this();

}

}

{案QbQd

解析Q选项a中必Mؓ父类提供~省构造方法。选项c中没有把super语句攑֜构造方法的W一行。选项e中有两个Music(String)构造方法,不合法。选项f中没有把this语句攑֜构造方法的W一行?

11QGiven the following class definition which of the following can be legally placed after the comment line//Here ?

class Base{

public Base(int i){}

}

public class MyOver extends Base{

public static void main(String arg[]){

MyOver m = new MyOver(10);

}

MyOver(int i){

super(i);

}

MyOver(String s, int i){

this(i);

//Here

}

}

a) MyOver m = new MyOver();

b) super();

c) this("Hello",10);

d) Base b = new Base(10);

{案Qd

解析Q类MyOver没有~省构造方法,所以选项a不正?/p>

清晨 2009-05-02 12:38 发表评论
]]>
Java的子c调用父cȝ构造方法,构造方法的相关问题http://www.aygfsteel.com/NewMoring/articles/268599.html清晨清晨Sat, 02 May 2009 04:34:00 GMThttp://www.aygfsteel.com/NewMoring/articles/268599.htmlhttp://www.aygfsteel.com/NewMoring/comments/268599.htmlhttp://www.aygfsteel.com/NewMoring/articles/268599.html#Feedback0http://www.aygfsteel.com/NewMoring/comments/commentRss/268599.htmlhttp://www.aygfsteel.com/NewMoring/services/trackbacks/268599.html11.2.1 重蝲构造方?
11.2.2 默认构造方?
11.2.3 子类调用父类的构造方?
11.2.4 构造方法的作用?
11.2.5 构造方法的讉KU别

从上一节可以看出,在多数情况下Q初始化一个对象的最l步骤是去调用这个对象的构造方法。构造方法负责对象的初始化工作,为实例变量赋予合适的初始倹{构造方法必L以下语法规则:
(1) Ҏ(gu)名必Mcd相同?br /> (2)不要声明q回cd?br /> (3)不能被static、final、synchronized、abstract和native修饰。构造方法不能被子类l承Q所以用final?/p>

abstract修饰没有意义。构造方法用于初始化一个新建的对象Q所以用static修饰没有意义。多个线E不会同时创建内存地址相同的同一个对象,因此用synchronized修饰没有必要。此外,Java语言不支持nativecd的构造方法?br /> 在以下SamplecMQ具有intq回cd的Sample(int x)Ҏ(gu)只是个普通的实例Ҏ(gu)Q不能作为构造方法:
public class Sample {
private int x;
public Sample() { // 不带参数的构造方?br /> this(1);
}
public Sample(int x) { //带参数的构造方?br /> this.x=x;
}
public int Sample(int x) { //不是构造方?br /> return x++;
}
}

以上例子管能编译通过Q但是把实例Ҏ(gu)和构造方法同名,不是好的~程习惯Q容易引h؜淆。例如以下MysterycȝMystery()Ҏ(gu)有voidq回cdQ因此是普通的实例Ҏ(gu)Q?br />

public class Mystery {
private String s;
public void Mystery() { //不是构造方?br /> s = "constructor";
}
void go() {
System.out.println(s);
}
public static void main(String[] args) {
Mystery m = new Mystery();
m.go();
}
}


以上E序的打印结果ؓnull。因为用new语句创徏Mystery实例Ӟ调用的是Mysterycȝ默认构造方法,而不是以上有voidq回cd的Mystery()Ҏ(gu)。关于默认构造方法的概念Q参见本章第11.2.2节(默认构造方法)?br />

11.2.1 重蝲构造方?/strong>

当通过new语句创徏一个对象时Q在不同的条件下Q对象可能会有不同的初始化行为。例如对于公司新q来的一个雇员,在一开始的时候,有可能他的姓名和q龄是未知的Q也有可能仅仅他的姓名是已知的,也有可能姓名和年龄都是已知的。如果姓名是未知的,暂且把姓名设ؓ"无名?Q如果年龄是未知的,暂且把q龄设ؓ-1?br /> 可通过重蝲构造方法来表达对象的多U初始化行ؓ。以下例E?1-2的Employeecȝ构造方法有三种重蝲形式。在一个类的多个构造方法中Q可能会出现一些重复操作。ؓ了提高代码的可重用性,Java语言允许在一个构造方法中Q用this语句来调用另一个构造方法?br />

例程11-2 Employee.java
public class Employee {
private String name;
private int age;

/** 当雇员的姓名和年龄都已知Q就调用此构造方?*/
public Employee(String name, int age) {
this.name = name;
this.age=age;
}

/** 当雇员的姓名已知而年龄未知,p用此构造方?*/
public Employee(String name) {
this(name, -1);
}

/** 当雇员的姓名和年龄都未知Q就调用此构造方?*/
public Employee() {
this( "无名? );
}
public void setName(String name){this.name=name; }
public String getName(){return name; }
public void setAge(int age){this.age=age;}
public int getAge(){return age;}
}


以下E序分别通过三个构造方法创Z三个Employee对象Q?br />

Employee zhangsan=new Employee("张三",25);
Employee lisi=new Employee("李四");
Employee someone=new Employee();


在Employee(String name)构造方法中Qthis(name,-1)语句用于调用Employee(String name,int age)构造方法。在Employee()构造方法中Qthis("无名?)语句用于调用Employee(String name)构造方法?br /> 用this语句来调用其他构造方法时Q必遵守以下语法规则:

Q?Q假如在一个构造方法中使用了this语句Q那么它必须作ؓ构造方法的W一条语句(不考虑注释语句Q。以下构造方法是非法的:
public Employee(){
String name="无名?;
this(name); //~译错误Qthis语句必须作ؓW一条语?br /> }
Q?Q只能在一个构造方法中用this语句来调用类的其他构造方法,而不能在实例Ҏ(gu)中用this语句来调用类的其他构造方法?br /> Q?Q只能用this语句来调用其他构造方法,而不能通过Ҏ(gu)名来直接调用构造方法。以下对构造方法的调用方式是非法的Q?br /> public Employee() {
String name= "无名?;
Employee(name); //~译错误Q不能通过Ҏ(gu)名来直接调用构造方?br /> }


11.2.2 默认构造方?/strong>


默认构造方法是没有参数的构造方法,可分ZU:Q?Q隐含的默认构造方法(2Q程序显式定义的默认构造方法?br /> 在Java语言中,每个c至有一个构造方法。ؓ了保证这一点,如果用户定义的类中没有提供Q何构造方法,那么Java语言自动提供一个隐含的默认构造方法。该构造方法没有参敎ͼ用public 修饰Q而且Ҏ(gu)体ؓI,格式如下Q?br />

public ClassName(){} //隐含的默认构造方?br />

在程序中也可以显式的定义默认构造方法,它可以是L的访问别。例如:

protected Employee() { //E序昑ּ定义的默认构造方?br /> this("无名?);
}

如果cM昑ּ定义了一个或多个构造方法,q且所有的构造方法都带参敎ͼ那么q个cd失去了默认构造方法。在以下E序中,Sample1cL一个隐含的默认构造方法,Sample2cL有默认构造方法,Sample3cL一个显式定义的默认构造方法:

public class Sample1{}
public class Sample2{
public Sample2(int a){System.out.println("My Constructor");}
}

public class Sample3{
public Sample3(){System.out.println("My Default Constructor");}
}


可以调用Sample1cȝ默认构造方法来创徏Sample1对象Q?br />

Sample1 s=new Sample1(); //合法
Sample2cL有默认构造方法,因此以下语句会导致编译错误:
Sample2 s=new Sample2(); //~译出错
Sample3cL式定义了默认构造方法,因此以下语句是合法的?br /> Sample3 s=new Sample3();


11.2.3 子类调用父类的构造方?/strong>


父类的构造方法不能被子类l承。以下MyExceptioncȝ承了java.lang.Exceptionc:

public class MyException extends Exception{} // MyExceptioncd有一个隐含的默认构造方?br />

管在ExceptioncM定义了如下Ş式的构造方法:

public Exception(String msg)

但MyExceptioncM会承以上Exceptioncȝ构造方法,因此以下代码是不合法的:

//~译出错QMyExceptioncM存在q样的构造方?br /> Exception e=new MyException("Something is error");

在子cȝ构造方法中Q可以通过super语句调用父类的构造方法。例如:
public class MyException extends Exception{
public MyException(){
//调用Exception父类的Exception(String msg)构造方?br /> super("Something is error");
}

public MyException(String msg){
//调用Exception父类的Exception(String msg)构造方?br /> super(msg);
}
}

用super语句来调用父cȝ构造方法时Q必遵守以下语法规则?br /> Q?Q在子类的构造方法中Q不能直接通过父类Ҏ(gu)名调用父cȝ构造方法,而是要用super语句Q以下代码是非法的:
public MyException(String msg){
Exception(msg); //~译错误
}

Q?Q假如在子类的构造方法中有super语句Q它必须作ؓ构造方法的W一条语句,以下代码是非法的Q?/p>


public MyException(){
String msg= "Something wrong";
super(msg); //~译错误Qsuper语句必须作ؓ构造方法的W一条语?br /> }

在创建子cȝ对象ӞJava虚拟机首先执行父cȝ构造方法,然后再执行子cȝ构造方法。在多l承的情况下Q将从承树的最上层的父cd始,依次执行各个cȝ构造方法,q可以保证子cd象从所有直接或间接父类中承的实例变量都被正确的初始化。例如以下Base父类和Sub子类分别有一个实例变?a和bQ当构造Sub实例Ӟq两个实例变量都会被初始化?br />

public class Base{
private int a;
public Base(int a){ this.a=a;}
public int getA(){return a;}
}
public class Sub extends Base{
private int b;
public Base(int a,int b){super(a); this.b=b;}
public int getB(){return b;}

public static void main(String args[]){
Sub sub=new Sub(1,2);
System.out.println("a="+sub.getA()+" b="+sub.getB()); //打印a=1 b=2
}
}
在以下例E?1-3QSon.javaQ中QSoncȝ承Fatherc,Fathercȝ承GrandpacR这三个c都昑ּ定义了默认的构造方法,此外q定义了一个带参数的构造方法?/p>


例程11-3 Son.java
class Grandpa{
protected Grandpa(){
System.out.println("default Grandpa");
}
public Grandpa(String name){
System.out.println(name);
}
}

class Father extends Grandpa{
protected Father(){
System.out.println("default Father");
}

public Father(String grandpaName,String fatherName){
super(grandpaName);
System.out.println(fatherName);
}
}

public class Son extends Father{
public Son(){
System.out.println("default Son");
}

public Son(String grandpaName,String fatherName,String sonName){
super(grandpaName,fatherName);
System.out.println(sonName);
}

public static void main(String args[]){
Son s1= new Son("My Grandpa", "My Father", "My Son"); //?br /> Son s2=new Son(); //?br /> }
}
执行以上main()Ҏ(gu)的第①条语句Q打印结果如下:
My Grandpa
My Father
My Son

此时构造方法的执行序如图11-1所C?/p>

?1-1 调用Soncȝ带参数的构造方法时所有构造方法的执行序

当子cȝ构造方法没有用super语句昑ּ调用父类的构造方法,那么通过q个构造方法创建子cd象时QJava虚拟Z自动先调用父cȝ默认构造方法。执行以上Soncȝmain()Ҏ(gu)的第②条语句Q打印结果如下:
default Grandpa
default Father
default Son

此时构造方法的执行序如图11-2所C?/p>

?1-2 调用Soncȝ默认构造方法时所有构造方法的执行序

当子cȝ构造方法没有用super语句昑ּ调用父类的构造方法,而父cd没有提供默认构造方法时Q将会出现编译错误。例如把例程11-3做适当修改Q删除GrandpacM昑ּ定义的默认构造方法:

// protected Grandpa(){
// System.out.println("default GrandPa");
// }

q样QGrandpacd失去了默认构造方法,q时Q在~译Fathercȝ默认构造方法时Q因为找不到Grandpacȝ默认构造方法而编译出错。如果把Grandpacȝ默认构造方法的protected讉KU别改ؓprivate讉KU别Q也会导致编译错误,因ؓFathercȝ默认构造方法无法访问GrandpacȝU有默认构造方法?br /> 在以下例子中Q子cSub的默认构造方法没有通过super语句调用父类的构造方法,而是通过this语句调用了自w的另一个构造方法Sub(int i)Q而在Sub(int i)中通过super语句调用了父cBase的Base(int i)构造方法。这P无论通过Subcȝ哪个构造方法来创徏Sub实例Q都会先调用父类Base的Base(int i)构造方法?br />

class Base{
Base(int i){System.out.println("call Base(int i)");}
}
public class Sub extends Base{
Sub(){this(0); System.out.println("call Sub()");}

Sub(int i){super(i); System.out.println("call Sub(int i)");}
public static void main(String args[]){
Sub sub=new Sub();
}
}
执行以上Subcȝmain()Ҏ(gu)的new Sub()语句Q打印结果如下:
call Base(int i)
call Sub(int i)
call Sub()
此时构造方法的执行序如图11-3所C?br />


?1-3 调用Subcȝ默认构造方法时所有构造方法的执行序
在下面的例子中,BasecM没有定义M构造方法,它实际上有一个隐含的默认构造方法:
Base(){}
SubcȝSub(int i)构造方法没有用super语句昑ּ调用父类的构造方法,因此当创建Sub实例Ӟ会先调用Base父类的隐含默认构造方法?
class Base{} //h隐含默认构造方?br /> public class Sub extends Base{
Sub(int i){System.out.println(i);}
public static void main(String args[]){
System.out.println(new Sub(1)); //打印1
}
}

11.2.4 构造方法的作用?/strong>
构造方法只能通过以下方式被调用:
(1) 当前cȝ其他构造方法通过this语句调用它?br /> (2) 当前cȝ子类的构造方法通过super语句调用它?br /> (3)在程序中通过new语句调用它?br /> 对于例程11-4QSub.javaQ的代码Q请读者自己分析某些语句编译出错的原因?br />

例程11-4 Sub.java
class Base{
public Base(int i,int j){}
public Base(int i){
this(i,0); //合法
Base(i,0); //~译出错
}
}

class Sub extends Base{
public Sub(int i,int j){
super(i,0); //合法
}

void method1(int i,int j){
this(i,j); //~译出错
Sub(i,j); //~译出错
}
void method2(int i,int j){
super(i,j); //~译出错
}
void method3(int i,int j){
Base s=new Base(0,0); //合法
s.Base(0,0); //~译出错
}
}

11.2.5 构造方法的讉KU别
构造方法可以处于public、protected、默认和privateq四U访问别之一。本节着重介l构造方法处于privateU别的意义?br /> 当构造方法ؓprivateU别Q意味着只能在当前类中访问它Q在当前cȝ其他构造方法中可以通过this语句调用它,此外q可以在当前cȝ成员Ҏ(gu)中通过new语句调用它?br /> 在以下场合之一Q可以把cȝ所有构造方法都声明为privatecd?br /> Q?Q在q个cM仅仅包含了一些供其他E序调用的静态方法,没有M实例Ҏ(gu)。其他程序无需创徏该类的实例,p讉Kcȝ静态方法。例?java.lang.MathcdW合q种情况Q在MathcM提供了一pd用于数学q算的公共静态方法,Z止外部E序创徏Mathcȝ实例Q?Mathcȝ惟一的构造方法是privatecd的:

private Math(){}

在第7章的7.2节(abstract修饰W)提到q,abstractcd的类也不允许实例化。也怽会问Q把Mathcd义ؓ如下abstractcdQ不是也能禁止Mathc被实例化吗Q?br />

public abstract class Math{…}

如果一个类是抽象类Q意味着它是专门用于被承的c,可以拥有子类Q而且可以创徏具体子类的实例。而JDKq不希望用户创徏Mathcȝ子类Q在q种情况下,把类的构造方法定义ؓprivatecd更合适?br />

Q?Q禁止这个类被ѝ当一个类的所有构造方法都是privatecdQ假如定义了它的子类Q那么子cȝ构造方法无法调用父cȝM构造方法,因此会导致编译错误。在W?章的7.3.1节(finalc)提到q,把一个类声明为finalcdQ也能禁止这个类被ѝ这两者的区别是:
1)如果一个类允许其他E序用new语句构造它的实例,但不允许拥有子类Q那把cd明ؓfinalcd?br /> 2)如果一个类既不允许其他E序用new语句构造它的实例,又不允许拥有子类Q那把cȝ所有构造方法声明ؓprivatecd?/p>


׃大多数类都允许其他程序用new语句构造它的实例,因此用final修饰W来止c被l承的做法更常见?br />

Q?Q这个类需要把构造自w实例的l节装hQ不允许其他E序通过new语句创徏q个cȝ实例Q这个类向其他程序提供了获得自n实例的静态方法,q种Ҏ(gu)UCؓ静态工厂方法,本章W?1.3节(静态工厂方法)Ҏ(gu)作了q一步的介绍?/p>

清晨 2009-05-02 12:34 发表评论
]]>
վ֩ģ壺 ϽϽ| Ӷ| | | ţ| | | | | ǭ| ˳| żҸ| | Ҿ| ӡ| | Դ| ÷| ƽ| | | | ԭ| ƽ| | | | ʼ| | DZ| | | ɽ| ֦| Ӧñر| | | | ͤ| ƽ| ˮ|