Java心得---单例类、final修饰符、抽象类

1.  设计模式:是一种问题解决思想。解决某一类问题最行之有效的方法。Java有23中设计模式(前人总结出来的)。

单例设计模式:解决一个类在内存中只存在一个对象。

如果一个类始终只能创建一个实例,则这个类称为单例(Singleton)类。

2. 想要保证对象的唯一(创建单例类的三个步骤):

1).禁止其他程序自由创建对象:将构造方法私有化,使用private修饰。

2).为了让其他程序可以访问到该类对象,只能在本类定义一个对象:在类中创建一个本类对象。

3).为了方便其他程序对该对象的访问,可以对外提供访问方法:提供一个public方法可以获取该对象。

3.   一般情况下,把类的构造方法定义成public访问权限,即允许任何类自由创建该对象,但在某些时候允许其他类自由创建该类的对象没有任何意义,反而可能造成系统性能下降(因为每创建一个对象都要占用一定的系统资源)。

提供的public方法必须使用static修饰(因为调用该方法之前不存在对象而且是实例对象,只能有一个对象,不能在new了,因此调用该方法的不可能是对象,只能是类);该类必须缓存已经创建的对象,否则随后它无法知道是否曾经创建过对象,也就无法保证只创建一个对象,为此该类需要使用一个属性来保存曾经创建的对象,且因为属性需要被上面的静态方法访问,故必须使用static修饰。

4 两种写法:

1).饿汉式:不管你用不用,一开始就建立单例对象,即先初始化对象。

    开发一般使用此写法,安全性高

         private static Single s=newSingle();

private Single(){}

         public static SinglegetInstance(){

return s;

}

        2).懒汉式:使用时才建立对象,是延迟加载。

            private static Single1s=null;

            private Single1(){}

public static Single1 getInstance(){

                if(s==null){

 s=new Single1();}

return s;

}

5.     final关键字可用于修饰类、变量和方法,用于表示它修饰的类、变量和方法不可改变。

     final修饰变量时,表示该变量一旦获得了初始值之后就不可被改变,final既可修饰成员变量(包括类变量和实例变量),也可以修饰局部变量、形参。

6. 1).final修饰成员变量:

       类变量:当类初始化时,系统会为类变量分配内存,并赋默认值。

       实例变量:当创建对象时,系统会为该对象的实例属性分配内存,并赋默认值。

   2).final修饰的类属性、实例属性能指定初始值的地方如下:

          类属性:静态初始化块或声明该属性时指定初始值。

          实例属性:非静态初始化块、声明该属性时或构造方法中指定初始值。

注意:实例属性不能在静态初始化块中指定初始值,因为静态初始化块是静态成员,不可访问实例属性—非静态成员;类属性不能在普通初始化块中指定初始值,因为类属性在类初始化阶段已经被初始化了,普通初始化块不能对其重新赋值。

对于final修饰的成员变量,一旦有了初始值就不能再被重新赋值,因此不可以在普通方法中对其重新赋值,成员变量只能在在定义其时指定默认值(显示赋值),或在静态初始化块、初始化块和构造方法中为成员变量指定初始值(即要么在定义成员变量时指定初始值,要么在初始化块、构造方法中为该属性重新赋值)。

Final修饰的成员变量必须赋初值,否则报错;原因:

  如果既没有在定义成员变量时指定默认值,也没有在初始化块、构造方法中为成员变量指定初始值,那么这些成员变量的值将一直是:0、’\u000’、false、null,失去了存在的意义。

 与普通变量不同的是,final成员变量(包括实例属性和类属性)必须由程序员进行显示初始化,即系统不会对final成员变量进行隐式初始化。

7.使用final修饰局部变量:

    由于系统不会对局部变量进行初始化,局部变量必须由程序员手动赋值,因此final修饰的局部变量既可以在定义时指定默认值,也可以不指定默认值。如果在定义时没有指定默认值,则可在后面代码中对该final变量赋初始值,但只能一次,不能重复赋值。可以在定义时指定默认值,则后面代码中不能再对该变量赋值。

     final修饰形参的情形:由于形参在调用该方法时,由系统根据传入的参数来完成初始化,因此使用final修饰的形参不能被赋值

8. final修饰基本类型和引用类型变量的区别 :

      当用final修饰基本类型变量时,不能对基本类型变量重新赋值,即基本类型变量的值不能被改变

      引用类型变量保存的是一个引用,final只保证这个引用(地址)不会改变,即一直引用同一个对象,但这个对象可以发生改变。

     final修饰的引用类型变量不能被重新赋值,但引用类型变量所引用的对象内容却可以被改变。

     如果final修饰的变量为基本数据类型,且在编译时就能确定改变量的值,则可以把该变量变成常量处理。常量名由多个有意义的单词大写组成,单词与单词之间以下划线分割,final修饰的变量是引用数据类型,final变量无法在编译时获得初值,而必须运行时才能得到值。

