java基础-2-面向对象(2)-封装与单例程序设计思想

来源:互联网 发布:淘宝孤品衣服能买么 编辑:程序博客网 时间:2024/05/17 03:36


------- android培训java培训、期待与您交流! ----------



封装

        封装是指隐藏对象的属性及实现细节,仅对外提供公共访问方式。即程序透明。

        封装的原则:     将不需要对外提供的内容隐藏起来。

                                     把属性隐藏起来,提供公共方法对其访问。

        封装思想,不仅仅是局限于类的定义,而是贯穿于整个程序编程的重要思想之一。封装操作能够提高程序的安全性,避免将一些不用对用户开放的程序接口暴露在用户可以触及的地方。同时,封装操作可以提高程序的重用性,提高代码效率。封装是我们编程过程中,必不可少的操作。我们一般使用关键字private来实现对成员变量、方法的封装。如果有一些需要提供接口来改变的成员变量,我们通常将成员变量设为private,而再定义方法用于获取和改变该成员变量值。例如:

classEncapsulationDemo{       public static void main(String[] args)       {              //建立K类对象k,并为成员变量name其赋初值"w"              K k = new K("w");              //显示对象k中的name值              System.out.println(k.get());               //使用K类的接口set,修改k对象的name值              k.set("ppp");              //显示对象k,在重新设定后的name值              System.out.println(k.get());       }} //测试类K:public class K{       //封装的成员变量       private String name;        //K类构造函数       void K(String name)       {              this.name = name;       }       void K(){}        //定义成员变量的获取接口       public String get()       {              return name;       }        //提供修改成员变量的方法       public void set(String name)       {              this.name = name;       }}

        上面这个例子中,我们就使用了封装的思想,将K类的成员变量name做了封装,只提供了get用于获取,和set用于修改。从结果不难看出,原来的name值"w",经过调用set方法修改后,变成了"ppp"。实现了间接的成员变量访问与修改。

 

单例程序设计

        设计模式起源于早起建筑概念,并衍生到程序编程之中。设计模式,是通过对过往经验的总结,将过去具有一定相同点的经典案例总结起来,并简化出一套可以解决同类问题的一系列设计理念的整合。这样的解决方案、经验总结,称之为设计模式。Java中,总共有23种经典设计模式,详见《设计模式》一书。设计模式偏重于思想,多个简单模式的复杂集合,就可以成为框架。

        什么叫单例设计模式?单例设计模式就是指,一个类只在内存当中存在一个对象。即该类只能被持有一个对象。想要实现这种思想,我们就必须保证该类无法外部调用构造函数,来创建对象。我们想到,想要如此,最简单的方式就是将该类的对象封装到类中,并且将对象和构造方法设为private,对象设为privatestatic。这样,为了访问该对象,我们就必须得通过该类,来提供一个获取对象的方法。

        单例程序设计分为两种方式:饿汉式和懒汉式。饿汉式,顾名思义,就是在类中率先进行了该类对象的实例化操作,保持它不用保持“饥饿”的状态。懒汉式,就是在未调用前不给对应类建立对象,因为“懒”。

        饿汉式:

classSingletonDesignHungry{       public static void main(String[] args)       {              //建立Lazy类的类型变量,并通过getInstance方法获取对象              Hungry  ins = Hungry. getInstance();              //输出检测参数i的值              System.out.println("ins_1:"+ins.i);               //建立Lazy类的另一个类型变量,获取对象,用于检测              Hungry  ins2 = Hungry .getInstance();              //通过第二个类型变量来改变检测参数              ins2.i = 5;              //分别通过第一个和第二个类型变量来输出检测参数              System.out.println("ins_1:"+ins.i);              System.out.println("ins_2:"+ins2.i);       }} //饿汉式单例程序设计:class Hungry{       //定义一个类参数,此处为了简略就不设它为私有了       int i;             //封装单例类对象到类中,并以私有静态形式在声明处定义赋值       private static Hungry  la = new Hungry (2);       //将本类的构造函数设置为私有,防止外部调用创造对象       private void Hungry (int i)          {              this.i = i       }       //定义本类对象的获取方式,以提供接口给人员使用       public Hungry  getInstance()       {              //返回封装的类对象              return la;       }}

        上面的例子,有结果:          ins_1:2

                                                          ins_1:5

                                                          ins_2:5

        从结果上不难看出,不论是通过ins2还是ins1访问Lazy类的内部封装对象,结果都是相同的。ins1、ins2俩,本质上都是指向了同一个Lazy类的对象,那就是Lazy类内部封装的静态对象la。

        虽然定义简单,但是饿汉式有饿汉式的缺点,那就是对内存资源的浪费。当我们不需要该对象的时候,这个方法定义的饿汉式单例类就已经将它的对象存储到了内存中,占据了内存空间。这样的用法如果在一个程序中出现次数太多,而且未有合理的处理手段的话,就会导致程序的运行效率较低。

        于是,我们有了另一种设计方式,懒汉式:

classSingletonDesignLazy{       public static void main(String[] args)       {              //建立Lazy类的类型变量,并通过getInstance方法获取对象              Lazy ins = Lazy.getInstance();              //输出检测参数i的值              System.out.println("ins_1:"+ins.i);               //建立Lazy类的另一个类型变量,获取对象,用于检测              Lazy ins2 = Lazy.getInstance();              //通过第二个类型变量来改变检测参数              ins2.i = 5;              //分别通过第一个和第二个类型变量来输出检测参数              System.out.println("ins_1:"+ins.i);              System.out.println("ins_2:"+ins2.i);       }} //懒汉式单例程序设计:class Lazy{       //定义一个类参数,此处为了简略就不设它为私有了       int i;             //将对应的对象封装到类中,并设置为私有静态防止直接调用       private static Lazy la;       //将类的构造函数设置为私有,防止直接调用创造对象       private void Lazy(int i)       {              this.i = i;       }       //设置本类的获取方法,为人员提供访问接口       public Lazy getInstance()       {              //在对类内部对象进行初始化前,我们先判断对象是否已存在              if(la == null)              {                     //加类锁,以防止在方法被调用创建对象时,又有其他的调用,造成冲突                     synchronized(Lazy.class)                     {                            //二次判断,防止错误发生                            if(la == null)                            {                                   //调用私有构造函数,初始化对象                                   Lazy(2);                            }                     }              }       }    }

        上面的例子,有结果:          ins_1:2

                                                          ins_1:5

                                                          ins_2:5

        懒汉式的单例程序设计,避免了对内存的占用问题,提高了内存的利用率,但是算法本省却需要加锁来降低发生冲突概率。这正是所谓的有得必有失。具体的使用过程中,应根据具体的情况使用。因此虽然懒汉式节约内存,但是我们定义单例的时候一般常用饿汉式。

 

 

 ------- android培训java培训、期待与您交流! ----------

 


0 0
原创粉丝点击