单例模式
1.设计模式的说明
1.1 理解
设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格、
以及解决问题的思考方式。
1.2 常用设计模式 --- 23种经典的设计模式
创建型模式,共5种:工厂模式、抽象工厂模式、单例模式、建造者模式、原型模式
结构型模式,共7种:适配器模式、过滤器模式、装饰模式、享元模式、代理模式、外观模式、组合模式、桥接模式
行为型模式,共11种:责任链模式、命令模式、中介者模式、观察者模式、状态模式、策略模式、模板模式、空对象模式、备忘录模式、迭代器模式、解释器模式、访问者模式
2.单例模式
2.1 要解决的问题:
所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例2.2 具体代码的实现:
饿汉式1:
//饿汉式1
class Bank{
//1.私有化类的构造器
private Bank(){
}
//2.内部创建类的对象
//4.要求此对象也必须声明为静态的
private static Bank instance = new Bank();
//3.提供公共的静态方法,返回类的对象
public static Bank getInstance() {
return instance;
}
}
class Order{
//1.私有化类的构造器
private Order(){
}
//2.声明当前类对象,没有初始化
//4.此对象也必须声明为static的
private static Order instance = null;
static{
instance = new Order();
}
//3.声明public、static的返回当前类对象的方法
public static Order getInstance() {
return instance;
}
}
懒汉式:
class Order{
//1.私有化类的构造器
private Order(){
}
//2.声明当前类对象,没有初始化
//4.此对象也必须声明为static的
private static Order instance = null;
//3.声明public、static的返回当前类对象的方法
public static Order getInstance() {
if (instance == null){
instance = new Order();
}
return instance;
}
}
2.3 两种方式的对比:
饿汉式:
坏处:对象加载时间过长。
好处:饿汉式是线程安全的。
懒汉式:
好处:延迟对象的创建。
目前的写法坏处:线程不安全。--->到多线程内容时,再修改
main()的使用说明
* 1. main()方法作为程序的入口
* 2. main()方法也是一个普通的静态方法
* 3. main()方法可以作为我们与控制台交互的方式。(之前:使用Scanner)
如何将控制台获取的数据传给形参:String[] args?
运行时:java 类名 "Tom" "Jerry" "123" "true"
sysout(args[0]);//"Tom"
sysout(args[3])//"true" --> Boolean.parseBoolean(args[3]);
sysout(args[4]);//报异常
小结:一叶知秋
public static void main(String[] args){//方法体}
权限修饰符:private 缺省 protected public ---->封装性
修饰符:stati\final\abstract\native 可以用来方法
返回值类型:无返回值 / 有返回值 --> return
方法名:需要满足标识符命名的规则、规范:“见名知意”
形参列表:重载 vs 重写:参数值传递机制;体现对象的多态性
方法体:来体现方法的功能
类的结构之四:代码块
类的成员之四:代码块(初始化块)(重要性较属性、方法、构造器差一些)
1.代码块的作用:用来初始化类、对象的信息
2.分类:代码块要是使用修饰符,只能使用static
分类:静态代码块 vs 非静态代码块
3.
静态代码块:
>内部可以有输出语句
>随着类的加载而执行,而且只执行一次
>作用:初始化类的信息
>如果一个类中定义了多个静态代码块,则按照声明的先后顺序执行
>静态代码块的执行要优先于非静态代码块的执行。
>静态代码块内只能调用静态的属性、静态的方法,不能调用非静态的结构
非静态代码块:
>内部可以有输出语句
>随着对象的创建而执行
>每创建一个对象,就执行一次非静态代码块
>作用:可以在创建对象时,对对现象的属性等进行初始化
>如果一个类中定义了多个静态代码块,则按照声明的先后顺序执行
>非静态代码块内可以调用静态的属性、静态的方法,或非静态的属性、非静态的方法
4. 实例化子类对象时,涉及到父类、子类中静态代码块、非静态代码块、构造器的加载顺序:
对应的练习:LeafTest.java / Son.java
由父及子,静态先行。
* 对属性可以赋值的位置:
* ① 默认初始化
* ② 显式初始化 ⑤ 在代码块中赋值 (看谁先写,谁后写)
* ③ 构造器中初始化
* ④ 有了对现象以后,可以通过"对象.属性"或"对象.方法"的方式,进行赋值
* 执行的先后顺序:① - ② / ⑤ - ③ - ④
类的结构之五:内部类
内部类:类的第五个成员
1.定义:Java中允许将一个类A声明在另一个类B中,则类A就是内部类,类B称为外部类
2.内部类的分类:
成员内部类(静态、非静态 ) vs 局部内部类(方法内、代码块内、构造器内)
3.成员内部类的理解:
一方面,作为外部类的成员:
* >调用外部类的结构
* >可以被static修饰
* >可以被4种不同的权限修饰
*
另一方面,作为一个类:
* > 类内可以定义属性、方法、构造器等
* > 可以被final修饰,表示此类不能被继承。言外之意,不使用final,就可以被继承
* > 可以被abstract修饰
4.成员内部类:
4.1如何创建成员内部类的对象?(静态的,非静态的)
4.1如何创建成员内部类的对象?(静态的,非静态的)
//创建静态的Dog内部类的实例(静态的成员内部类):
Person.Dog dog = new Person.Dog();
//创建非静态的Bird内部类的实例(非静态的成员内部类):
//Person.Bird bird = new Person.Bird();//错误的
Person p = new Person();
Person.Bird bird = p.new Bird();
4.2如何在成员内部类中调用外部类的结构?
class Person{//外部类
String name = "小明";
public void eat(){
}
//非静态成员内部类
class Bird{//内部类
String name = "杜鹃";
public void display(String name){
System.out.println(name);//方法的形参
System.out.println(this.name);//内部类的属性
System.out.println(Person.this.name);//外部类的属性
//Person.this.eat();
}
}
}
5.局部内部类的使用:
//返回一个实现了Comparable接口的类的对象
public Comparable getComparable(){
//创建一个实现了Comparable接口的类:局部内部类
//方式一:
// class MyComparable implements Comparable{
//
// @Override
// public int compareTo(Object o) {
// return 0;
// }
//
// }
//
// return new MyComparable();
//方式二:
return new Comparable(){
@Override
public int compareTo(Object o) {
return 0;
}
};
}
注意点:
在局部内部类的方法中(比如:show如果调用局部内部类所声明的方法(比如:method)中的局部变量(比如:num)的话,要求此局部变量声明为final的。
*
jdk 7及之前版本:要求此局部变量显式的声明为final的
jdk 8及之后的版本:可以省略final的声明
总结:
成员内部类和局部内部类,在编译以后,都会生成字节码文件。
格式:成员内部类:外部类$内部类名.class
局部内部类:外部类$数字 内部类名.class