9. final方法

     1).final修饰的方法不可被重写,如果出于某些原因,不希望子类重写父类的某个方法,则可以使用final修饰该方法。

     2).final修饰的方法仅仅是不能被重写,并不是不能被重载

     3).final修饰的类不可有子类。例如,java.lang.Math类就是一个final类,它不可以有子类。(子类继承父类时将可以访问到父类的内部数据,并可通过重写父类方法来改变父类方法的实现细节,从而导致一些不安全的因素;因此,当需要保证某个类无法被继承时,可以用final修饰)

      Java提供的Object类里就有一个final方法:getClass()。因为java不希望任何类重写这个方法。

10.抽象方法声明格式:
[修饰符] abstract  返回值类型方法名([形式参数表]);

抽象方法的特点

ü    抽象方法的返回值类型前有关键字abstract;

ü    抽象方法没有方法体;抽象方法只有方法抽象签名,没有方法的实现部分。

ü    抽象方法的定义是一行单独语句,以分号结束;

ü    在抽象方法声明中使用static修饰符是错误的。

11. 抽象类(一个没有包含足够的信息以描绘一个具体的对象时的类)

     类中如果定义了抽象方法,这个类必须定义为抽象类。

     [public]  abstract  class 类名{

            //类体(属性、非抽象方法、抽象方法、构造方法)

            //类体(初始化块、内部类、枚举类)  

     }

µ   抽象类不能创建自己的对象,使用new创建抽象类对象将产生错误。抽象类不能被实例化,也不能创建实例。

µ   子类继承抽象类时,应该覆盖抽象类中的所有抽象方法,否则子类也必须定义为抽象类。

µ   抽象类可以含有属性、方法(普通方法、抽象方法都可以)、构造方法、初始化块、内部类、枚举类等六种成分。

µ   含有抽象方法的类(包括直接定义了一个抽象类方法;继承了一个抽象父类但没有完全实现父类包含的抽象方法;以及实现一个接口,但没有完全实现接口包含的抽象方法三种情况)只能被定义成抽象类。

µ   注意

含有抽象方法的类(包括直接定义了一个抽象方法;继承了一个抽象父类,但没有完全实现父类包含的抽象方法)只能被定义成抽象类。但抽象类中却并一定包含抽象方法。

抽象方法和空方法体的方法不是同一个概念
public abstract void test();
public void test(){}

     子类在实现从父类继承来的抽象方法时,其返回值类型、方法名、参数列表必须和父类相同,但不同的是子类有方法体,且不同的子类可以有不同的方法体。

 

12. 注意:

ü        final和abstract永远不能同时使用。(当abstract修饰类时只能被子类继承;修饰方法时只能重写,而final修饰的类不能被继承,修饰的方法不能被重写)

ü        abstract不能用于修饰属性,不能用于修饰局部变量,即没有抽象变量、没有抽象属性等说法;abstract也不能用于修饰构造方法,没有抽象构造方法。抽象类里定义的构造方法只能是普通构造方法。

ü        static和abstract不能同时修饰某个方法,即没有所谓的类抽象方法。(static修饰方法,表明这个方法属于当前类,即该方法可以通过类来调用;如果被定义成抽象方法,则将导致通过改类来调用该方法时出错,调用一个没有方法体的方法肯定错误)

ü        abstract关键字修饰的方法必须被其子类重写才有意义,否则这个方法将永远不会有方法体,因此abstract方法不能定义为private访问权

13. 抽象类的作用

ü    代码重用--子类可以重用抽象父类中的属性和非抽象方法;

ü    规划--抽象类中通过定义抽象方法规划了其所有子类必须要实现的功能,或者说指定了其子类对象与外界的交互界面,因为抽象方法的方法头部分已经规定了该方法将来被子类对象调用的格式。

14. 模板模式:抽象类作为多个子类的通用模板,子类在抽象类的基础上扩展、改造,但子类总体上会保留抽象类的行为方式。

     使用模版的简单规则如下:

 1).抽象父类可以只定义需要使用的某些方法,其余留给子类来实现。

2).父类可以包含已经实现的具体方法,通常这些方法只是定义了一个通用算法,其实现不需要完全由自身实现,而可以借助子类来实现。

ü    抽象类不能实例化,但抽象类可作为变量的类型和方法形参类型,可将抽象类子类的对象赋给该变量或做方法的实参。例如,
Shape s=new Rectangle();
public static String ShowShapinfo(Shape item){
      if(item instanceof Rectangle){
                    Rectangler=(Rectangle)item; //其他代码
      }
}

 

 

转载于:https://www.cnblogs.com/yangkai-cn/archive/2012/04/16/4017192.html

你可能感兴趣的:(Java心得---单例类、final修饰符、抽象类)