[Java Basic Tutorial] (Eighteen) Packages and Access Permissions Part 2: Comprehensive analysis of permission control modifiers, singleton design patterns (Singleton) and multi-case design patterns in Java programming~

insert image description here

Learning objectives for this section

  • Master the 4 access rights in Java;
  • Master the naming conventions of the Java language;
  • Master the definition structure of singleton design pattern and multi-case design pattern;

1️⃣ Access Control Permissions

For encapsulation, in fact, I only explained it in detail before private, but if you want to explain the encapsulation completely, you must combine all 4 kinds of access rights. The definitions of these 4 kinds of access rights are shown in the following table.

scope private default protected public
in the same category
different classes in the same package
Subclasses of different packages
Non-subclasses of different packages

The above table can be simply understood as: privateit can only be accessed in this class; defaultit can only be accessed in the same package; protectedit can be accessed in subclasses of different packages; publicit can be accessed for all classes.

In the previous article , we have already learned about private, default, and , so this section mainly explains .publicprotected

//	范例 1: 定义 com.xiaoshan.demoa.A 类
package com.xiaoshan.demoa; 

public class A{
    
    
	protected String info="Hello";//使用 protected权限定义
}
//	范例 2: 定义 com.xiaoshan.demob.B 类,此类继承A 类
package com.xiaoshan.demob;

import com.xiaoshan.demoa.A;

public class B extends A{
    
        // B是A 不同包的子类
	public void print(){
    
                  //直接访问父类中的protected属性
		System.out.println("A 类的 info = "+ super.info);
	}
}

Since Bthe class is Aa subclass of , the permission attribute Bin the parent class can be directly accessed in the class .protected

//	范例 3: 代码测试
package com.xiaoshan.test;

import com.xiaoshan.demob.B;

public class Test {
    
    
	public static void main(String args[]){
    
    
		new B().print();
	}
}

Program execution result:

A 类的 info = Hello

This program directly imports class B, and then instantiates the object to call print()the method, and print()uses " super.info" in the method to directly access protectedthe permission attribute in the parent class.
And if you want to directly use the main class to access the attributes in com.xiaoshan.testthe package , because they are not in the same package, and there is no inheritance relationship, they will not be accessible.TestA

//	范例 4: 错误的访问
package com.xiaoshan.test;

import com.xiaoshan.demoa.A;

public class Test {
    
    
	public static void main(String args[]){
    
    
		A a = new A();
		System.out.println(a.info);		//错误:无法访问
	}
}

This program will directly prompt the user when compiling, infoit is protecteda permission, so it cannot be directly accessed.

In fact, among the 4 kinds of permissions given, 3 kinds of permissions ( private, default, protected) are all descriptions of encapsulation, that is to say, the object-oriented encapsulation is now truly explained completely. In terms of actual development and use, permissions are rarely used , so there are only two permissions and encapsulation defaultconcepts that are really used private.protected

For access rights, beginners should grasp the following two basic usage principles.

  • The attribute declares the main usage privaterights;
  • Method declarations primarily use publicpermissions.

2️⃣ Naming convention

The main feature of the naming convention is to ensure that the class name or method name in the program is clearly marked, but for Java, there are some fixed naming conventions that need to be followed.

  • Class name: the first letter of each word is capitalized, for example: TestDemo;
  • Variable name: the first letter of the first word is lowercase, and the first letter of each word after that is capitalized, for example: studentName;
  • Method name: the first letter of the first word is lowercase, and the first letter of each word after that is capitalized, for example: printInfo();
  • Constant names: capitalize each letter, for example: FLAG;
  • Package name: all lowercase letters, for example: com.xiaoshanjava.util.

It should be noted that the five naming conventions given above should be followed by all developers, and different development teams may also have their own naming conventions. For these naming conventions, they should be carefully followed in the process of software development in the future.

3️⃣ Singleton design pattern (Singleton)

Most of the attribute definitions used to privatedeclare, but the constructor can also be privatedeclared, and the constructor at this time is privatized. And what problems will arise after the privatization of the constructor, and what effect will it have? Let's do a simple analysis.

First, before explaining the operation of the private constructor, let's observe the following program.

//	范例 5: 构造方法非私有化
class Singleton {
    
                     	//定义一个类,此类默认提供无参构造方法
	public void print(){
    
    
		System.out.println("Hello World.");
	}
}

public class TestDemo{
    
    
	public static void main(String args[])(
		Singleton inst = null;                          //声明对象
		inst = new Singleton(;                       //实例化对象
		inst.print();                                       //调用方法
	}
}

Program running result:

Hello World.

In this program, Singletonthere is a construction method in the class (because if a construction method is not explicitly defined in a class, a construction method without parameters and doing nothing will be automatically generated), so you can directly instantiate the object first, and then call the method provided in the class print(). Let's change the construction method, that is, use privateencapsulation.

//	范例 5: 私有化构造方法
class Singleton{
    
