<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<script type=text/javascript charset=utf-8>
//javascript没有定义接口的概念,我们通过模拟高级程序语言的方式来创建javascript中的接口。实现要重写接口所有的方法。
/* javascript定义接口有三种方式
1 注释描述接口
2 属性检测接口
3 鸭式辩型接口
*/ // 1 注解描述的方式(注释方式,假的)
/**
interface Composite {
function add(obj);
function remove(obj);
function uopdate(obj);
} var CompositeImpl = function(){
this.add = function(){},
this.remove = function(){},
this.upload = function(){}
};
var c1 = new CompositeImpl();
var c2 = new CompositeImpl();
alert(c1.add == c2.add); //false,每次都有一个add,所以写到原型里面
*/ // CompositeImpl implements Composite
var CompositeImpl = function(){
}; CompositeImpl.prototype.add = function(obj){
}
CompositeImpl.prototype.remove = function(obj){
}
CompositeImpl.prototype.update = function(obj){
} var c1 = new CompositeImpl();
var c2 = new CompositeImpl();
alert(c1.add == c2.add);
</script>
</head>
<body>
</body>
</html>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<script type=text/javascript charset=utf-8>
// 第二种实现接口的方式 属性检测的方式(继承接口,就要实现所有方法。)
/**
* interface Composite {
* function add(obj);
* function remove(obj);
* function uopdate(obj);
* }
*
* interface FormItem {
* function select(obj);
* }
*
*/ // CompositeImpl implements Composite , FormItem
var CompositeImpl = function(){
// 显示的再类的内部 接受所实现的接口
// 一般来说是一个规范 我们项目经理:在类的内部定义一个数组(名字要固定)
this.implementsInterfaces = ['Composite' ,'FormItem' ];//this是这个类的当前对象
} CompositeImpl.prototype.add = function(obj){
alert('add...');
}
CompositeImpl.prototype.remove = function(obj){
}
CompositeImpl.prototype.update = function(obj){
}
CompositeImpl.prototype.select = function(obj){
} // 检测CompositeImpl类的对象的
function CheckCompositeImpl(instance){
//判断当前对象是否实现了所有的接口
if(!IsImplements(instance,'Composite','FormItem')){
throw new Error('Object does not implement a required interface!');
}
} function IsImplements(object){//实参多个,形参一个,这个形参就是实参的第一个,
// arguments 对象 获得函数的实际参数
for(var i = 1 ; i < arguments.length;i++){
//接受所实现的每一个接口的名字
var interfaceName = arguments[i];//arguments[i]在不在object.implementsInterfaces里面
var interfaceFound = false ;
for(var j = 0 ; j <object.implementsInterfaces.length;j++){
if(object.implementsInterfaces[j] == interfaceName) {
interfaceFound = true ;
break;//跳出for循环
}
}
if(!interfaceFound){
return false ;
}
}
return true ;
} var c1 = new CompositeImpl();
CheckCompositeImpl(c1);
c1.add();
</script>
</head>
<body>
</body>
</html>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<script type=text/javascript charset=utf-8>
// 实现接口的第三种方式:鸭式辨型法实现接口(最完美的javascript实现接口方式)
// 鸭式辨型法实现的核心:一个类实现接口的主要目的:把接口里的方法都实现(检测方法)
// 完全面向对象 代码也实现统一 也解耦了 // 一: 接口类 Class Interface ==>实例化N多个接口 /**
* 接口类需要2个参数
* 参数1: 接口的名字 (string)
* 参数2: 接受方法名称的集合(数组) (array)
*/
var Interface = function(name,methods){
//判断接口的参数个数
if(arguments.length != 2){
throw new Error('this instance interface constructor arguments must be 2 length!');
}
this.name = name ;
this.methods = [] ; //定义一个内置的空数组对象 等待接受methods里的元素(方法名字)
for(var i = 0,len = methods.length ; i <len ; i++){
if( typeof methods[i] !== 'string'){
throw new Error('the Interface method name is error!');
}
this.methods.push(methods[i]);
}
} // 1 实例化接口对象
var CompositeInterface = new Interface('CompositeInterface' , ['add' , 'remove']);//CompositeInterface对象有属性name为CompositeInterface,数组['add' , 'remove']
var FormItemInterface = new Interface('FormItemInterface' , ['update','select']);
// CompositeImpl implements CompositeInterface , FormItemInterface
var CompositeImpl = function(){
}
// 3 实现接口的方法implements methods
CompositeImpl.prototype.add = function(obj){
alert('add');
}
CompositeImpl.prototype.remove = function(obj){
alert('remove');
}
CompositeImpl.prototype.update = function(obj){
alert('update');
}
/*
CompositeImpl.prototype.select = function(obj){
alert('select');
}
*/ // 三:检验接口里的方法
Interface.ensureImplements = function(object){
// 如果检测方法接受的参数小于2个 参数传递失败!
if(arguments.length < 2 ){
throw new Error('Interface.ensureImplements method constructor arguments must be >= 2!');
} for(var i = 1 , len = arguments.length; i<len; i++ ){
var instanceInterface = arguments[i];
// 判断对象是不是一个类的实例,判断对象的构造器是不是类名字
if(instanceInterface.constructor !== Interface){
throw new Error('the arguments constructor not be Interface Class');
}
// 循环接口实例对象里面的每一个方法
for(var j = 0 ; j < instanceInterface.methods.length; j++){
// 用一个临时变量 接受每一个方法的名字(注意是字符串)
var methodName = instanceInterface.methods[j];
if( !object[methodName] || typeof object[methodName] !== 'function' ){
throw new Error("the method name '" + methodName + "' is not found !");
}
}
}
} var c1 = new CompositeImpl();
Interface.ensureImplements(c1,CompositeInterface,FormItemInterface);
c1.add();
</script>
</head>
<body>
</body>
</html>
var CompositeImpl = function(){}
CompositeImpl.prototype.add = function(obj){
alert('add');
} var c1 = new CompositeImpl();
alert(c1['add']);//function(obj){alert('add');}
alert(c1['ssadd']);//undefined
alert(c1['sss']);//undefined,
alert(c1.ssadd());//ssadd is not a function
alert(c1.sss);//undefined, 没有属性,方法,通过中括号返回未定义,就是假
c1['add'];//什么都没有
alert(typeof c1['add']);//function if( !c1[methodName] || typeof c1[methodName] !== 'function' ){
throw new Error("the method name '" + methodName + "' is not found !");
}// c1[methodName]有可能是一个属性,不是方法。 !== // 判断对象是不是一个类的实例,判断对象的构造器是不是类名字
instanceInterface.constructor !== Interface

