[Tutorial básico de Java] (Dieciocho) Paquetes y permisos de acceso, Parte 2: análisis exhaustivo de los modificadores de control de permisos, patrones de diseño singleton (Singleton) y patrones de diseño multicaso en programación Java~

inserte la descripción de la imagen aquí

Objetivos de aprendizaje para esta sección

  • Domina los 4 derechos de acceso en Java;
  • Domine las convenciones de nomenclatura del lenguaje Java;
  • Domine la estructura de definición del patrón de diseño singleton y el patrón de diseño de casos múltiples;

1️⃣ Permisos de control de acceso

Para la encapsulación, de hecho, solo lo expliqué en detalle antes private, pero si desea explicar la encapsulación por completo, debe combinar los 4 tipos de derechos de acceso. Las definiciones de estos 4 tipos de derechos de acceso se muestran en la siguiente tabla.

alcance privado por defecto protegido público
en la misma categoría
diferentes clases en el mismo paquete
Subclases de diferentes paquetes.
No subclases de paquetes diferentes

La tabla anterior se puede entender simplemente como: privatesolo se puede acceder en esta clase; defaultsolo se puede acceder en el mismo paquete; protectedse puede acceder en subclases de diferentes paquetes; publicse puede acceder para todas las clases.

En el artículo anterior , ya hemos aprendido acerca de private, y, por lo que esta sección defaultexplica principalmente .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);
	}
}

Dado que Bla clase es Auna subclase de , Bse puede acceder directamente protectedal atributo de permiso de la clase principal en la clase .

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

import com.xiaoshan.demob.B;

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

Resultado de la ejecución del programa:

A 类的 info = Hello

Este programa importa directamente la clase B y luego crea una instancia del objeto para llamar print()al método y print()usa " super.info" en el método para acceder directamente protectedal atributo de permiso en la clase principal.
Y si desea usar directamente la clase principal para acceder a los atributos en com.xiaoshan.testel paquete , porque no están en el mismo paquete y no hay una relación de herencia, no serán accesibles.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);		//错误:无法访问
	}
}

Este programa preguntará directamente al usuario al compilar, infoes protectedun permiso, por lo que no se puede acceder directamente.

De hecho, entre los 4 tipos de permisos otorgados, 3 tipos de permisos ( private, default, protected) son todas descripciones de encapsulación, es decir, la encapsulación orientada a objetos ahora se explica completamente. En términos de desarrollo y uso reales, los permisos rara vez se usan , por lo que solo hay dos conceptos de permisos y encapsulación defaultque se usan realmente private.protected

Para los derechos de acceso, los principiantes deben comprender los siguientes dos principios básicos de uso.

  • El atributo declara el permiso de uso principal private;
  • Las declaraciones de métodos utilizan principalmente publicpermisos.

2️⃣ Convención de nomenclatura

La característica principal de la convención de nomenclatura es garantizar que el nombre de la clase o el nombre del método en el programa esté claramente marcado, pero para Java, hay algunas convenciones de nomenclatura fijas que deben seguirse.

  • Nombre de la clase: la primera letra de cada palabra se escribe en mayúscula, por ejemplo: TestDemo;
  • Nombre de la variable: la primera letra de la primera palabra está en minúscula y la primera letra de cada palabra posterior está en mayúscula, por ejemplo: studentName;
  • Nombre del método: la primera letra de la primera palabra está en minúsculas y la primera letra de cada palabra posterior está en mayúsculas, por ejemplo: printInfo();
  • Nombres constantes: escriba en mayúscula cada letra, por ejemplo: FLAG;
  • Nombre del paquete: todas las letras en minúsculas, por ejemplo: com.xiaoshanjava.util.

Cabe señalar que todos los desarrolladores deben seguir las cinco convenciones de nomenclatura dadas anteriormente, y que los diferentes equipos de desarrollo también pueden tener sus propias convenciones de nomenclatura.Estas convenciones de nomenclatura deben seguirse cuidadosamente en el proceso de desarrollo de software en el futuro.

