企业网站建设既可以外包给专业的网站建设服务公司,什么项目必须走辽宁建设工程信息网,免费做游戏网站,wordpress删除模板Java基础教程之包及访问权限 下 本节学习目标1️⃣ 访问控制权限2️⃣ 命名规范3️⃣ 单例设计模式 (Singleton)4️⃣ 多例设计模式 本节学习目标
掌握Java 中的4种访问权限#xff1b;掌握Java 语言的命名规范#xff1b;掌握单例设计模式与多例设计模式的定义结构#x… Java基础教程之包及访问权限 · 下 本节学习目标1️⃣ 访问控制权限2️⃣ 命名规范3️⃣ 单例设计模式 (Singleton)4️⃣ 多例设计模式 本节学习目标
掌握Java 中的4种访问权限掌握Java 语言的命名规范掌握单例设计模式与多例设计模式的定义结构
1️⃣ 访问控制权限
对于封装性实际上之前只详细讲解了 private, 而封装性如果要想讲解完整必须结合全部4种访问权限来看这4种访问权限的定义如下表所示。
范围privatedefaultprotectedpublic同包的同类中√√√√同包的不同类√√不同包的子类√√不同包的非子类√
对于上表可以简单理解为 private 只能在本类中访问default 只能在同一个包中访问protected 可以在不同包的子类中访问public 为所有类都可以访问。
前面文章中对于 private、default、public 都已经有所了解所以本节主要讲解 protected。
// 范例 1: 定义 com.xiaoshan.demoa.A 类
package com.xiaoshan.demoa; public class A{protected String infoHello;//使用 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); //错误无法访问}
}此程序在进行编译时会直接提示用户info 是protected 权限所以无法被直接访问。
实际上在给出的4种权限中有3种权限 ( private、default、protected) 都是对封装的描述也就是说面向对象的封装性现在才算是真正讲解完整。从实际的开发使用来讲几乎不会使用到 default 权限所以真正会使用到的封装概念只有两个权限 private、protected。
对于访问权限初学者要把握以下两个基本使用原则即可。
属性声明主要使用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 visibleinst.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 只能支持对 int 或 char 类型进行判断正因为如果纯粹是数字或字符意义不明确所以增加了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类介绍~》