【Java基础教程】(十八)包及访问权限篇 · 下:Java编程中的权限控制修饰符、单例设计模式 (Singleton)和多例设计模式的综合探析~

这篇具有很好参考价值的文章主要介绍了【Java基础教程】(十八)包及访问权限篇 · 下:Java编程中的权限控制修饰符、单例设计模式 (Singleton)和多例设计模式的综合探析~。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【Java基础教程】(十八)包及访问权限篇 · 下:Java编程中的权限控制修饰符、单例设计模式 (Singleton)和多例设计模式的综合探析~,# Java基础教程,java,设计模式,单例模式,开发语言,后端,经验分享,java-ee

本节学习目标

  • 掌握Java 中的4种访问权限;
  • 掌握Java 语言的命名规范;
  • 掌握单例设计模式与多例设计模式的定义结构;

1️⃣ 访问控制权限

对于封装性,实际上之前只详细讲解了 private, 而封装性如果要想讲解完整,必须结合全部4种访问权限来看,这4种访问权限的定义如下表所示。

范围 private default protected public
同包的同类中
同包的不同类
不同包的子类
不同包的非子类

对于上表可以简单理解为: private 只能在本类中访问;default 只能在同一个包中访问;protected 可以在不同包的子类中访问;public 为所有类都可以访问。

前面文章中对于 privatedefaultpublic 都已经有所了解,所以本节主要讲解 protected

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

由于B类是A 的子类,所以在B 类中可以直接访问父类中的 protected 权限属性。

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

import com.xiaoshan.demob.B;

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

程序执行结果:

A 类的 info = Hello

此程序直接导入了B类 , 而后实例化对象调用 print() 方法,而在 print()方法中利用“super.info” 直接访问了父类中的 protected 权限属性。
而如果要在 com.xiaoshan.test 包中直接利用 Test 主类访问A 中的属性,由于它们不在同一个包下,也不存在继承关系,所以将无法访问。

//	范例 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);		//错误:无法访问
	}
}

此程序在进行编译时会直接提示用户,infoprotected 权限,所以无法被直接访问。

实际上在给出的4种权限中,有3种权限 ( privatedefaultprotected) 都是对封装的描述,也就是说面向对象的封装性现在才算是真正讲解完整。从实际的开发使用来讲,几乎不会使用到 default 权限,所以真正会使用到的封装概念只有两个权限 privateprotected

对于访问权限,初学者要把握以下两个基本使用原则即可。

  • 属性声明主要使用private权限;
  • 方法声明主要使用public权限。

2️⃣ 命名规范

命名规范的主要特点就是保证程序中类名称或方法等名称的标记明显一些,可是对于 Java 而言,有如下一些固定的命名规范还是需要遵守的。

  • 类名称:每一个单词的开头首字母大写,例如:TestDemo;
  • 变量名称:第一个单词的首字母小写,之后每个单词的首字母大写,例如: studentName;
  • 方法名称:第一个单词的首字母小写,之后每个单词的首字母大写,例如: printInfo();
  • 常量名称:每个字母大写,例如: FLAG;
  • 包名称:所有字母小写,例如:com.xiaoshanjava.util

需要注意以上所给出的5种命名规范,是所有开发人员都应该遵守的,而不同的开发团队也可能会有属于自己的命名规范,对于这些命名规范,在日后从事软件开发的过程中,都应该仔细遵守。

3️⃣ 单例设计模式 (Singleton)

在之前大部分的属性定义时都使用了 private 进行声明,而对于构造方法其实也可以使用 private 声明,则此时的构造方法就被私有化。而构造方法私有化之后会带来哪些问题,以及有什么作用呢?下面就来进行简单的分析。

首先在讲解私有化构造方法操作之前,来观察如下的程序。

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

程序运行结果:

Hello World.

在本程序中, Singleton 类里面存在构造方法 ( 因为如果一个类中没有明确地定义一个构造方法,则会自动生成一个无参的、什么都不做的构造方法) , 所以可以先直接实例化对象,再调用类中提供的 print()方法。下面将构造方法改变一下,即使用 private封装。

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

此程序在实例化 Singleton 类对象时,程序出现了编译错误,因为构造方法被私有化了,无法在外部调用,即无法在外部实例化 Singleton类的对象。

那么现在在保证 Singleton 类中的构造方法不修改不增加,以及 print()方法不修改的情况下,如何操作才可以让类的外部通过实例化对象去调用 print()方法呢?

