1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>javascript高级语法5-接口</title> 6 </head> 7 <body> 8 <script> 9 /* 10 * 接口: 11 * 1.注解的方法 12 * 最简单,功能最弱,利用interface和implement“文字” 13 * 把他们用注解的方式显式表现出来。 14 * 2.属性检验法 15 * 3.鸭式变形法 16 17 * */ 18 19 //1.注解方法 20 function demo1(){ 21 (function b(){ 22 /* 23 * 用注释来定义一个接口 24 * interface PersonDao(){ 25 * function add(obj); 26 * function remove(obj); 27 * function find(id); 28 * } 29 */ 30 //用注释的方式实现它 31 /* 32 * PersonDaoImpl implement interface 33 * */ 34 var PersonDaoImpl = function(){}; 35 PersonDaoImpl.prototype.add = function(obj){ 36 // 37 } 38 PersonDaoImpl.prototype.remove = function(obj){ 39 // 40 } 41 PersonDaoImpl.prototype.find = function(id){ 42 // 43 } 44 /* 45 * 千万不要感觉它是没有任何意义的 46 * 1.大型项目靠的就是标准和规范 47 * 2.这样的写法会让你的程序员在没有写实现之前有充分时间做代码的设计和架构 48 * 3.缺点:要人为的遵守 49 50 * */ 51 })(); 52 } 53 //2.属性检验法 54 function demo2(){ 55 (function(){ 56 /* 57 * 用注释来定义一个接口 58 * interface PersonDao(){ 59 * function add(obj); 60 * function remove(obj); 61 * function find(id); 62 * } 63 */ 64 /* 65 * PersonDaoImpl implement interface 66 * */ 67 var PersonDaoImpl = function(){ 68 this.implementInterface=["PersonDao"]; 69 }; 70 PersonDaoImpl.prototype.add = function(obj){ 71 // 72 alert(obj); 73 } 74 PersonDaoImpl.prototype.remove = function(obj){ 75 // 76 } 77 PersonDaoImpl.prototype.find = function(id){ 78 // 79 } 80 81 function addObj(obj){ 82 var PersonDao = new PersonDaoImpl(); 83 //开始检查 84 if(!impl(PersonDao,"PersonDao")){ 85 throw new Error("类PersonDaoImpl没有实现接口PersonDao") 86 }else{ 87 PersonDao.add(obj); 88 } 89 } 90 addObj("张三") 91 //他接收一个不定参数:属性检验函数 92 function impl(obj){ 93 //遍历传入对象的属性 94 for(var i=1;i<arguments.length;i++){ 95 var interfaceName = arguments[i]; 96 var interfaceFound = false; 97 for(var j=0;j<obj.implementInterface.length;j++){ 98 if(obj.implementInterface[j] == interfaceName){ 99 interfaceFound=true; 100 break; 101 } 102 } 103 if(!interfaceFound){ 104 return false; 105 } 106 } 107 return true; 108 } 109 })() 110 } 111 112 //3. 鸭式变形法: 113 /*来源于一个国外老头,他有句名言: 114 * "像鸭子一样走路,并且会嘎嘎叫的东西" 115 * 换言之: 116 * 如果对象具有与接口定义的方法名字的所有方法(同名的所有方法),那么就认为实现了接口。 117 */ 118 119 function demo3(){ 120 (function(){ 121 //定义一个接口类 122 var Interface = function(name ,methods){ 123 if(arguments.length!=2){ 124 alert("interface must have two params") 125 } 126 this.name = name; //接口名字 127 this.methods = [];//定义一个空数组来装载函数名 128 for(var i=0;i<methods.length;i++){ 129 if(typeof methods[i] != "string"){ 130 alert("method name must be string") 131 }else{ 132 this.methods.push(methods[i]); 133 } 134 } 135 } 136 // 定义接口的一个静态方法来实现接口与实现类的直接检验 137 //静态方法不要写成Interface.prototype.* 因为这是写到接口的原型链上的 138 //我们要把静态的函数直接写到类层次上。 139 Interface.ensureImplements = function(obj){ 140 if(arguments.length<2){ 141 alert("至少两个参数"); 142 return false; 143 } 144 //遍历 145 for(var i=1;i<arguments.length;i++){ 146 var inter = arguments[i]; 147 //如果你是接口,就必须是interface类型的, 148 if(inter.constructor != Interface){ 149 throw new Error("必须是接口类型") 150 } 151 //遍历函数集合并分析 152 for(var j=0;j<inter.methods.length;j++){ 153 var method = inter.methods[j]; 154 //实现类中必须有方法名 和 接口中所有的方法名相同 155 if(!obj[method] || typeof obj[method]!="function"){ 156 throw new Error("类中实现类并没有完全实现接口中的所有方法") 157 } 158 } 159 } 160 }; 161 162 //应用 163 //定义自己的接口 164 var GridManager = new Interface("GridManager",["add","remove","list"]); 165 var FormManager = new Interface("FormManager",["save"]); 166 167 function commonManager(){ 168 //先实现方法 169 this.add = function(){ 170 alert("ok"); 171 } 172 this.list = function(){} 173 this.remove = function(){} 174 this.save = function(){} 175 //检验 176 Interface.ensureImplements(this,GridManager,FormManager) 177 } 178 179 var c = new commonManager(); 180 c.add(); 181 })() 182 } 183 /* 接口的重要性: 184 * 1.大型项目提高代码的灵活度 185 * 2.松耦合 186 * 3.在团队开发的时候,有时候在你真正编码之前就可以写API(自己的类库)。 187 * 这些类库就可以事后进行实现。 188 * 开始的时候我们就可以对整个项目是否可行,通过接口就可以模拟出来。 189 */ 190 191 </script> 192 </body> 193 </html>