                                           //定义一个类
	private  Singleton(){
    
                                     //构造方法私有化
	}
	public void print(){
    
    
		System.out.println("Hello World.");
	}
}

public class TestDemo {
    
    
	public static void main(String args[]){
    
    
		Singleton inst = null;               //声明对象
		inst = hew Singletono:           //错误:The constructor Singleton() is not visible
		inst.print();                      //调用方法
	}
}

When this program instantiates the class object, the program has a compilation error, because the constructor is privatized and cannot be called externally, that is, the object of the class Singletoncannot be instantiated externally .Singleton

So now, in the case of ensuring that Singletonthe construction method in the class is not modified or added, and the method is not modified, how can the outside of the class call the method by instantiating the object?print()print()

Thinking 1: privateOperations defined with access permissions can only be accessed by this class, and cannot be called externally. Now that the construction method is privatized, it proves that the construction method of this class can only be called by this class, that is, only instantiated objects of this class can be generated in this class.

//	范例 6: 第一步思考
class Singleton {
    
    	//定义一个类
	Singleton instance = new Singleton();	//在内部实例化本类对象
	
	private Singleton(){
    
    	//构造方法私有化
	}
	
	public void print(){
    
    
		System.out.println("Hello World.");
	}
}

Thinking 2: For ordinary attributes in a class, by default, they must be called after there are instantiated objects in this class, but this program cannot generate instantiated objects outside the class, so we must find a way to allow the attributes in the class to be called when there is no instantiated object Singletonof Singletonthe class instance. SingletonSo it can be staticdone using , staticdefined property traits are called directly by the class name, and can be called when no object is instantiated.

//	范例 7: 第二步思考
class Singleton {
    
    	//定义一个类

	static Singleton instance = new Singleton();	//可以由类名称直接访问  

	private Singleton(){
    
    	//构造方法私有化
	}
	
	public void print(){
    
    
		System.out.println("Hello World.");
	}
}
	
public class TestDemo {
    
    
	public static void main(String args[]){
    
     
		Singleton inst = null; //声明对象
		inst = Singleton.instance; //利用“类.static属性”方式取得实例化对象
		inst.print();	//调用方法 
	}
}

Program running result:

Hello World.

Thinking 3: All attributes in the class should be encapsulated, so the attribute in the above example instanceshould also be encapsulated, and to get the attribute after encapsulation, you need to write gettera method, but at this time getterthe method should also be called directly by the class name, defined as statictype.

//	范例 8: 第三步思考
class Singleton {
    
                    	//定义一个类
	private static Singleton instance = new Singleton();
	
	private Singleton(){
    
             	//构造方法私有化
	}
	
	public void print(){
    
    
		System.out.println("Hello World.");
	}
	
	public static Singleton getInstance(){
    
                     //取得本类对象
		return instance;
	}
}

public class TestDemo(
	public static void main(String args[]){
    
     
		Singleton inst = null;			//声明对象
		inst = Singleton.getInstance();	//利用“类.static方法()”取得实例化对象
		inst.print();			//调用方法
	}
}

Program running result:

Hello World.

Thinking 4: What is the purpose of doing this? instanceThe attribute in the program belongs to staticthe definition, which means that Singletonno matter how many object declarations there are, all objects of the class will share the same instanceattribute reference, so since they are the same, what is the point?

If you want to control the number of instantiated objects in a class, the first thing you need to lock is the constructor in the class (use to privatedefine the constructor), because the constructor must be used when instantiating any new object. If the constructor is locked, it will naturally be impossible to generate new instantiated objects.

If you want to call the operations defined in the class, you obviously need an instantiated object. At this time, you can use the method inside the class staticto define a public object, and staticreturn a unique object every time through the method, so that no matter how many times there are external calls, a class can only generate a unique object in the end. This design belongs to the singleton design pattern ( ) Singleton.

However, there is still a problem with this program, that is, the following code can also be used.

//	范例 9: 程序出现的问题
class Singleton {
    
           //定义一个类
	private static Singleton instance = new Singleton();
	
	private Singleton(){
    
      	//构造方法私有化
	}
	
	public void print(){
    
    
		System.out.println("Hello World.");
	}
	
	public static Singleton getInstance(){
    
    	// 取得本类对象   
		instance = new Singleton();	//重新实例化对象
		return instance;
	}
}

There is nothing wrong with the syntax of the operation in this program, and there is no need to consider whether it makes sense, and the current code allows it, and doing so will find that all previous efforts to represent the only instantiated object have been wasted. Therefore, we must find a way to abolish this practice, so we need to instanceadd a finalkeyword when defining .

//	范例 10: 一个完整的单例模式的程序 
class Singleton {
    
