Package and Access Permission of Java Basic Tutorial Part 2
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: private
it can only be accessed in this class; default
it can only be accessed in the same package; protected
it can be accessed in subclasses of different packages; public
it can be accessed for all classes.
In the previous article , we have already learned about private
, default
, and , so this section mainly explains .public
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);
}
}
Since B
the class is A
a subclass of , the permission attribute B
in 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 protected
the permission attribute in the parent class.
And if you want to directly use the main class to access the attributes in com.xiaoshan.test
the package , because they are not in the same package, and there is no inheritance relationship, they will not be accessible.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); //错误:无法访问
}
}
This program will directly prompt the user when compiling, info
it is protected
a 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 default
concepts that are really used private
.protected
For access rights, beginners should grasp the following two basic usage principles.
- The attribute declares the main usage
private
rights; - Method declarations primarily use
public
permissions.
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 private
declare, but the constructor can also be private
declared, 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, Singleton
there 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 private
encapsulation.
// 范例 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 Singleton
cannot be instantiated externally .Singleton
So now, in the case of ensuring that Singleton
the 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: private
Operations 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 Singleton
of Singleton
the class instance
. Singleton
So it can be static
done using , static
defined 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 instance
should also be encapsulated, and to get the attribute after encapsulation, you need to write getter
a method, but at this time getter
the method should also be called directly by the class name, defined as static
type.
// 范例 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? instance
The attribute in the program belongs to static
the definition, which means that Singleton
no matter how many object declarations there are, all objects of the class will share the same instance
attribute 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 private
define 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 static
to define a public object, and static
return 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 instance
add a final
keyword 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 Singleton
the class, no matter how the code operates, there will always be only one Singleton
instantiated 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 Sex
class object after receiving the specified number.
The code in Example 11 obtains an Sex
object 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 Sex
class object, it can use the global constants defined in the interface (in fact, Sex
some 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, switch
it can only support the judgment of int
or type, just because if it is purely numbers or characters, the meaning is not clear, so the support of is added.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);
}
}
Program execution result:
男
This program directly uses String
as switch
the 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.