Day22-2.单例设计模式 、枚举类型

1 单例设计模式

1.1概述

  1. 设计模式:在设计类型、设计接口、设计方法、设计框架的时候使用的一种方式(套路),就是设计模式。
  2. 单例设计模式:
    在定义类型时,如果该类的对象,最多只能有一个,就可以使用单例设计模式
  3. 单例模式的设计原则:
    (1)构造方法私有化
    (2)在类中创建好该类对象
    (3)在类中,给外界提供获取该对象的方式

1.2 饿汉式设计单例类型

package demos3;

public class Demo01 {
    public static void main(String[] args) {

        //使用类型调用静态方法,获取类中提供好的对象
        //不管调用多少次,返回的都是同一个对象
        Sun s1 = Sun.getSun();
        Sun s2 = Sun.getSun();
        System.out.println(s1 == s2);
    }
}
//太阳类型的对象,只能创建一个(提供一个)
class Sun{
    //1、为了防止在其他类中随意创建对象
    //   将类中的构造方法私有化
    private Sun(){}
    //2、要在类中提供一个共有的对象
    private static Sun s = new Sun();
    //3、提供一个获取该对象的方式
    public static Sun getSun(){
        return s;
    }
}

1.3 单例设计模式之:老汉式设计(饿汉式的一种)

package demos3;

public class Demo02 {
    public static void main(String[] args) {

       Sun2 s1 =  Sun2.s;
       Sun2 s2 = Sun2.s;
       System.out.println(s1 == s2);

    }
}
//保证该类对象只有一个
class Sun2{
    //将构造方法私有化
    private Sun2(){}
    //提供一个共用的对象
    //将该对象定义为公共的,静态的,最终修饰的
    //可以多次使用这一个对象,通过类名调用即可,但是不能更改
    public static final Sun2 s = new Sun2();

    public void show(){
        System.out.println("太阳发光发热");
    }
}

1.4 单例设计模式之懒汉式

package demos3;

public class Demo03 {
    public static void main(String[] args) {

        Thread t1 = new Thread(){
            public void run(){
                Sun3 s1 = Sun3.getSun();
            }
        };

        Thread t2 = new Thread(){
            public void run(){
                Sun3 s2 = Sun3.getSun();
            }
        };

    }
}
//问题:第一种和第二种,都是静态定义该对象,都是在类型加载之后就已经创建成功(浪费空间)
//     提供的对象,什么时候需要使用,什么时候再提供
class Sun3{
    //构造私有化
    private Sun3(){}
    //提供一个共有的对象使用
    private static Sun3 s;
    //一旦给该方法加上同步代码块之后,每次执行该方法,都需要先获取锁对象,降低了程序的运行效率
    public static Sun3 getSun(){
        //同步代码块之前加上一个判断:为了防止每次执行该方法都获取锁对象
        if(s == null){
            //为了保证多线程情况下,只创建一个对象,需要将判断语句同步
            synchronized (Sun3.class){
                //为了防止创建多次对象,如果s没有创建过,就创建
                //如果有创建过,就不需要再次创建
                if (s == null){
                    s = new Sun3();
                }
            }
        }
        return s;
    }
}

2 枚举类型

2.1 概述

  1. 概述:如果某个类型的对象是有限个,可以使用枚举来定义该类型。

2.2 定义枚举类型的第一种形式

  1. 定义枚举使用enum关键字来定义,定义的也是一个类型(和class同一个级别)
  2. 该类需要几个对象,就定义几个对象名(正常给对象起名即可)
  3. 每个对象使用逗号分隔,最后一个分号结束
  4. 枚举类型中的对象都必须在第一行定义
  5. 枚举类型中定义的对象一般称为:枚举项
  6. 如果使用枚举定义一个类型,前提是:该类的对象是有限个
  7. 如果在类中没有定义任何构造方法,默认提供一个私有的空参构造

代码

package demos4;