思考一:使用 private 访问权限定义的操作只能被本类所访问,外部无法调用,现在既然构造方法被私有化,就证明这个类的构造方法只能被本类所调用,即只能在本类中产生本类实例化对象。

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

思考二: 对于一个类中的普通属性,默认情况下一定要在本类存在实例化对象后才可以进行调用,可是此程序在 Singleton 类的外部无法产生实例化对象,就必须想一个办法,让 Singleton 类中的 instance 属性可以在没有 Singleton 类实例化对象时来进行调用。因此可以使用 static 完成,static 定义的属性特点是由类名称直接调用,并且在没有实例化对象时候可以调用。

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

程序运行结果:

Hello World.

思考三: 类中的全部属性都应该封装,所以上边范例中的 instance 属性也应该进行封装,而封装之后要想取得属性,则要编写 getter方法,只不过这时的 getter 方法应该也由类名称直接调用,定义为 static 型。

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

程序运行结果:

Hello World.

思考四: 这样做的目的是什么?程序中的 instance 属性属于 static 定义,就表示所有 Singleton 类的对象不管有多少个对象声明,其本质都会共同拥有同一个 instance 属性引用,那么既然是同一个,又有什么意义呢?

如果要控制一个类中实例化对象的产生个数,首先要锁定的就是类中的构造方法(使用 private 定义构造方法), 因为在实例化任何新对象时都要使用构造方法,如果构造方法被锁,就自然就无法产生新的实例化对象。

如果要调用类中定义的操作,那么很显然需要一个实例化对象,这时就可以在类的内部使用 static 方式来定义一个公共的对象,并且每一次通过 static 方法返回唯一的一个对象,这样外部不管有多少次调用,最终一个类只能够产生唯一的一个对象,这样的设计就属于单例设计模式 (Singleton)。

不过本程序依然有一个问题,那就是以下代码也可以使用。

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

此程序中操作语法没有错误,也不需要考虑是否有意义,现在的代码也允许这样做,而这样做会发现之前表示唯一一个实例化对象的所有努力就白费了。因此,必须想办法废除这种做法,于是需要在定义 instance 的时候增加一个 final 关键字。

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

程序运行结果:

Hello World.

在使用 Singleton 类时,不管代码如何操作,也永远只会存在唯一的一个 Singleton 类的实例化对象,而这样的代码,在设计模式上就称为单例设计模式(Singleton)。

4️⃣ 多例设计模式

单例设计模式只留下一个类的一个实例化对象,而多例设计模式,会定义出多个对象。

例如:定义一个表示星期几的操作类,这个类的对象只能有7个实例化对象(星期一 ~星期日);定义一个表示性别的类,只能有2个实例化对象(男、女);定义一个表示颜色基色的操作类,只能有3个实例化对象(红、绿、蓝)。

这些情况下,这样的类就不应该由用户无限制地去创造实例化对象,应该只使用有限的几个,这个就属于多例设计。不管是单例设计还是多例设计,有一个核心不可动摇,即构造方法私有化。

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

程序执行结果:

此程序首先定义了一个描述性别的多例程序类,并且将其构造方法封装,然后利用 getInstance() 方法,接收指定编号后返回一个实例化好的Sex 类对象。

范例11的代码利用数字编号来取得了一个 Sex 类的对象,有朋友可能觉得这样做表示的概念不明确,那么为了更加明确要取得对象类型,可以引入一个接口进行说明。

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

此程序如果要取得指定的 Sex 类对象,可以利用接口中定义的全局常量(实际上也可以在Sex 类中定义一些全局常量)来进行判断。这样的做法是一种标准做法,但是这样做有一些复杂,所以利用字符串直接判断会更加简单一些。

在 JDK 1.7 之前, switch 只能支持对 intchar 类型进行判断,正因为如果纯粹是数字或字符意义不明确,所以增加了String 的支持。

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

程序执行结果:

此程序直接使用 String 作为 switch 的判断条件,这样在取得实例化对象时就可以利用字符串来描述对象名字,这一点要比直接使用数字更加方便。


温习回顾上一篇(点击跳转)《【Java基础教程】(十七)包及访问权限篇 · 上:包的定义及导入、常用系统包概览,javac、java和 jar命令的作用,package和 import关键字的应用~》

继续阅读下一篇(点击跳转)《【Java基础教程】(十九)异常捕获处理篇 · 上:异常的概念及处理流程解析,try、catch、finally、throws、throw的作用,RuntimeException类介绍~》
文章来源地址https://www.toymoban.com/news/detail-599901.html

