单例设计模式
概述:
设计模式:前人根据自己的经验总结的一种设计的规范。其实也不仅仅是一种设计规范,更多的是一种设计经验或者设计套路。
单例设计模式:在定义类型时,如果该类的对象,在整个系统中只能提供一个,可以使用该模式定义类 型
单例模式的设计原则:
(1)构造方法私有化:防止在其他类中随意创建
(2)在类中创建好该类对象:因为构造私有化,其他类无法创建,只能提供一个公用
(3)在类中,给外界提供获取该对象的方式
单例设计模式一:饿汉式
概述:因为该对象是静态修饰的,类型加载之后,就已经存在该对象。
public class Danli {
public static void main(String[] args) {
Sun sun = Sun.getSun();
sun.print();
Sun sun2 = Sun.getSun();
sun2.print();
}
}
class Sun{
//防止在其他的类中随意创造对象,所以无参构造 私有化
private Sun() {
}
//将构造方法私有化之后,外界无法创建,所以需要内部创建一个对象以供使用
private static Sun s =new Sun();
//因为对象是私有的,所以需要提供一个公共的访问方式
public static Sun getSun() {
return s;
}
public void print(){
System.out.println(s+"是这个对象的地址。");
}
}
单例设计模式二:饿汉式的优化版
public class Danli02 {
public static void main(String[] args) {
Sun1 s = Sun1.s;
Sun1 s1 = Sun1.s;
s.print();
s1.print();
}
}
class Sun1{
//防止在其他的类中随意创造对象,所以无参构造 私有化
private Sun1() {
}
//将构造方法私有化之后,外界无法创建,所以需要内部创建一个对象以供使用
//public 共有访问可以,加上 final 之后表示 s 地址不可修改
public final static Sun1 s =new Sun1();
public void print(){
System.out.println(s+"是这个对象的地址。");
}
}
单例设计模式三:懒汉式
public class Danli03 {
public static void main(String[] args) {
}
}
class Sun3{
private Sun3(){
}
//为了节约内存,什么时候用什么时候创建对象
private static Sun3 s;
//提供公共获取的方法
public static Sun3 getSun(){
//为了防止每次都获取锁对象,占用资源所以提前判断是否需要创建对象
if (s == null){
//需要创建的时候获取锁对象
synchronized (Sun3.class){
//内层也需要判断,如果不判断的话,线程进入外层判断等待锁对象释放,外层判断失去意义
if (s==null){
s= new Sun3();
}
return s;
}
}
return s;
}
}
枚举类型
概述:如果某个类型的对象是有限个,可以使用枚举来定义该类型。
枚举类型的第一种方式
特点:
- 定义枚举类,使用关键字:enum
- 枚举类中需要几个对象,就写几个对象名即可
- 定义的枚举的对象,有一个别名(枚举项)
- 多个枚举项之间,使用逗号分隔,必须都在第一行定义
- 定义一个枚举类之后,么有提供构造方法,类型默认提供一个空参构造,将空参 构造私有化
public class Demo01 {
week w = week.w1;
week w1 = week.w2;
week w2 = week.w3;
week1 ww = week1.w1;
week1 ww2 = week1.w2;
week1 ww3 = week1.w3;
}
//借鉴了单例模式来定义该类型
//定义了一个类型,给类型中对象只有三个
class week{
private week(){}
public static final week w1 = new week();
public static final week w2 = new week();
public static final week w3 = new week();
public void printf(){
System.out.println("这是一个普通类型");
}
}
//使用枚举类型来定义
enum week1{
w1,w2,w3;
public void printf(){
System.out.println("这是一个美剧类型");
}
}
枚举类型的第二种方式
特点:
- 在枚举类中也可以正常定义属性,属性可以私有化,也可以正常提供公共的访问方式。
- 如果需要当对象中的属性有值的,就需要提供有参构造,有参构造私有修饰
- 在枚举项定义的时候,如果该对象需要属性值,就直接在对象名后面写一个小括号,小括号中给定要赋的值即可。
public class Demo02 {
public static void main(String[] args) {
Week2.w.print();
Week3.w1.print();
}
}
class Week2{
private String name;
private Week2(){}
private Week2(String name){
this.name = name;
}
public static final Week2 w= new Week2("aaa");
public static final Week2 w1= new Week2("bbb");
public static final Week2 w2= new Week2("ccc");
public void print(){
System.out.println(name);
}
}
//使用枚举类型定义
enum Week3{
w1("aaa"),w2("bbb"),w3("ccc");
private String name;
private Week3(){}
private Week3(String name){
this.name = name;
}
public void print(){
System.out.println(name);
}
}
枚举类型的第三种方式
特点:
- 在枚举类中可以正常定义抽象方法,而且类型不需要通过abstract来修饰
- 在定义枚举项时,使用匿名内部类的方式来定义该类的子类对象
- 之间使用逗号分隔
public class Demo03 {
public static void main(String[] args) {
//调用普通类
Week4.w.show();
Week4.print();
//调用枚举类
Week5.w1.show();
Week5.print();
}
}
abstract class Week4{
private String name;
private Week4(){}
private Week4(String name){
this.name = name;
}
public static final Week4 w =new Week4("aaa"){
@Override
public void show(){
System.out.println("第一个子类对象");
}
};
public static final Week4 w1 =new Week4("bbb"){
@Override
public void show(){
System.out.println("第二个子类对象");
}
};
public static final Week4 w2 =new Week4("ccc"){
@Override
public void show(){
System.out.println("第三个子类对象");
}
};
public abstract void show();
public static void print(){
System.out.println("方法");
}
}
//定义枚举类型
enum Week5{
w1("aaa"){
@Override
public void show() {
System.out.println("第一个子类对象");
}
},
w2("bbb"){
@Override
public void show() {
System.out.println("第二个子类对象");
}
},
w3("ccc"){
@Override
public void show() {
System.out.println("第三个子类对象");
}
};
private String name;
private Week5(){}
private Week5(String name){
this.name = name;
}
public abstract void show();
public static void print(){
System.out.println("方法");
}
}