如果基础的可见性(第4.4.1节)选项不满足需求,可以使用访问控制。它适用于类级别和字段级别,知道两个方向:
> Access control can be used if the basic visibility (4.4.1) options are not sufficient. It is applicable at class-level and at field-level and knows two directions:
允许访问:目标是一个授予的访问指定类或者字段,使用 :allow(target) 元数据(第6.9节)。
禁止访问:目标是一个禁止访问的指定类或字段,使用 :access(target) 元数据(第6.9节)。
> **Allowing access**: The target is granted access to the given class or field by using the :allow(target) metadata (6.9).
> **Forcing access**: A target is forced to allow access to the given class or field by using the :access(target) metadata (6.9).
在这个上下文中,一个目标可以是一个点路径(第3.7节)到:
* 一个类字段
* 一个类或者抽象类型
* 一个包
> In this context, a target can be the dot-path (3.7) to
> * a class field,
> * a class or abstract type, or
> * a package.
目标不能遵从导入,所以必须是完整的合格路径。
> Target does not respect imports, so the fully qualified path has to be used.
如果它是一个类或者抽象类型,访问修正延伸到所有这个类型的字段。同样的,如果它是一个包,访问修正延伸到所有这个包的类型和递归到所有这些类型的字段。
> If it is a class or abstract type, access modification extends to all fields of that type. Likewise, if it is a package, access modification extends to all types of that package and recursively to all fields of these types.
~~~
@:allow(Main)
class MyClass {
static private var foo: Int;
}
class Main {
static public function main() {
MyClass.foo;
}
}
~~~
这里 ,MyClass.foo 可以从main方法中访问,因为 MyClass 被使用 @:allow(Main) 注释。这也可以使用 @:allow(Main.main),这两种方法都可以作为字段foo的注释替代对MyClass的注释:
> Here, MyClass.foo can be accessed from the main-method because MyClass is annotated with @:allow(Main). This would also work with @:allow(Main.main) and both versions could alternatively be annotated to the field foo instead of the class MyClass:
~~~
class MyClass {
@:allow(Main.main)
static private var foo: Int;
}
class Main {
static public function main() {
MyClass.foo;
}
}
~~~
如果一个类型不能被修改为允许这类的访问,访问方法可以禁止访问:
> If a type cannot be modified to allow this kind of access, the accessing method may force access:
~~~
class MyClass {
static private var foo: Int;
}
class Main {
@:access(MyClass.foo)
static public function main() {
MyClass.foo;
}
}
~~~
@:access(MyClass.foo) 注释在main方法中有效的颠覆了foo字段的可见性。
> The @:access(MyClass.foo) annotation effectively subverts the visibility of the foo field within the main-method.
**元数据的选择**
>[warning] 花絮:元数据的选择
访问控制语言特性使用 Haxe元数据语法,而不是额外的语言特定语法。有如下几个理由:
另外的语法通常使得语言解析更加复杂,也会添加太多关键字。
另外的语法需要另外的学习成本,元数据语法是已知的知识。
元数据语法足够灵活来扩展这个功能。
元数据可以被通过Haxe的宏 访问/生成/修改。
当然,使用元数据语法主要的缺点是,如果你拼错元数据的关键字(例如@:acesss)或者类/包的名将不会得到错误报告。然而,通过这个功能,当你尝试访问一个不被允许的私有字段,你会得到一个错误,毕竟不可能是一个不被察觉的错误。
>[warning] **Trivia**: On the choice of metadata
The access control language feature uses the Haxe metadata syntax instead of additional language-specific syntax. There are several reasons for that:
> * Additional syntax often adds complexity to the language parsing, and also adds (too) many keywords.
> * Additional syntax requires additional learning by the language user,whereas metadata syntax is something that is already known.
> * The metadata syntax is flexible enough to allow extension of this feature.
> * The metadata can be accessed/generated/modified by Haxe macros.
> Of course, the main drawback of using metadata syntax is that you get no error report in case you misspell either the metadata key (@:acesss for instance) or the class/package name. However, with this feature you will get an error when you try to access a private field that you are not allowed to, therefore there is no possibility for silent errors.
**Haxe 3.1.0 以后**
> **Since Haxe 3.1.0**
如果允许访问一个 接口(第2.3.3节),它延伸到所有实现这个接口的类:
> If access is allowed to an interface(2.3.3),it extends to all classes implementing that interface:
~~~
class MyClass {
@:allow(I)
static private var foo: Int;
}
interface I { }
class Main implements I {
static public function main() {
MyClass.foo;
}
}
~~~
对于访问授权父类,也是同样的,这种情况会延伸到所有的子类:
> This is also true for access granted to parent classes, in which case it extends to all child classes.
**破坏性功能**
>[warning] **花絮**:破坏性功能
子类和实现类的访问扩展只支持Haxe 3.0以后。当编写这本手册时发现这部分的访问控制实现是容易缺失的。
>[warning] **Trivia**: Broken feature
Access extension to child classes and implementing classes was supposed to work in Haxe 3.0 and even documented accordingly. While writing this manual it was found that this part of the access control implementation was simply missing.
- 空白目录
- 1.Haxe介绍
- 1.1.Haxe是什么
- 1.2.关于本文档
- 1.2.1.作者及贡献者
- 1.2.2.License
- 1.3Hello World
- 1.4.Haxe的历史
- 2.类型
- 2.1.基本类型
- 2.1.1.数值类型
- 2.1.2.溢出
- 2.1.3.数值运算符
- 2.1.4.Bool类型
- 2.1.5.Void类型
- 2.2.为空性
- 2.2.1.可选参数和为空性
- 2.3.类实例
- 2.3.1.类的构造函数
- 2.3.2.继承
- 2.3.3.接口
- 2.4.枚举实例
- 2.4.1.Enum构造函数
- 2.4.2.使用枚举
- 2.5.匿名结构
- 2.5.1.结构值的JSON形式
- 2.5.2. 结构类型的类记法
- 2.5.3.可选字段
- 2.5.4.性能影响
- 2.6.函数类型
- 2.6.1.可选参数
- 2.6.2.默认值
- 2.7.动态类型
- 2.7.1.Dynamic使用类型参数
- 2.7.2.实现Dynamic
- 2.8.抽象类型
- 2.8.1.隐式类型转换
- 2.8.2.运算符重载
- 2.8.3.数组访问
- 2.8.4.选择函数
- 2.8.5.枚举抽象类型
- 2.8.6.转发抽象类型字段
- 2.8.7.核心类型抽象
- 2.9.单形
- 3.类型系统
- 3.1.Typedef
- 3.1.1.扩展
- 3.2.类型参数
- 3.2.1.约束
- 3.3.泛型
- 3.3.1.泛型类型参数解释
- 3.4.变异
- 3.5.统一
- 3.5.1.类/接口 之间
- 3.5.2.结构子类型化
- 3.5.3.单形
- 3.5.4.函数返回
- 3.5.5.通用基本类型
- 3.6.类型推断
- 3.6.1.由上而下推断
- 3.6.2.局限
- 3.7.模块和路径
- 3.7.1.模块子类型
- 3.7.2.Import
- 3.7.3.解析顺序
- 4.类字段
- 4.1.变量
- 4.2.属性
- 4.2.1.常见访问标识符组合
- 4.2.2.对类型系统的影响
- 4.2.3.getter和setter的规则
- 4.3.方法
- 4.3.1.重写方法
- 4.3.2.变异和访问修饰符的影响
- 4.4.访问修饰符
- 4.4.1.可见性
- 4.4.2.Inline
- 4.4.3.Dynamic
- 4.4.4.Override
- 4.4.5.Static
- 5.表达式
- 5.1.块
- 5.2.常量
- 5.3.二元操作符
- 5.4.一元操作符
- 5.5.数组声明
- 5.6.对象声明
- 5.7.字段访问
- 5.8.数组访问
- 5.9.函数调用
- 5.10.var
- 5.11.局部函数
- 5.12.new
- 5.13.for
- 5.14.while
- 5.15.do-while
- 5.16.if
- 5.17.switch
- 5.18.try/catch
- 5.19.return
- 5.20.break
- 5.21.continue
- 5.22.throw
- 5.23.类型转换
- 5.23.1.不安全转换
- 5.23.2.安全转换
- 5.24.类型检查
- 6.语言特性
- 6.1.条件编译
- 6.2.Externs
- 6.3.静态扩展
- 6.3.1.标准库中的静态扩展
- 6.4.模式匹配
- 6.4.1.介绍
- 6.4.2.枚举匹配
- 6.4.3.变量捕获
- 6.4.4.结构匹配
- 6.4.5.数组匹配
- 6.4.6.Or 模式
- 6.4.7.守护
- 6.4.8.多个值的匹配
- 6.4.9.提取器
- 6.4.10.穷尽性检查
- 6.4.11.无效的模式检查
- 6.5.字符串插值
- 6.6.数组推导
- 6.7.迭代器
- 6.8.函数绑定
- 6.9.元数据
- 6.10.访问控制
- 6.11.内联构造函数
- 7.编译器用法
- 7.1.编译器标记
- 8.编译器功能
- 8.1.内建编译器元数据
- 8.2.无用代码消除
- 8.3.编译器服务
- 8.3.1.概述
- 8.3.2.字段访问完成
- 8.3.3.调用参数完成
- 8.3.4.类型路径完成
- 8.3.5.使用完成
- 8.3.6.位置完成
- 8.3.7.顶级完成
- 8.3.8.完成服务
- 8.4.资源
- 8.4.1.嵌入资源
- 8.4.2.检索文本资源
- 8.4.3.检索二进制资源
- 8.4.4.实现细节
- 8.5.运行时类型信息
- 8.5.1.RTTI 结构
- 8.6.静态分析仪
- 9.宏
- 9.1.宏上下文
- 9.2.参数
- 9.2.1.ExprOf
- 9.2.2.常数表达式
- 9.2.3.其它的参数
- 9.3.具体化
- 9.3.1.表达式具体化
- 9.3.2.类型具体化
- 9.3.3.类具体化
- 9.4.工具
- 9.5.类型构建
- 9.5.1.枚举构建
- 9.5.2.@:autoBuild
- 9.5.3.@:genericBuild
- 9.6.限制
- 9.6.1.Macro-in-Macro
- 9.6.2.静态扩展
- 9.6.3.构建顺序
- 9.6.4.类型参数
- 9.7.初始化宏
- 10.标准库
- 10.1.字符串
- 10.2.数据结构
- 10.2.1.数组
- 10.2.2.向量
- 10.2.3.列表
- 10.2.4.GenericStack
- 10.2.5.Map
- 10.2.6.Option
- 10.3.正则表达式
- 10.3.1.匹配
- 10.3.2.分组
- 10.3.3.替换
- 10.3.4.分割
- 10.3.5.Map
- 10.3.6.实现细节
- 10.4.Math
- 10.4.1.特殊数值
- 10.4.2.数学错误
- 10.4.3.整数数学
- 10.4.4.扩展
- 10.5.Lambda
- 10.6.模板
- 10.7.反射
- 10.8.序列化
- 10.8.1.格式化序列化
- 10.9.Xml
- 10.9.1.开始使用Xml
- 10.9.2.解析Xml
- 10.9.3.编码Xml
- 10.10.Json
- 10.10.1.解析JSON
- 10.10.2.编码JSON
- 10.10.3.实现细节
- 10.11.Input/Output
- 10.12.Sys/sys
- 10.13.远程处理
- 10.13.1.远程连接
- 10.13.2.实现细节
- 10.14.单元测试
- 11.Haxelib
- 11.1.Haxe编译器使用库
- 11.2.haxelib.json
- 11.2.1.版本控制
- 11.2.2.依赖关系
- 11.3.extraParams.hxml
- 11.4.使用Haxelib
- 12.目标平台细节
- 12.1.JavaScript
- 12.1.1.开始使用Haxe/JavaScript
- 12.1.2.使用外部JavaScript库
- 12.1.3.注入原生JavaScript
- 12.1.4.JavaScript untyped函数
- 12.1.5.调试JavaScript
- 12.1.6.JavaScript目标元数据
- 12.1.7.为JavaScript暴露Haxe类
- 12.1.8.使用 require函数加载外部类
- 12.2.Flash
- 12.2.1.开始使用Haxe/Flash
- 12.2.2.嵌入资源
- 12.2.3.使用外部Flash库
- 12.2.4.Flash目标元数据
- 12.3.Neko
- 12.4.PHP
- 12.4.1.开始使用Haxe/PHP
- 12.4.2.PHP untyped函数
- 12.5.C++
- 12.5.1.Using C++定义
- 12.5.2.Using C++ 指针
- 12.6.Java
- 12.7.C#
- 12.8.Python