这里简单说说我对Java访问权限控制和设计模式——单例设计模式的理解。
我们知道关于Java编程语言的特点中有一个叫做封装,我个人对封装的理解有两点:类和访问权限控制。
对于一个类的设计而言,可以分为两部分:属性和方法。好比一个人,他有生理心理上的各种特点(属性),也有着吃穿住行等 一系列行为(方法)。这个人有一个好朋友,但是不管关系多好,这个人都不会允许他的朋友知道他的生理心理上的一些特点,也就是这个人的隐私,也就是说这个人只会允许他的朋友知道他想让他知道的,不想让他知道的就不让他知道。
那么这些东西对应到程序设计里面应该怎么设计呢?
很显然,类的访问权限控制起到作用了。
Java中类的访问权限控制有四种:private,protected,default,public。
对于类的属性,我们应该尽可能的设置为private。类不想除自己之外的类还能获知这一属性,除非特殊情况,这个时候类就会提供相关接口供其他的类访问这个属性。
对于protected、default这两种权限控制,在同一个包中两者功能大致相同:在同一个包中的类都有权限访问这个属性或者方法。但是如果不在同一个包中,两者的区别就显示出来了,假设在包A中的类MyClass有方法fun1()和fun2(),两个方法的访问权限控制分别是protected和default,那么在包中的类如果继承了MyClass,这个类是可以访问fun1(),而不能访问fun2()的。简单的来说,就是在有继承发生的情况下,子类对于protected和default修饰的属性和方法的访问权限是不一样的。
对于public,这是访问权限最大的控制修饰符了,包内、包外都是可以访问public修饰的属性和方法。
那么这和单例设计模式模式有什么关系呢?
这里就涉及到了创建类的实例的过程了。在Java中,类中有一个很特殊的方法叫做构造器方法,它是在对类进行初始化的时候回调用的一个方法。一般情况下,每个类都会有一个默认的构造器方法,但是如果我们为一个类现实的声明了一个构造器方法,这是类在初始化的时候就会调用我们声明的构造器方法。
类中默认的构造器方法:
public class Constractor {
public static void main(String [] args)
{
//这里创建一个类的实例创建过程中会调用器默认的构造器方法
MyClass mc = new MyClass();
//实例调用类中的方法。
mc.show();
}
}
class MyClass{
//这里会有默认的构造器方法,如下:
public MyClass()
{
}
//这是类中一个普通的方法
public void show()
{
System.out.println("this ia a common function().");
}
}
我们显式的声明构造器方法,这个时候就会调用我们声明的构造器方法:
public class Constractor {
public static void main(String [] args)
{
//这里会调用我们声明的构造器方法,我们会在控制台上看到输出信息。
MyClass mc = new MyClass();
//实例调用类中的方法。
mc.show();
}
}
class MyClass{
//显式的声明自己构造器方法,如下:
public MyClass()
{
System.out.println("this is my constractor.");
}
//这是类中一个普通的方法
public void show()
{
System.out.println("this ia a common function().");
}
}
在看到类的构造器方法之后,如果将构造器方法和访问权限控制结合到一起,这个时候就会发生特别的事情:
public class Constractor {
public static void main(String [] args)
{
//在这里我们创建实例的时候,突然发现不能创建类的实例了。
//下面这条语句会报错。
MyClass mc = new MyClass();
}
}
class MyClass{
//显式的声明自己构造器方法,如下:
private MyClass()
{
System.out.println("this is my constractor.");
}
//这是类中一个普通的方法
public void show()
{
System.out.println("this ia a common function().");
}
}
我们发现将类的构造器方法设置为private的之后我们不能创建类的实例了!当然这是合理的也是安全的,我们知道创建类的实例的时候会调用构造器方法,可是如果构造器方法是private,那么类外是不能访问的,除了类的自身。
那么,我们可不可以在类中实现一个方法,它可以访问private构造器方法,而且返回值类型是一种特殊类型——返回值类型是这个类!于是单例设计出现了:
public class Constractor {
public static void main(String [] args)
{
//这里我们就可以调用类中提供给外部的接口,得到一个类的实例:
MyClass mc = MyClass.getInstance();
//调用其内部的方法:
mc.show();
}
}
class MyClass{
//显式的声明一个private的构造器方法
private MyClass()
{
}
//一个特殊的私有属性,数据类型是MyClss的一个实例。
private static MyClass instance;
//这里提供一个特殊方法,返回值类型是MyClass:
//也是对类外提供的方法。
public static MyClass getInstance()
{
if(instance == null)
{
return new MyClass();
}
return instance;
}
//这里写一个简单的方法.
public void show()
{
System.out.println("this is a common function().");
}
}
在上面的实现中,可能有些人会感觉到奇怪,我相信这是因为对static的不理解,请读者阅读本人博客中的static介绍或者上网学习,理解了static之后相信必然会豁然开朗。