Flash/Flex学习笔记(8):ActionScript3.0中的面对对象
首先要习惯AS3.0的几个BT约定:
1.一个.as文件中,只能定义一个类 2.类名称必须与.as的文件名相同 3.类定义中必须要有package包声明 4.一个类最多只能有一个构造函数
5.包package的路径/名称约定:
这个初次接触时感觉有点小复杂,这样描述吧:
如果您在定义一个类时,package的声明指定了名称,比如 package jimmy{ public class MyClass{...}},那么也就意味着需要对它引用的fla/as文件同级目录下,必须要有jimmy目录,而且jimmy目录下必须要有MyClass.as文件,而且MyClass文件中定义的类名必须为MyClass
然后你再引用该类时,必须导入该包
import jimmy.MyClass;
然后才能引用比如: var mycls:MyClass = new MyClass();
简单来讲,就是package名必须与目录名准确匹配。
这里还有一种特殊情况:
假如定义的package名称为jimmy.yang,根据上面的解释,则同级目录下必须要有jimmy.yang目录,这是没问题的,但是还可以这样组织目录结构,先创建一个jimmy目录,然后再创建一个yang目录,然后把as文件放到jimmy/yang/目录下,即:如果package名称中有"点"时(比如package a.b),则目录./a.b/ 与./a/b/效果相同,推荐用后者,这样层次更分明
好了,开始定义第一个类:
package {
public class Human {
public function Human(){
this._name = "暂无名字";
trace("Human构造函数被调用!");
}
private var _name:String;
public function get Name():String{
return _name;
}
////仅本类及子类定义中可用(实际上这个编译能过,但无法在子类中使用)
// protected function set Name(n:String):void{
// this._name = n;
// }
public function SetName(n:String):void{
this._name = n;
}
//属性 set get示例
private var _sex:Boolean
public function set Sex(v:Boolean):void{
_sex = v;
}
public function get Sex():Boolean{
return _sex;
}
public function Hello():void{
trace(_name + " say:Hello World!");
HiChildren();//测试在本类中调用受保护方法
}
//受保护方法
protected function HiChildren():void{
trace(_name + ":HiChildren");
}
//静态方法
public static function WhoAmI():String{
return "This is a Human Class"
}
}
}
上面演示了构造器,属性(set/get),静态方法,受保护方法,注意:AS3中不支抽象类
package {
public class Man extends Human {
public function Man(n:String):void {
super();
SetName(n);
super.Sex=true;
trace("Man构造函数被调用!");
HiChildren();//调用父类的受保护方法
}
//覆盖父类的性别设置函数
public override function set Sex(v:Boolean):void {
//Sex = true;//既然已经是男的,肯定是男的,这里就用不着了,除非咱们的系统支持"变性"
trace("无法修改Man的性别");
}
//protected override function set Name(n:String):void{
// //Name = n;//报错:对Name的引用有歧义
// }
public function ChaseGirls():void{
trace(Name + "正在泡妞...");
}
}
}
上面演示了类继承、覆写,下面调用这二个类测试一番:
var h:Human = new Human();
trace(h.Name);
h.Sex = true;
trace(h.Sex);
trace(Human.WhoAmI())
h.Hello();
//h.Name = "菩提树下的杨过";//这里会报错:属性只读,因为Name的set方法受保护
//h.HiChildren(); //同理无法调用
var _man:Man = new Man("菩提树下的杨过");
_man.Sex = false;
trace("_man的性别:" + _man.Sex);
//trace(Man.WhoAmI());//静态方法将不被继承
_man.Hello();
//_man.HiChildren();//受保护方法无法在子类实例中使用
_man.ChaseGirls();
输出结果: Human构造函数被调用! 暂无名字 true This is a Human Class 暂无名字 say:Hello World! 暂无名字:HiChildren Human构造函数被调用! Man构造函数被调用! 菩提树下的杨过:HiChildren 无法修改Man的性别 _man的性别:true 菩提树下的杨过 say:Hello World! 菩提树下的杨过:HiChildren 菩提树下的杨过正在泡妞...
另外:做为符合ECMA规范的语言,ActionScript同样具有类似JavaScript的动态语言能力,我们把Human.cs再改一下:
package {
public dynamic class Human {
public function Human() {
trace("Human构造函数被调用!");
}
public function toString():String {
return "This is a Human instance!";
}
}
}
注意dynamic关键字,加上这个后,Human就具备了动态修改属性的能力,看下面的测试代码:
var h:Human = new Human();
h.age = 10;
h.name = "菩提树下的杨过";
h.Say = function(){
trace(h.name + ":Hello!" );
}
trace(h.toString());
trace(h.age);
trace(h.name);
h.Say();
var h2:Human = new Human();
trace(h2.age);//输出undefiend
输出结果:
Human构造函数被调用! This is a Human instance! 10 菩提树下的杨过 菩提树下的杨过:Hello! Human构造函数被调用! undefined
如果一个类不想被继承,可以用final关键字标识,通常可以把一些辅助方法以static方式定义在final标识的类中,构成自己的工具类库(有点象c#中的静态类)
package {
public final class MyUtils {
public static function Test(s:String):String {
trace(s);
return s;
}
public static function Now():String {
trace(new Date());
return new Date().toLocaleString();
}
}
}
调用:
MyUtils.Test("hello test");
MyUtils.Now();
用final + static组合还能实现类似枚举的效果:
package {
public final class LOGIN_REG_ERROR {
public static const USERNAME_EXISTS = "用户名已存在";
public static const PASSWORD_ERROR = "密码错误";
public static const USENAME_ERROR = "用户名错误";
//...
}
}
使用示例:
var _loginResult:String;
if (_loginResult==LOGIN_REG_ERROR.USERNAME_EXISTS) {
trace("用户名已存在!");
}
AS3.0还支持接口,看下面的代码
package {
public interface IFly {
function Fly():void;
}
}
package {
public class Duck implements IFly {
public function Duck() {
trace("来来,我是一只鸭子...");
}
public function Fly():void{
trace("请叫我小飞侠,谢谢!")
}
}
}
最后看下原型链prototype:在javascript中正是得益于prototype才实现了很多惊人的应用,同样在as3.0中也存在原型链,所有动态属性的继承都可以通过原型继承实现,不过要注意的是:如果你准备对一个类进行prototype扩展以实现原型继承,则该类必须标识为dynamic,下面是示例代码:
var d:Duck = new Duck();
d.Fly();
Duck.prototype.Swim = function(){
trace("正在游泳...请回避(裸泳?)");
}
d.Swim(); //请先将上一段代码中的Duck类定义加上dynamic关键字,否则本行代码无法执行
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Nginx 跨域 add_header 403状态下无效
- Cannot set property 'branchdata' of undefined
- 【每日一题】27. Remove Element
- 【CPP】《程序员面试金典》习题(1)——数组与字符串
- 【CPP】《程序员面试金典》习题(2)——链表
- 【CPP】《程序员面试金典》习题(3)——栈和队列
- PPYOLO:2020不容错过的目标检测调参Tricks
- 【笔记】《C++Primer》—— 第11章:关联容器
- 【笔记】《C++Primer》—— 第12章:动态内存
- 【笔记】《C++Primer》—— 第13章:拷贝控制
- 【笔记】《C++Primer》—— 第16章:模板与泛型编程
- 【笔记】《C++Primer》—— 第19章:特殊工具与技术
- 【翻译】C++14的新特性简介
- Python 为什么要有 pass 语句?
- 【翻译】C++17的新特性简介