Java单例模式和关键字

来源:互联网 发布:我国的医疗数据网站 编辑:程序博客网 时间:2024/06/06 19:56

static关键字

 

static关键字是一个标记,有static修饰的是静态成员,属于类;没有static修饰的属于实例成员,属于实例(对象)。

声明为static的变量称为静态变量或类变量。静态变量是跟类相关联的,类的所有实例共同拥有一个静态变量——最后一次赋值的值。

声明为static的方法称为静态方法或类方法。静态方法可以直接调用静态方法,访问静态变量,但是不能直接访问实例变量和实例方法(因为有static修饰的方法执行结果应该相同,如果调用实例会不相同)。静态方法中不能使用this关键字,因为静态方法不属于任何一个实例。父类中的static方法可以在子类中重写,但是不能被覆盖(所以重写也没用,还是会调用父类的方法)

publicclassStaticTest {

publicstaticvoid main(String[]args) {

A a = new B();

a.f1();//Af1

a.f2();//Bf1

}

}

//父类

class A {

publicstaticvoid f1() {

System.out.println("Af1");

}

publicvoid f2() {

System.out.println("Af2");

}

}

//子类

class Bextends A {

    //重写父类的静态方法,但不会被覆盖

publicstaticvoid f1() {

System.out.println("Bf1");

}

//重写父类的方法,会被覆盖

publicvoid f2() {

System.out.println("Bf2");

}

 

}

 

类回收

类在第一次被使用以后,就常驻内存,直到java命令结束。

类不会被java自动回收,属于类的静态成员,也不会被回收。

对象被创建出来以后,java会自动检查对象是否需要回收,如果检查到对象需要被回收,会自动把对象从内存删除。

对象里面的实例成员也会被回收、删除。

 

final关键字

是修饰符,可以修饰类、方法、变量

  • 修饰类,表示类不能被继承public final class...
  • 修饰方法,表示方法不能被子类重写(覆盖)但可以被继承public final void...
  • 修饰变量,表示只能赋值一次
    • 修饰成员(全局)变量,那么必须在合适的地方给成员变量初始化,因为final的成员变量系统不会赋予默认值。
      • 修饰实例变量(无static修饰):实例变量必须在三个地方进行初始化:

        1.直接等号赋值

        2.使用实例初始化代码块赋值

        3.使用构造器赋值

        • 修饰类变量(有static修饰):必须在两个地方进行初始化:

          1.直接等号赋值

          2.使用类初始化代码块赋值

      • 修饰局部变量,赋值没有区别,因为局部变量本身就是需要被赋值以后才能使用的。只是有final修饰的时候,意味着变量不能被再次赋值。

eg.实例变量

publicclassTestFinal

{

//直接等号赋值

finalinta = 5;

finalintb;

{

//使用实例代码块初始化final的实例变量

b = 10;

}

 

finalintc;

//在构造器里面初始化c变量

TestFinal()

{

c = 15;

}

 

}

eg.类变量

publicclassTestFinal

{

//等号直接赋值

finalstaticintd = 110;

 

//使用静态代码块赋值

finalstaticinte;

static

{

e = 120;

}

 

abstract关键字

修饰符,可以修饰类、方法

无论什么情况下,finalabstract都是对头,不能同时存在的。原因:对于类, final类不能被继承,而abstract类要通过子类实例化。对于方法, static的方法是通过类名进行方法,并且static的方法不具备多态的特性。

 

  • 修饰类,表示类不能被new,要想获得实例,只能通过new子类来实现。相当于new了一个子类的实例,赋予给父类类型的变量。抽象类里面,不一定有抽象方法。类里面如果有抽象方法,那么类必须是抽象的。
  • 修饰方法,表示方法不能有方法体,直接使用分号结束,必须由子类来重写(覆盖)

eg.抽象类

publicclassTestAbstract

{

publicstaticvoid main(String[]args)

{

//抽象类不能被new,报错

//Parent p = new Parent();

 

//非抽象类child继承抽象类parent,小类给大类,多态

Parent p = new Child();

}

}

 

//抽象父类

abstractclass Parent

{

}

 

//写一个子类,继承Parent

class Childextends Parent

{

}

 

eg.抽象方法

publicclassTestAbstract

{

publicstaticvoid main(String[]args)

{

 

//多态

AbstractMethod am = new AbstractMethodChild2();

 

//编译的时候,只检查am的类型里面是否有定义test方法,但是是否有实现,不考虑

//运行的时候,amAbstractMethodChild2类型的,实际上已经覆盖了父类的抽象方法,test被实现了!

am.test();

}

}

 

//有抽象方法的类,一定是抽象类,抽象方法一定要子类去重写(覆盖)

abstractclass AbstractMethod

{

//抽象方法没有方法体,直接使用分号结束

//方法的参数、返回值、修饰符等全部和普通的方法一样

abstractvoid test();

}

 

//继承了抽象类,要么实现所有的抽象方法,要么子类也是抽象的

abstractclass AbstractMethodChild1extends AbstractMethod

{

}

 

class AbstractMethodChild2extends AbstractMethod

{

void test()

{

System.out.println("子类的test方法实现");

}

}

 

 

模板模式

解决的问题:当一个类的大部分的操作都能够被确定下来,但是一小部分需要给子类来实现的时候。这种情况下就使用模板模式。

步骤

1.把大量的、已经确定的工作写到一个final的方法里面

2.不确定的事情,交给一些抽象的方法去执行

3.因为类里面有了抽象方法,所以类必须是抽象的,这个时候要实例就只能从子类创建

4.执行业务代码的时候,抽象方法因为被子类实现了,所以行为就有子类来决定

 

单例模式——避免重复创建实例

单例模式,是一种设计模式。利用静态成员的特性来实现。

目的:避免在内存里面出现一个类的多个实例。每当new一次类,就一定产生一个新的实例,现在需要避免这种实例的产生。

如果一个类里面,没有记录任何的用户相关的数据,那么就可以使用单例模式,降低不必要的new,提高程序的性能。

 

实现步骤

1.私有构造器,避免类外面使用new去调用构造器。

2.在类里面提供一个类型为当前类的静态变量(唯一的),并且调用构造器进行初始化

3.提供一个公共的、静态的方法,用于获取静态变量。

//这个是支付服务

//单例模式避免重复创建实例

class PaymentService

{

//1.私有构造器

private PaymentService()

{

System.out.println("创建了支付服务 " + this);

}

 

//2.在类里面提供一个类型为当前类的静态变量,并且调用构造器进行初始化

privatefinalstatic PaymentServiceinstance = new PaymentService();

 

//3.提供一个静态的、公共的方法,获得实例

publicstatic PaymentService getPaymentService()

{

returninstance;

}

}

 

publicclassTestPaymanetService

{

publicstaticvoid main(String[]args)

{

//不能再new,因为构造器私有,下式报错

//PaymentServiceps = new PaymentService();

 

//调用静态方法获得唯一的实例

PaymentServiceps1 = PaymentService.getPaymentService();

PaymentServiceps2 = PaymentService.getPaymentService();

 

//每次获得的都是相同的实例

System.out.println(ps1);

System.out.println(ps2);

}

}

 

原创粉丝点击