3️⃣ Patrón de diseño Singleton (Singleton)

La mayoría de las definiciones de atributos se utilizan para privatedeclarar, pero el constructor también se puede privatedeclarar, y el constructor en este momento está privatizado. ¿Y qué problemas surgirán después de la privatización del constructor, y qué efecto tendrá? Hagamos un análisis simple.

Primero, antes de explicar el funcionamiento del constructor privado, observemos el siguiente programa.

//	范例 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();                                       //调用方法
	}
}

Resultado de la ejecución del programa:

Hello World.

En este programa, Singletonhay un método de construcción en la clase (porque si un método de construcción no está definido explícitamente en una clase, se generará automáticamente un método de construcción sin parámetros y sin hacer nada), por lo que primero puede instanciar directamente el objeto y luego llamar al método provisto en la clase print(). Cambiemos el método de construcción, es decir, usemos privateencapsulación.

//	范例 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();                      //调用方法
	}
}

Cuando este programa instancia el objeto de la clase, el programa tiene un error de compilación, porque el constructor está privatizado y no se puede llamar externamente, es decir, el objeto de la clase Singletonno se puede instanciar externamente .Singleton

Ahora, en el caso de garantizar que Singletonel método de construcción en la clase no se modifique ni se agregue, y que el método no se modifique, ¿cómo puede el exterior de la clase llamar al método instanciando el objeto?print()print()

Pensamiento 1: privateLas operaciones definidas con permisos de acceso solo pueden ser accedidas por esta clase y no pueden ser llamadas externamente. Ahora que el método de construcción está privatizado, prueba que el método de construcción de esta clase solo puede ser llamado por esta clase, es decir, solo los objetos instanciados de esta clase pueden generarse en esta clase.

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

Pensamiento 2: Para los atributos ordinarios en una clase, por defecto, deben llamarse después de que haya objetos instanciados en esta clase, pero este programa no puede generar objetos instanciados fuera de la clase, por lo que debemos encontrar una manera de permitir que los atributos en la clase sean llamados cuando no hay un objeto instanciado Singletonde Singletonla clase instance. SingletonPor lo tanto, se puede hacer staticusando , staticlos rasgos de propiedad definidos se llaman directamente por el nombre de la clase y se pueden llamar cuando no se instancia ningún objeto.

//	范例 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();	//调用方法 
	}
}

Resultado de la ejecución del programa:

Hello World.

Pensamiento 3: todos los atributos de la clase deben encapsularse, por lo que instanceel atributo del ejemplo anterior también debe encapsularse, y para obtener el atributo después de la encapsulación, debe escribir getterun método, pero en este momento getterel método también debe ser llamado directamente por el nombre de la clase, definido como statictipo.

//	范例 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();			//调用方法
	}
}

Resultado de la ejecución del programa:

Hello World.

Pensamiento 4: ¿Cuál es el propósito de hacer esto? instanceEl atributo en el programa pertenece a staticla definición, lo que significa que Singletonno importa cuántas declaraciones de objetos haya, todos los objetos de la clase compartirán la misma instancereferencia de atributo, así que dado que son iguales, ¿cuál es el punto?

Si desea controlar la cantidad de objetos instanciados en una clase, lo primero que debe bloquear es el constructor en la clase (utilícelo para privatedefinir el constructor), porque el constructor debe usarse al instanciar cualquier objeto nuevo. Si el constructor está bloqueado, naturalmente será imposible generar nuevos objetos instanciados.

Si desea llamar a las operaciones definidas en la clase, obviamente necesita un objeto instanciado. En este momento, puede usar el método dentro de la clase staticpara definir un objeto público y staticdevolver un objeto único cada vez que pasa por el método, de modo que no importa cuántas veces haya llamadas externas, una clase solo puede generar un objeto único al final. Este diseño pertenece al patrón de diseño singleton ( ) Singleton.

