黑马程序员——Java基础_单例设计模式、内部类

时间:2021-06-25 00:45:54

 ----------------------Android培训Java培训、期待与您交流! ----------------------

1 设计模式:解决某一类问题最行之有效的方法。

     java中有23种设计模式。

-----------------------------分割线-----------------------------

2 单例设计模式

     目的:解决一个类在内存只存在一个对象,想要保证对象唯一。

     首先为了避免其他程序过多建立该类对象。先禁止其他程序建立该类对象;然后,还为了让其他程序可以访问到该类对象,只好在本类中,自定义一个对象。最后,为了方便其他程序对自定义对象的访问,可以对外提供一些访问方式。

这三部怎么用代码体现呢?

     ① 将构造函数私有化;

     ② 在类中创建一个本类对象;

     ③ 提供一个方法可以获取到该对象。

代码示例:

class Student
{
private int age;


private static Student s = new Student();
private Student(){}
public static Student getStudent()
{
return s;
}



public void setAge(int age)
{
this.age = age;
}
public int getAge()
{
return age;
}
}

对于事物该怎么描述,还怎么描述。当需要将该事物的对象保证在内存中唯一时,就将以上的三步加上即可。

-----------------------------分割线-----------------------------

3 单例设计模式之饿汉式

     先初始化对象称为:饿汉式。Single类一进内存,就已经创建好了对象。

代码示例:

class Single
{
private static Single s = new Single();
private Single(){}
public static Single getInstance()
{
return s;
}
}

-----------------------------分割线-----------------------------

4 单例设计模式之懒汉式

     对象是方法被调用时,才初始化,也叫做对象的延时加载。称为:懒汉式。
     Single类进内存,对象还没有存在,只有调用了getInstance方法时,才建立对象。

示例代码:

class Single//懒汉式  方法被调用时才初始化,也叫做对象的延时加载
{
private Single(){}
private static Single s=null;
public static Single getInstance()
{
if(s==null)
{
s=new Single();
}
return s;
}
}

 懒汉式的线程优化版(多线程访问时保证安全)

class Student
{
private Student(){}
private static Student s=null;
public static Student getStudent()
{
if(s==null)
{
synchronized(Student.class)
{
if(s==null)
{
s=new Student();
}
}
}
return s;
}
}

网上流传的优化版懒汉式

public class Singleton {  
/**
* 类级的内部类,也就是静态的成员式内部类,该内部类的实例与外部类的实例
* 没有绑定关系,而且只有被调用到才会装载,从而实现了延迟加载
*/
private static class SingletonHolder{
/**
* 静态初始化器,由JVM来保证线程安全
*/
private static Singleton instance = new Singleton();
}
/**
* 私有化构造方法
*/
private Singleton(){
}
public static Singleton getInstance(){
return SingletonHolder.instance;
}
}

-----------------------------分割线-----------------------------

5 模板方法模式

什么是模版方法?

     在定义功能时,功能的一部分是确定的,但是有一部分是不确定的,而确定的部分若需要使用不确定的部分的话,那么这时就将不确定的部分暴露出去,由该类的子类去完成。

如:

需求:获取程序运行花掉的时间

     运行的程序代码块是不确定的,但是计算运算时间的代码已经确定,但是它需要用到那个不确定的程序代码块,这个时候就将其暴露出去,定义成抽象方法交由子类区完成。

-----------------------------分割线-----------------------------

6  部类

     顾名思义,内部类即定义在类的内部的类。

内部类的访问规则:

     ① 内部类可以直接访问外部类中的成员,包括私有。为什么能直接访问外部类中的成员?因为内部类中持有了一个外部类的引用,格式:外部类名.this

     ② 外部类要访问内部类,必须建立内部类对象。

当描述事物时,事物的内部还有事物,该事物用内部类来描述。因为内部事务在使用外部事物的内容。

     内部类的意义:

     当描述事物时,事物的内部还有事物,该事物用内部类来描述。因为内部事物在使用外部事物的内容。如身体,身体还包含心脏等器官。

-----------------------------分割线-----------------------------

7 内部类之成员内部类

     当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中直接建立内部类对象。

     当内部类在成员位置上,就可以被成员修饰符所修饰。

比如,private:将内部类在外部类中进行封装。

     格式:外部类名.内部类名  变量名 外部类对象.内部类对象;

     示例:Outer.Inner in = new Outer().new Inner();

代码示例:

class Outer
{
private int x = 3;
class Inner//内部类
{
//int x = 4;
void function()
{
//int x = 6;
System.out.println("innner :"+Outer.this.x);
}
}
void method()
{
Inner in = new Inner();
in.function();
}
}

-----------------------------分割线-----------------------------

8 内部类之静态内部类

     static:内部类就具备static的特性。

     当内部类被static修饰后,只能直接访问外部类中的static成员。出现了访问局限。

     在外部其他类中,如何直接访问static内部类的非静态成员呢?

          new Outer.Inner().function();

     在外部其他类中,如何直接访问static内部类的静态成员呢?

          uter.Inner.function();

注意:当内部类中定义了静态成员,该内部类必须是static的。

     当外部类中的静态方法访问内部类时,内部类也必须是static的。

代码示例:

class Outer
{
private static int x = 3;
static class Inner//静态内部类
{
static void function()
{
System.out.println("innner :"+x);
}
}

static class Inner2
{
void show()
{
System.out.println("inner2 show");
}
}

public static void method()
{
//Inner.function();
new Inner2().show();
}

}


class InnerClassDemo2
{
public static void main(String[] args)
{
Outer.method();
}
}

-----------------------------分割线-----------------------------

9 内部类之局部内部类

     内部类定义在局部时,

         ① 不可以被成员修饰符修饰

          ② 可以直接访问外部类中的成员,因为还持有外部类中的引用;但是不能访问它所在的局部中的变量,只能访问被final修饰的局部变量 原因:

     局部内部类不能定义静态成员;非静态时,没对象的话类不会运行

代码示例:

class Outer
{
int x = 3;
void mathod()
{
final int y = 4;
class Inner
{
void function()
{
System.out.println(y);
}
}
new Inner().function();
}
}

-----------------------------分割线-----------------------------

10 内部类之匿名内部类

     匿名内部类其实就是内部类的简写格式

     定义匿名内部类的前提:

          内部类必须是继承一个类或者实现接口

     匿名内部类的格式:

          new 父类或接口(){定义子类的内容};

     其实匿名内部类就是一个匿名子类对象,而且这个对象有点胖。可理解为带内容的对象

     PS:匿名内部类中定义的方法最好不要超过3个;因为它的意义是为了简化书写

代码示例:

abstract class AbsDemo
{
abstract void show();
}
class Outer
{
int x=3;
public void function()
{
new AbsDemo()//new了一个父类AbsDemo
{
void show()
{
System.out.println("x=="+x); //实现父类的show方法
}
}.show();
}
}

PS

一道面试题:没有继承父类、接口,可以实现匿名内部类吗?  

      答:可以,因为所有类都继承自object

class Outer
{
public static void Main(string[] args)
{
new Object()
{
public void function()
{
System.out.println("test");
}
}.function();
}
}

PS:

与匿名内部类所不同的匿名对象有两种用法:

     ① 当你只需要调用一次该对象的方法时,比如new Person().speak 

     ② 作为参数传递,比如new Threadnew Service())。



 ----------------------Android培训Java培训、期待与您交流! ----------------------