面向对象类型系统

面向对象类型系统
•合理使用面向对象编程
–提高复用性,提高可维护性,etc.
–并非提高软件质量的保证
•可以使用各种成熟的设计方式
–模式,etc
•不拘泥于使用OO方式扩展对象
–结合JavaScript的动态特性
–下一次课程


命名空间
•合理的组织大量的类型
–使开发人员能够方便地找到他们所需要的类型
–并非仅仅为了避免命名冲突
•可重复注册
–每个独立的脚本模块前都要注册命名空间以保证命名空间存在
Type.registerNamespace(“MyNamespace”);



•定义步骤:
–定义构造函数
–定义成员(方法、属性、事件)
–注册类


类–构造函数
•类的构造函数即为function定义
•通常用于初始化域变量
•私有成员使用下划线开头(无法真正封装)
–this._myPrivateField;
–this._myPrivateMethod();


类–构造函数
Type.registerNamespace("MyNamespace");
MyNamespace.MyClass= function(param1, ...){
this._myField= null;
...
}


类–定义方法
•基于prototype定义
MyNamespace.MyClass.prototype = {
myMethod1 : function() { ... },
myMethod2 : function(){
this.myMethod1(); // this保留字不可少
}
}


类–定义属性
•Microsoft AJAX Library的面向对象类型系统将add_和set_开头的方法认作属性
•避免定义只写属性,使用某个方法替代


类–定义属性
MyNamespace.MyClass = function(param1, ...) {
this._myProperty = null;
}
MyNamespace.MyClass.prototype = {
get_myProperty : function(){
return this._myProperty;
},
set_myProperty : function(value){
this._myProperty = value;
}
}


类–注册类
MyNamespace.MyClass = function(param1, ...) {
// …
}
MyNamespace.MyClass.prototype = {
// …
}
MyNamespace.MyClass.registerClass(
'MyNamespace.MyClass');


定义及使用类
     < form id = " form1 "  runat = " server " >
        
< asp:ScriptManager ID = " ScriptManager1 "  runat = " server "  ScriptMode = " Debug " >
            
< Scripts >
                
< asp:ScriptReference Path = " Employee.js "   />
            
</ Scripts >
        
</ asp:ScriptManager >

        
< div id = " info " ></ div >
        
< script language = " javascript "  type = " text/javascript " >
            function display(text)
            {
                document.getElementById(
" info " ).innerHTML  +=  (text  +   " <br /> " );
            }
            
            var jeffz 
=   new  MyNamespace.Intern( " Jeffrey Zhao " );
            jeffz.set_year(
3 );
            display(jeffz.getDescription());
            
            var tom 
=   new  MyNamespace.Vendor( " Tom " );
            tom.set_year(
3 );
            display(tom.getDescription());
            
            var jerry 
=   new  MyNamespace.FulltimeEmployee( " Jerry " );
            jerry.set_year(
5 );
            display(jerry.getDescription());
            
            display(
" jeffz implements 'IEmployee' interface:  "   +  
                MyNamespace.IEmployee.isImplementedBy(jeffz));
                
            var type 
=  MyNamespace.EmployeeType.toString(tom.get_type());
            display(String.format(
" {0} is a {1}. " , tom.get_name(), type));
            
            var all 
=  MyNamespace.MyFlags.All;
            display(MyNamespace.MyFlags.toString(all));
            
            display(MyNamespace.MyFlags.parse(
" Item1, Item3 " ));
        
</ script >
    
</ form >

Employee.js
Type.registerNamespace( " MyNamespace " );

MyNamespace.EmployeeType 
=  function()
{
    
throw  Error.notImploemented();
}
MyNamespace.EmployeeType.prototype 
=  
{
    Intern : 
0 ,
    Vendor : 
1 ,
    FulltimeEmployee : 
2
}
MyNamespace.EmployeeType.registerEnum(
" MyNamespace.EmployeeType " );

MyNamespace.IEmployee 
=  function()
{
    
throw  Error.notImplemented();
}
MyNamespace.IEmployee.prototype 
=  
{
    calcaulateSalary : function()
    {
        
throw  Error.notImplemented();
    },
    
    get_type : function()
    {
        
throw  Error.notImplemented();
    }
}
MyNamespace.IEmployee.registerInterface(
" MyNamespace.IEmployee " );

MyNamespace.Employee 
=  function(name)
{
    
this ._name  =  name  ?  name :  " [Anonymous] " ;
    
this ._year  =   0 ;
}
MyNamespace.Employee.prototype 
=  
{
    get_name : function()
    {
        
return   this ._name;
    },
    
    get_year : function()
    {
        
return   this ._year;
    },
    set_year : function(value)
    {
        
this ._year  =  value;
    },
    
    calculateSalary : function()
    {
        
throw  Error.notImplemented();
    },
    
    getDescription : function()
    {
        
return  String.format(
            
" {0} gets {1} yuan per month. " ,
            
this ._name,
            
this .calculateSalary());
    }
}
MyNamespace.Employee.registerClass(
" MyNamespace.Employee " null ,
    MyNamespace.IEmployee);

MyNamespace.Intern 
=  function(name)
{
    MyNamespace.Intern.initializeBase(
this , [name]);
}
MyNamespace.Intern.prototype 
=  
{
    calculateSalary : function()
    {
        
return   2000 ;
    },
    
    getDescription : function()
    {
        var description 
=  MyNamespace.Intern.callBaseMethod( this " getDescription " );
        
return  description  +   "  What a poor intern! " ;
    },
    
    get_type : function()
    {
        
return  MyNamespace.EmployeeType.Intern;
    }
}
MyNamespace.Intern.registerClass(
" MyNamespace.Intern " , MyNamespace.Employee);

MyNamespace.Vendor 
=  function(name)
{
    MyNamespace.Vendor.initializeBase(
this , [name]);
}
MyNamespace.Vendor.prototype 
=  
{
    calculateSalary : function()
    {
        
return   5000   +   1000   *  ( this .get_year()  -   1 );
    },
    
    get_type : function()
    {
        
return  MyNamespace.EmployeeType.Vendor;
    }
}
MyNamespace.Vendor.registerClass(
" MyNamespace.Vendor " , MyNamespace.Employee);

MyNamespace.FulltimeEmployee 
=  function(name)
{
    MyNamespace.FulltimeEmployee.initializeBase(
this , [name]);
}
MyNamespace.FulltimeEmployee.prototype 
=  
{
    calculateSalary : function()
    {
        
return   15000   +   2000   *  ( this .get_year()  -   1 );
    },
    
    get_type : function()
    {
        
return  MyNamespace.EmployeeType.FulltimeEmployee;
    }
}
MyNamespace.FulltimeEmployee.registerClass(
" MyNamespace.FulltimeEmployee " , MyNamespace.Employee);


///////////////////////////////////////
MyNamespace.MyFlags  =  function()
{
    
throw  Error.notImplemented();
}
MyNamespace.MyFlags.prototype 
=  
{
    Item1 : 
1 ,
    Item2 : 
2 ,
    Item3 : 
4 ,
    None : 
0 ,
    All : 
7
}
MyNamespace.MyFlags.registerEnum(
" MyNamespace.MyFlags " true );

//  Item1 + Item3
//  Item1 | Item3 (preferred)

你可能感兴趣的:(面向对象)