Sin embargo, todavía hay un problema con este programa, es decir, también se puede usar el siguiente código.

//	范例 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;
	}
}

No hay nada malo con la sintaxis de la operación en este programa, y ​​no hay necesidad de considerar si tiene sentido, y el código actual lo permite, y al hacerlo descubrirá que todos los esfuerzos anteriores para representar el único objeto instanciado se han desperdiciado. Por lo tanto, debemos encontrar una manera de abolir esta práctica, por lo que debemos instanceagregar una finalpalabra clave al definir .

//	范例 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();		//调用方法
	}
}

Resultado de la ejecución del programa:

Hello World.

Al usar Singletonla clase, sin importar cómo opere el código, siempre habrá un solo Singletonobjeto instanciado de la clase, y dicho código se denomina patrón de diseño singleton ( Singleton) en el patrón de diseño.

4️⃣ Patrón de diseño de múltiples instancias

El patrón de diseño singleton deja solo un objeto instanciado de una clase, mientras que el patrón de diseño de instancias múltiples define varios objetos.

Por ejemplo: defina una clase de operación que represente el día de la semana, y los objetos de esta clase solo pueden tener 7 objetos instanciados ( ) 星期一 ~星期日; defina una clase que represente género, y solo tenga 2 objetos instanciados ( 男、女); defina una clase de operación que represente el color base, y solo tenga 3 objetos instanciados ( 红、绿、蓝).

En estos casos, dicha clase no debería permitir a los usuarios crear objetos instanciados sin restricciones, y solo debería usarse un número limitado, que pertenece al diseño de múltiples instancias. Ya sea un diseño de instancia única o un diseño de múltiples instancias, existe un núcleo inquebrantable, es decir, la privatización del método de construcción.

//	范例 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);
	}
}

Resultado de la ejecución del programa:

Este programa primero define una clase de programa de múltiples instancias que describe el género y encapsula su método de construcción, y luego usa el getInstance()método para devolver un Sexobjeto de clase instanciado después de recibir el número especificado.

El código del Ejemplo 11 obtiene un Sexobjeto de una clase usando números. Algunos amigos pueden sentir que el concepto expresado por este método no es claro. Para obtener el tipo de objeto más claramente, se puede introducir una interfaz para explicarlo.

//	范例 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);
	}
}

Si este programa quiere obtener el Sexobjeto de clase especificado, puede usar las constantes globales definidas en la interfaz (de hecho, Sexalgunas constantes globales también se pueden definir en la clase) para juzgar. Este enfoque es una práctica estándar, pero es un poco complicado, por lo que será más fácil usar cadenas para juzgar directamente.

Antes de JDK 1.7, switchsolo puede admitir el juicio de into tipo, solo porque si se trata de números o caracteres puramente, el significado no está claro, por lo que se agrega el soporte de.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);
	}
}

Resultado de la ejecución del programa:

Este programa usa directamente Stringcomo switchcondición de juicio, de modo que al obtener el objeto instanciado, la cadena de caracteres se puede usar para describir el nombre del objeto, lo cual es más conveniente que usar números directamente.


Revisa el artículo anterior (haz clic para saltar) : "[Tutorial básico de Java] (Diecisiete) Paquetes y permisos de acceso Parte 1: Definición e importación de paquetes, descripción general de los paquetes comunes del sistema, funciones de los comandos javac, java y jar, aplicación del paquete y palabras clave de importación ~"

Continúe leyendo el siguiente artículo (haga clic para saltar) : "[Tutorial básico de Java] (19) Captura y procesamiento de excepciones Parte 1: El concepto de excepción y análisis del flujo de procesamiento, el rol de probar, capturar, finalmente, lanzar, lanzar, la introducción de la clase RuntimeException~"

Supongo que te gusta

Origin blog.csdn.net/LVSONGTAO1225/article/details/131789632
Recomendado
Clasificación