js20---接口3种方式的更多相关文章

  1. C# 调用HTTP接口两种方式

    using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net ...

  2. HBase读写的几种方式(三)flink篇

    1. HBase连接的方式概况 主要分为: 纯Java API读写HBase的方式: Spark读写HBase的方式: Flink读写HBase的方式: HBase通过Phoenix读写的方式: 第一 ...

  3. C#动态调用WCF接口,两种方式任你选。

    写在前面 接触WCF还是它在最初诞生之处,一个分布式应用的巨作. 从开始接触到现在断断续续,真正使用的项目少之又少,更谈不上深入WCF内部实现机制和原理去研究,最近自己做一个项目时用到了WCF. 从这 ...

  4. Java创建线程的第二种方式:实现runable接口

    /*需求:简单的卖票程序多个窗口买票 创建线程的第二种方式:实现runable接口 *//*步骤1.定义类实现Runable接口2.覆盖Runable接口中的run方法    将线程要运行的代码存放在 ...

  5. 创建线程的两种方式:继承Thread类和实现Runnable接口

    第一种方式:继承Thread类 步骤:1.定义类继承Thread 2.覆写Threa类的run方法. 自定义代码放在run方法中,让线程运行 3.调用线程的star方法, 该线程有两个作用:启动线程, ...

  6. java 的对象拷贝(有深浅拷贝两种方式,深拷贝实现的两种方式(逐层实现cloneable接口,序列化的方式来实现))

    Java提高篇--对象克隆(复制)(转自:http://www.cnblogs.com/Qian123/p/5710533.html#_label0)   阅读目录 为什么要克隆? 如何实现克隆 浅克 ...

  7. java中创建多线程两种方式以及实现接口的优点

    多线程创建方式有两种 创建线程的第一种方式.继承Thread类 1.继承Thread类 2.重写Thread类中的run方法--目的将自定义代码存储在run方法.让线程执行3.调用线程的start() ...

  8. 8.13.2 TreeSet实现Comparable接口的两种方式

    推荐使用第二种方式,编写比较器可以使数据类的程序耦合度降低,同时比较器也可以重复利用! 第一种方式:数据类实现Comparable接口,实现其中的compareTo方法 创建对象时,使用TreeSet ...

  9. 从后端接口下载文件的2种方式:get方式、post方式

    从后端接口下载文件的2种方式 一.get方式 直接使用: location.href='http://www.xxx.com/getFile?params1=xxx&params2=xxxx' ...

  10. 51、多线程创建的三种方式之实现Callable接口

    实现Callable接口创建线程 Callable接口是在jdk5版本中加入的,这个接口在java.util.concurrent包下面,与其他两种方式不同的地方在于使用Callable接口创建的线程 ...

随机推荐

  1. Java基础学习总结(13)——流IO

    一.JAVA流式输入/输出原理 流是用来读写数据的,java有一个类叫File,它封装的是文件的文件名,只是内存里面的一个对象,真正的文件是在硬盘上的一块空间,在这个文件里面存放着各种各样的数据,我们 ...

  2. python list的+,+=,append,extend

    面试题之中的一个. def func1(p): p = p + [1] def func2(p): p += [1] p1 = [1,2,3] p2 = [1,2,3] func1(p1) func2 ...

  3. OpenCASCADE Incremental Mesh

    OpenCASCADE Incremental Mesh eryar@163.com Abstract. OpenCASCADE IncrementalMesh is used to build th ...

  4. iOS开发系列之四 - UITextView 使用方法小结

    // 初始化输入框并设置位置和大小 UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(10, 10, 300, 1 ...

  5. android ViewPager实现 跑马灯切换图片+多种切换动画

    近期在弄个项目.要求有跑马灯效果的图片展示. 网上搜了一堆,都没有完美实现的算了还是自己写吧! 实现原理利用 ViewPager 控件,这个控件本身就支持滑动翻页非常好非常强大好多功能都能用上它.利用 ...

  6. Firefox访问https的网站,一直提示不安全

    http://mozilla.com.cn/thread-374897-1-1.html 要激活此功能步骤如下: 在地址栏键入"about:config" 点击“我了解此风险” 在 ...

  7. Entity Framework之Model First开发方式

    一.Model First开发方式 在项目一开始,就没用数据库时,可以借助EF设计模型,然后根据模型同步完成数据库中表的创建,这就是Model First开发方式.总结一点就是,现有模型再有表. 二. ...

  8. Linux下通过.desktop 文件创建桌面程序图标及文件编写方式(Desktop Entry文件概述)

    Linux下通过.desktop 文件创建桌面程序图标及文件编写方式 1.Desktop Entry文件概述:在 Windows 平台上,用户可以通过点击位于桌面或菜单上的快捷方式轻松打开目标应用程序 ...

  9. 【Codeforces Round #460 (Div. 2) C】 Seat Arrangements

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 用pre[i][j]表示第i行前j列的和. 然后枚举连续座位的最左上点. (有两种可能向右或向下k个. 则还需要处理出pre2[i] ...

  10. 这是一套Java菜鸟到大牛的学习路线之高级教程,由工作了10年的资深Java架构师整理。

    这是一套Java菜鸟到大牛的学习路线之高级教程,由工作了10年的资深Java架构师整理.        01-java高级架构师设计-基础深入        J2SE深入讲解        Java多 ...