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


------- 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值