【Java基础教程】(十八)包及访问权限篇 · 下:Java编程中的权限控制修饰符、单例设计模式 (Singleton)和多例设计模式的综合探析~,# Java基础教程,java,设计模式,单例模式,开发语言,后端,经验分享,java-ee

到了这里,关于【Java基础教程】(十八)包及访问权限篇 · 下:Java编程中的权限控制修饰符、单例设计模式 (Singleton)和多例设计模式的综合探析~的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Java基础教程】(三)程序概念篇 · 上:探索Java编程基础,注释、标识符、关键字、数据类型~

    掌握Java中标识符的定义; 掌握Java中数据类型的划分以及基本数据类型的使用原则; 掌握Java运算符的使用; 在编写程序时,为了提高程序的可维护性,我们可以在代码中添加注释。 注释是一种说明性的文字,不会被编译器编译执行 。 Java提供了三种注释形式: // :单行注

    2024年02月12日
    浏览(160)
  • Java基础(十八)Collection

    使用一个List集合存储多个元素。计算集合中共有多少个不重复元素并输出。 有两个List集合, 计算两个集合的交集元素。 有两个List集合, 计算第一个集合对第二个集合的差集元素。 有两个List集合, 计算两个集合的对称差集元素。 有两个List集合, 计算两个集合的并集元素。 使

    2024年02月09日
    浏览(37)
  • 【Linux命令行与Shell脚本编程】第十八章 文本处理与编辑器基础

    文本处理 学习sed编辑器 sed编辑器基础命令 gawk编辑器入门 sed编辑器基础 shell脚本可以将文本文件中各种数据的日常处理任务自动化Linux中的sed和gawk两款工具能够极大地简化数据处理任务。 想要即时处理文本文件中的文本,有一个可以自动格式化、插入、修改或删除文本元素

    2024年02月13日
    浏览(52)
  • 计算机网络技术与JAVA网络编程URL编程-----JAVA入门基础教程-----计算机网络经典

    import org.junit.jupiter.api.Test; import java.io.*; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; public class URLTest { public static void main(String[] args) { //URL:统一资源定位符(种子),一个URL就定位着互联网上某个资源的地址 //http:应用层协议,IP地址,端口号,资源地址,参数

    2024年02月15日
    浏览(62)
  • 计算机网络技术与JAVA网络编程UDP编程-----JAVA入门基础教程-----计算机网络经典

    import org.junit.jupiter.api.Test; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.*; public class UDP { public static void main(String[] args) { DatagramSocket datagramSocket = null; try { datagramSocket = new DatagramSocket(); InetAddress inetAddress = InetAddress.getByName(\\\"127.0.0.1\\\"); int port = 9090; byte[] byte

    2024年02月15日
    浏览(53)
  • 【Java基础教程】(四)程序概念篇 · 中:探索Java编程基础,解析各类运算符功能、用法及其应用场景~

    掌握Java中各类运算符及其运算使用; Java中的语句有很多种形式,表达式就是其中一种形式。 Java中的表达式由操作数、运算符、结果类型和求值顺序等元素组成 ,这些元素共同构成了复杂的逻辑和计算过程。 操作数(Operands) :操作数是表达式中的值或者变量,它们可以是

    2024年02月12日
    浏览(67)
  • 【JavaSE】Java基础语法(十八):接口

    接口就是一种公共的规范标准,只要符合规范标准,大家都可以通用。 Java中接口存在的两个意义 用来定义规范 用来做功能的拓展 接口用interface修饰 类实现接口用implements表示 接口不能实例化 我们可以创建接口的实现类对象使用 接口的子类 要么重写接口中的所有抽

    2024年02月06日
    浏览(58)
  • Java基础十八(正则表达式 + 日期时间)

    1.1 普通字符 字符 描述 示例 [abc] 匹配 […] 中所有字符 [hlo] 匹配字符串 \\\"hello world\\\" 中所有的 h l o 字母 [^ABC] 匹配除了 […] 中所有字符 [hlo] 匹配字符串 \\\"hello world\\\" 中除了 h l o 的所有字母 [^a-z] 匹配除了 […] 中所有字符 [hlo] 匹配字符串 \\\"hello world\\\" 中除了 a 到 z 的所有字母 [A-

    2024年02月11日
    浏览(59)
  • java的四种访问权限

    1、public: 所修饰的类、变量、方法,在内外包均具有访问权限,Public (公有) 访问权限较为宽松的一种,不仅可以被跨类访问,而且可以跨包访问。 2、protected: 这种权限是为继承而设计的,protected所修饰的成员,对所有子类是可访问的,但只对同包的类是可访问的,对外

    2024年02月15日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包