前几天在学习和使用多线程时,意外的发现java中的构造方法可以使用私有修饰符---private 我们都知道public的构造方法,子类实例化时是会运行父类的构造函数的,但是如果父类的构造函数是private私有的,子类怎么去调用呢?我们先来看看代码吧
我们先定义一个类,创建一个私有构造函数
package com.rim.org.day01.test06;
public class PrivateMethod {
private PrivateMethod(){
System.out.println("父类的私有构造函数");
}
}
然后我们创建一个新的类,去继承父类
package com.rim.org.day01.test06;
public class SonOfPrivateMethod extends PrivateMethod {
private SonOfPrivateMethod(){
System.out.println("Hello");
}
}
这里编辑器报了个错,子类没有找到默认的构造方法
那么一个类如果创建一个私有的构造函数,具体是做什么用呢?
通过私有的构造函数强化不可实例化的能力.
在面向对象程序设计中,假如存在太多只有静态属性和静态方法的类;那么,面向对象的思想可能在这块会损失殆尽。
但是,并不能说面向对象的程序中就不应该出现只有静态属性和静态方法的类,相反,有时候我们还必须写这样的类作为工具类。
这样的类怎么实现呢?有人可能会把该类定义成抽象类(Abstract class),的确,抽象类是不可以实例化的,但是别忘了还有继承,
继承了抽象类的子类在实例化时候,默认是会先调用父类无参数的构造函数的(super();),这时候,父类不是也被实例化了嘛?
其实我们可以这样做,把该类的构造函数定义为私有的(private),而类的内部又不调用该构造函数的话,就成功了。
这样带来的后果就是该类成了 final的,不可能再被任何类继承了,要被继承,得提供一个公有(public)的或者保护(protect)的构造函数, 这样才能被子类调用。
但是创建私有构造函数并不能阻止该类被继承,我们看下下面的例子:
class Single {
private Single(){
System.out.println("Single");
}
public void runSingleMethod()
{
System.out.println("runSingleMethod");
}
public static class Evil extends Single
{
public Evil(){
System.out.println("Evil");
}
}
}
public class SingleTest extends Single.Evil
{
public SingleTest()
{
System.out.println("normal");
}
public static void main(String[] args) {
SingleTest a = new SingleTest();
a.runSingleMethod();
}
}
我们在父类中创建一个内部static类,且该类继承了父类,并且创建了子类自己的无参构造函数
然后我们再创建一个类来测试下,看看static子类能不能调用父类中的另外一个方法
可以看到,实例化父类后,是可以调用子类的。
我们运行下试试,看看能不能打印出
即使父这类是私有构造函数,子类也可以继承 这句话
父类的私有构造函数
即使父类是私有构造函数,子类也可以继承
runPrivateMethod方法
可以看到,不仅打印出来了,还打印出来了自己的构造函数的方法,还有父类中的另外一个方法
说明: 要阻止继承,还是得靠关键字 final,无论是内部类还是子类,都是无法继承 final类的。对于工具类,最好还是用final修饰符来修饰
好的,今天先到这里,枚举类型等明天再说