                     	//定义一个类
	private final static Singleton instance = new Singleton();
	
	private Singleton(){
    
            	//构造方法私有化
	}
	
	public void print(){
    
    
		System.out.println("Hello World.");
	}
	
	public static Singleton getInstance(){
    
    	//取得本类对象
		return instance;
	}
}

public class TestDemo{
    
    
	public static void main(String args[]){
    
     
		Singleton inst = null;	//声明对象
		inst =  Singleton.getInstance(); 	//利用“类.static方法()”取得实例化对象
		inst.print();		//调用方法
	}
}

Program running result:

Hello World.

When using Singletonthe class, no matter how the code operates, there will always be only one Singletoninstantiated object of the class, and such code is called the singleton design pattern ( Singleton) in the design pattern.

4️⃣ Multiple instance design pattern

The singleton design pattern leaves only one instantiated object of a class, while the multi-instance design pattern defines multiple objects.

For example: define an operation class that represents the day of the week, and the objects of this class can only have 7 instantiated objects ( 星期一 ~星期日); define a class that represents gender, and only have 2 instantiated objects ( 男、女); define an operation class that represents the color base color, and only have 3 instantiated objects ( 红、绿、蓝).

In these cases, such a class should not allow users to create instantiated objects without restriction, and only a limited number should be used, which belongs to the multi-instance design. Whether it is a single-instance design or a multi-instance design, there is an unshakable core, that is, the privatization of the construction method.

//	范例 11: 定义一个表示性别的类
package com.xiaoshan.demo;

class Sex{
    
    
	private String title;
	private static final Sex MALE = new Sex("男");
	private static final Sex FEMALE = new Sex("女");
	
	private Sex(String title){
    
    		//构造私有化
		this.title = title;
	}
	public String toString(){
    
    
		return this.title;
	}
	
	public static Sex getInstance(int ch){
    
    	//返回实例化对象
		switch (ch){
    
    
			case 1:
				return MALE;
			case 2:
				return FEMALE;
			default:
				return;
		}
	}
}

public class TestDemo  {
    
    
	public static void main(String args[]){
    
    
		Sex sex = Sex.getInstance(2);
		System.out.println(sex);
	}
}

Program execution result:

This program first defines a multi-instance program class that describes gender, and encapsulates its construction method, and then uses the getInstance()method to return an instantiated Sexclass object after receiving the specified number.

The code in Example 11 obtains an Sexobject of a class by using numbers. Some friends may feel that the concept expressed by this method is not clear. In order to obtain the object type more clearly, an interface can be introduced to explain it.

//	范例 12: 利用接口标记对象内容
interface Choose {
    
    
	public int MAN = 1;		//描述数字
	public int WOMAN = 2;		//描述数字
}

public class TestDemo  {
    
    
	public static void main(String args[]){
    
    	//利用接口标记内容取得对象
		Sex sex = Sex.getInstance(Choose.MAM); 
		System.out.println(sex);
	}
}

If this program wants to obtain the specified Sexclass object, it can use the global constants defined in the interface (in fact, Sexsome global constants can also be defined in the class) to judge. This approach is a standard practice, but it is a bit complicated, so it will be easier to use strings to judge directly.

Before JDK 1.7, switchit can only support the judgment of intor type, just because if it is purely numbers or characters, the meaning is not clear, so the support of is added.charString

//	范例 13: 对取得Sex 类对象进行修改
package com.xiaoshan.demo;

class Sex{
    
    
	private String title;
	private static final Sex MALE = new Sex("男");
	private static final Sex FEMALE = new Sex("女");
	
	private Sex(String title){
    
    		//构造私有化
		this.title = title;
	}
	public String toString(){
    
    
		return this.title;
	}
	public static Sex getInstance(String ch){
    
    
		switch (ch){
    
                   	//利用字符串判断
			case "man":
				return MALE;
			case "woman":
				return FEMALE;
			default:
				return null;
		}
	}
}

public class TestDemo {
    
    
	public static void main(String args[]){
    
    
		Sex sex = Sex.getInstance("man");
		System.out.println(sex);
	}
}

Program execution result:

This program directly uses Stringas switchthe judgment condition, so that when obtaining the instantiated object, the character string can be used to describe the object name, which is more convenient than directly using numbers.


Review the previous article (click to jump) : "[Java Basic Tutorial] (Seventeen) Packages and Access Permission Part 1: Definition and import of packages, overview of common system packages, functions of javac, java and jar commands, application of package and import keywords~"

Continue reading the next article (click to jump) : "[Java Basic Tutorial] (19) Exception Capture and Processing Part 1: The concept of exception and analysis of the processing flow, the role of try, catch, finally, throws, throw, the introduction of the RuntimeException class~"

Guess you like

Origin blog.csdn.net/LVSONGTAO1225/article/details/131789632