public class Demo01 {
    public static void main(String[] args) {

        WeekDay111 w1 = WeekDay111.w1;
        WeekDay111 w2 = WeekDay111.w2;
        WeekDay111 w3 = WeekDay111.w3;
        System.out.println(w1==w2);
        System.out.println(w1==w3);
        System.out.println(w3==w2);
        w1.show();
        w2.show();
        w3.show();
    }
}
//定义一个类型,要求该类型的对象只有三个
//使用单例设计模式的思想来定义该类型
class WeekDay{
    //构造方法私有化
    private WeekDay(){}
    //提供共有的对象
    public static final WeekDay w1 = new WeekDay();
    public static final WeekDay w2 = new WeekDay();
    public static final WeekDay w3 = new WeekDay();
    public void show(){
        System.out.println("该类是一个星期类型");
    }
}
//使用枚举的方式定义该类型
enum WeekDay111{
    //定义的名字,其实就是一个个对象
    w1,w2,w3;
    public void show(){
        System.out.println("这是一个枚举类型");
    }
}

2.3 定义枚举类型的第二种形式

  1. 如果类中需要定义属性,直接定义即可,和之前定义方式相同
  2. 为枚举类型提供有参和空参构造
  3. 枚举项可以使用有参创建,也可以使用空参创建
    如果使用有参,就需要在对象名后面跟上实际参数;如果是空参不需要跟参数

代码

package demos4;

public class Demo02 {
    public static void main(String[] args) {

//        Week w1 = Week.w1;
//        w1.show();
//        Week.w2.show();
//        Week.w3.show();

        Week111.w1.show();
        Week111.w2.show();
        Week111.w3.show();
    }
}
//定义一个类型,对象是三个
//使用单例设计模式定义类型
class Week{
    private String name;
    //构造私有华
    private Week (){}
    private Week (String name){
        this.name = name;
    }
    //提供对象
    public static final Week w1 = new Week("星期一");
    public static final Week w2 = new Week("星期二");
    public static final Week w3 = new Week();
    //用来打印对象属性的方法
    public void show(){
        System.out.println(this.name);
    }
}
//使用枚举定义一个带着属性的类型
enum Week111{
    //在提供枚举项的时候,如果需要给参数赋值,就只需要在名字后面加一个小括号,传入参数即可(默认调用了有参构造)
    //如果在提供枚举项的时候,不需要给属性赋值,就不需要传递参数,默认调用了空参构造
    //如果需要使用有参和空参,前提在类中要定义有参构造和空参构造(私有修饰)
    w1("星期一"),w2("星期二"),w3;
    private Week111(String name){
        this.name = name;
    }
    private Week111(){
    }
    private String name;
    public void show(){
        System.out.println(name);
    }
}

2.4 定义枚举类型的第三种形式

  1. 在类型枚举类型中如果需要定义抽象方法,正常定义即可
  2. 再定义枚举项的时候,需要使用匿名内部类创建实现类的对象
    不能直接创建该类对象

代码

package demos4;

public class Demo03 {
    public static void main(String[] args) {

        Mon.m1.print();
        Mon.m2.print();
        Mon.m3.print();

        Mon.m1.show();
        Mon.m2.show();
        Mon.m3.show();

        Mon111.m1.print();
        Mon111.m2.print();
        Mon111.m3.print();
        Mon111.m1.show();
        Mon111.m2.show();
        Mon111.m3.show();
    }
}
//定义个类型,对象3个,而且类中有一个抽象方法
//单例模式实现
abstract class Mon{
    private String name;
    private Mon(){}
    private Mon(String name){
        this.name = name;
    }
    //因为类型是抽象类,所以不能直接创建对象,但是需要提供对象使用
    //只能提供子类的对象
    public static final Mon m1 = new Mon("星期一") {
        @Override
        public void print() {
            System.out.println("第一个子类的对象");
        }
    };
    public static final Mon m2 = new Mon("星期二") {
        @Override
        public void print() {
            System.out.println("第二个子类的对象");
        }
    };
    public static final Mon m3 = new Mon() {
        @Override
        public void print() {
            System.out.println("第三个子类的对象");
        }
    };
    public void show(){
        System.out.println(name);
    }

    public abstract void print();
}

enum Mon111{
    m1("星期一"){
        public void print(){
            System.out.println("一");
        }
    },
    m2("星期二"){
        public void print(){
            System.out.println("二");
        }
    },
    m3(){
        public void print(){
            System.out.println("三");
        }
    };
    private String name;
    private Mon111(){}
    private Mon111(String name){
        this.name = name;
    }
    public void show(){
        System.out.println(name);
    }
    public abstract void print();
}        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值