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关键字,否则本行代码无法执行

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏null的专栏

设计模式——类图以及类与类之间的关系

    设计模式在程序设计上有着很重要的作用,使用设计模式可以使得代码更容易被理解,使得代码更规范,真正实现工程化。 一、用UML表示一个类 ? 类图一般是三行...

3704
来自专栏程序员宝库

一些我认为有用有趣的 JDK 方法

在学习JDK的源码过程中我遇到了一些有趣有用的方法,在此之前如果要使用这些工具方法,我首先会想到的是 commons-lang和 guava这样的语言扩展包,但...

2897
来自专栏信数据得永生

JavaScript 编程精解 中文第三版 五、高阶函数

30510
来自专栏天天

Airbnb JavaScript Style Guide

const foo = 1; let bar = foo; bar = 9; console.log(foo, bar); // => 1, 9

1902
来自专栏前端新视界

立即执行函数表达式(IIFE)

原文:immediately-invoked-function-expression 译者:nzbin 也许你还没有注意到,我是一个对术语比较坚持的人。因此...

2165
来自专栏Java开发者杂谈

java如何获取一个对象的大小

When---什么时候需要知道对象的内存大小 在内存足够用的情况下我们是不需要考虑java中一个对象所占内存大小的。但当一个系统的内存有限,或者某块程序代码允许...

1.4K7
来自专栏iOS技术杂谈

iOS runtime探究(一): 从runtime开始理解面向对象的类到面向过程的结构体你要知道的runtime都在这里

你要知道的runtime都在这里 转载请注明出处 https://cloud.tencent.com/developer/user/1605429 本文主要讲解...

41112
来自专栏老司机的简书

老司机出品——源码解析之从Block说开去

近来把《iOS与OS X多线程和内存管理》这本书又掏出来看了一遍,这本书前前后后加起来看了能有三四遍了,每次看都有新的理解。现在就把个人对Block的一些理解记...

1093
来自专栏java达人

js的回调函数详解

在Javascript中,函数是第一类对象,这意味着函数可以像对象一样按照第一类管理被使用。既然函数实际上是对象:它们能被“存储”在变量中,能作为函数参数被传递...

3645
来自专栏拂晓风起

java 字符串编码转换 字符集/编码的见解 心得 体会(跟之前那个C++编码随笔对应)

1913

扫码关注云+社区

领取腾讯云代金券