zoukankan      html  css  js  c++  java
  • Java_构造方法私有化

    3.5、构造方法私有化(重点)

             在讲解本操作之前,首先来观察如下的程序。

    class Singleton { // 定义一个类

             public void print() {

                       System.out.println("Hello World .") ;

             }

    }

    public class Test {

             public static void main(String args[]) {

                       Singleton inst = null ;   // 声明对象

                       inst = new Singleton() ;         // 实例化对象

                       inst.print() ;         // 调用方法

             }

    }

             在以上的程序之中,Singleton类里面是存在构造方法的(因为如果一个类之中没有明确的定义一个构造方法的话,则会自动生成一个无参的,什么都不做的构造方法),但是下面要将构造方法改变一下。

    class Singleton { // 定义一个类

             private Singleton() {} // 构造方法私有化

             public void print() {

                       System.out.println("Hello World .") ;

             }

    }

             现在发现在实例化Singleton类对象的时候,程序出现了编译错误,因为构造方法被私有化了,无法在外部调用,即:无法在外部实例化Singleton类的对象。

             那么现在就需要思考:在保证Singleton类之中的构造方法不修改不增加,以及print()方法不修改的情况下,如何操作,才可以让类的外部通过实例化对象再去调用print()方法?

    思考过程一:使用private访问权限定义的操作只能被本类所访问,外部无法调用,那么现在既然构造方法被私有化了,就证明,这个类的构造方法只能被本类所调用,即:现在在本类之中产生本类实例化对象。

    class Singleton { // 定义一个类

             Singleton instance = new Singleton() ;

             private Singleton() {}   // 构造方法私有化

             public void print() {

                       System.out.println("Hello World .") ;

             }

    }

    思考过程二:对于一个类之中的普通属性,默认情况下一定要在本类存在了实例化对象之后才可以进行调用,可是现在在Singleton类的外部无法产生实例化对象,那么必须想一个办法,让Singleton类中的instance属性可以在没有Singleton类实例化对象的时候来进行调用,可以使用static完成,static定义的属性特点:由类名称直接调用,并且在没有实例化对象的时候也可以调用。

    class Singleton { // 定义一个类

             static Singleton instance = new Singleton() ;

             private Singleton() {}   // 构造方法私有化

             public void print() {

                       System.out.println("Hello World .") ;

             }

    }

    public class Test {

             public static void main(String args[]) {

                       Singleton inst = null ;   // 声明对象

                       inst = Singleton.instance ;   // 实例化对象

                       inst.print() ;         // 调用方法

             }

    }

    思考过程三:类之中的全部属性都应该封装,所以以上的instance属性应该进行封装,而封装之后要想取得属性要编写getter方法,只不过这个时候的getter方法应该也由类名称直接调用,定义为static型。

    class Singleton { // 定义一个类

             private static Singleton instance = new Singleton() ;

             private Singleton() {}  // 构造方法私有化

             public void print() {

                       System.out.println("Hello World .") ;

             }

             public static Singleton getInstance() {

                       return instance ;

             }

    }

    public class Test {

             public static void main(String args[]) {

                       Singleton inst = null ;   // 声明对象

                       inst = Singleton.getInstance() ;    // 实例化对象

                       inst.print() ;         // 调用方法

             }

    }

    思考过程四:这样做的目的?此时程序之中的instance属性,属于static,那么表示所有Singleton类的对象,不管有多少个都共同拥有同一个instance属性,那么既然是有同一个,那么又有什么意义呢?

             现在做一个简单的思考:如果说现在一个类只希望有唯一的一个实例化对象出现,应该控制构造方法,如果构造方法对外部不可见了,那么现在肯定无法执行对象的实例化操作,必须将构造方法隐藏,使用private隐藏。

             既然清楚了这个目的,不过本程序依然有一个问题。

             public static Singleton getInstance() {

                      instance = new Singleton() ;

                       return instance ;

             }

             本操作语法没有错误,也不需要考虑是否有意义,但是现在的代码是允许这样做的,而这样做发现之前表示唯一一个实例化对象的所有努力就白费了,那么必须想办法废除掉这种做法,可以在定义instance的时候增加一个final关键字。

    class Singleton { // 定义一个类

             private static final Singleton INSTANCE = new Singleton() ;

             private Singleton() {}   // 构造方法私有化

             public void print() {

                       System.out.println("Hello World .") ;

             }

             public static Singleton getInstance() {

                       return INSTANCE ;

             }

    }

    public class Test {

             public static void main(String args[]) {

                       Singleton inst = null ;   // 声明对象

                       inst = Singleton.getInstance() ;        // 实例化对象

                       inst.print() ;         // 调用方法

             }

    }

             这样的设计在设计模式上讲就称为单例设计模式(Singleton)。

    面试题:请编写一个Singleton程序,并说明其主要特点?

    class Singleton { // 定义一个类

             private static final Singleton INSTANCE = new Singleton() ;

             private Singleton() {}   // 构造方法私有化

             public void print() {

                       System.out.println("Hello World .") ;

             }

             public static Singleton getInstance() {

                       return INSTANCE ;

             }

    }

    public class Test {

             public static void main(String args[]) {

                       Singleton inst = null ;   // 声明对象

                       inst = Singleton.getInstance() ;        // 实例化对象

                       inst.print() ;         // 调用方法

             }

    }

             特点:构造方法被私有化,只能够通过getInstance()方法取得Singleton类的实例化对象,这样不管外部如何操作,最终也只有一个实例化对象,在单例设计模式之中,一定会存在一个static方法,用于取得本类的实例化对象。

             对于单例设计模式,在日后的开发之中,只会用到此概念,但是具体的代码很少去编写。

    扩展(可以不会):

             对于单例设计模式按照设计模式的角度而言,分为两种:

    · 饿汉式:之前写的程序就属于饿汉式,因为在类之中的INSNTACE属性是在定义属性的时候直接实例化;

    · 懒汉式:在第一次使用一个类实例化对象的时候才去实例化。

    范例:观察懒汉式

    class Singleton { // 定义一个类

             private static Singleton instance ;

             private Singleton() {}   // 构造方法私有化

             public void print() {

                       System.out.println("Hello World .") ;

             }

             public static Singleton getInstance() {

                       if (instance == null) {   // 没有实例化

                                instance = new Singleton() ;  // 实例化

                       }

                       return instance ;

             }

    }

             这些概念清楚就行了,对于单例设计再次强调:记清楚代码的结构以及操作的特点,以后这种代码虽然不会由你自己去写,但是概念一定会用到。

  • 相关阅读:
    Linux下安装mysql(yum和源码编译两种方式)
    搭建Hadoop集群(centos6.7+hadoop-2.7.3)
    xen虚拟机(Centos6.6)的创建和扩容
    Apache Ranger对HDFS的访问权限控制的原理分析(一)
    Block Token 原理分析
    Hadoop安全机制之令牌
    VS 2012 Unit Test
    java 并发
    图片相关
    cmd出现乱码
  • 原文地址:https://www.cnblogs.com/guwenren/p/3016489.html
Copyright © 2011-2022 走看看