<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />11.2.4 构造方法的作用域<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
构造方法只能通过以下方式被调用:
当前类的其他构造方法通过
this
语句调用它。
当前类的子类的构造方法通过
super
语句调用它。
在程序中通过
new
语句调用它。
对于例程
11-4
(
Sub.java
)的代码,请读者自己分析某些语句编译出错的原因。
例程
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 构造方法的访问级别
构造方法可以处于
public
、
protected
、
private
和默认这
4
种访问级别之一。本节着重介绍构造方法处于
private
级别的意义。
当构造方法为
private
级别时,意味着只能在当前类中访问它:在当前类的其他构造方法中可以通过
this
语句调用它,此外还可以在当前类的成员方法中通过
new
语句调用它。
在以下场合之一,可以把类的所有构造方法都声明为
private
类型。
(
1
)在这个类中仅仅包含了一些供其他程序调用的静态方法,没有任何实例方法。其他程序无须创建该类的实例,就能访问类的静态方法。例如
java.lang.Math
类就符合这种情况,在
Math
类中提供了一系列用于数学运算的公共静态方法,为了禁止外部程序创建
Math
类的实例,
Math
类的惟一的构造方法是
private
类型的。
private Math(){}
在第
7
章的
7.2
节(
abstract
修饰符)提到过,
abstract
类型的类也不允许实例化。也许你会问,把
Math
类定义为如下
abstract
类型,不是也能禁止
Math
类被实例化吗?
public abstract class Math{…}
如果一个类是抽象类,意味着它是专门用于被继承的类,可以拥有子类,而且可以创建具体子类的实例。而
JDK
并不希望用户创建
Math
类的子类,在这种情况下,把类的构造方法定义为
private
类型更合适。
(
2
)禁止这个类被继承。当一个类的所有构造方法都是
private
类型的时,假如定义了它的子类,那么子类的构造方法无法调用父类的任何构造方法,因此会导致编译错误。在第
7
章的
7.3.1
节(
final
类)中提到过,把一个类声明为
final
类型,也能禁止这个类被继承。这两者的区别是:
如果一个类允许其他程序用
new
语句构造它的实例,但不允许拥有子类,那么就把类声明为
final
类型。
如果一个类既不允许其他程序用
new
语句构造它的实例,又不允许拥有子类,那么就把类的所有构造方法声明为
private
类型。
由于大多数类都允许其他程序用
new
语句构造它的实例,因此用
final
修饰符来禁止类被继承的做法更常见。
(
3
)这个类需要把构造自身实例的细节封装起来,不允许其他程序通过
new
语句创建这个类的实例。这个类向其他程序提供了获得自身实例的静态方法,这种方法称为静态工厂方法,本章第
11.3
节(静态工厂方法)对此做了进一步的介绍。
转载于:https://blog.51cto.com/1988wlpznn/168518