java script 继承的实现

 ECMAScript 中实现继承的方式不止一种。这是因为 JavaScript 中的继承机制并不是明确规定的,而是通过模仿实现的。这意味着所有的继承细节并非由解释程序处理。 



对象冒充--- 构造函数使用 this 关键字给所有属性和方法赋值(即采用类声明的构造函数方式)。因为构造函数只是一个函数,所以可使 ClassA 的构造函数成为 ClassB 的方法,然后调用它。 ClassB 就会收到 ClassA 的构造函数中定义的属性和方法。 

Java代码  复制代码   收藏代码
  1. Js代码    
  2. function ClassA(sColor){      
  3.     this.color = sColor;      
  4.     this.sayColor = function (){      
  5.         alert(this.color);      
  6.     }      
  7. }     
  8.      
  9. function ClassB(sColor,sName){      
  10.     this.newMethod = ClassA;    //为ClassA赋予了方法newMethod      
  11.     this.newMethod(sColor);     //调用newMethod      
  12.     delete this.newMethod;      //删除对ClassA的引用      
  13.      
  14.     this.name = sName;      
  15.     this.sayName = function(){      
  16.         alert(this.name);      
  17.     }      
  18. }     
  19.    
[java]  view plain copy
  1. <span style="font-size:16px;">Js代码   
  2. function ClassA(sColor){     
  3.     this.color = sColor;     
  4.     this.sayColor = function (){     
  5.         alert(this.color);     
  6.     }     
  7. }    
  8.     
  9. function ClassB(sColor,sName){     
  10.     this.newMethod = ClassA;    //为ClassA赋予了方法newMethod     
  11.     this.newMethod(sColor);     //调用newMethod     
  12.     delete this.newMethod;      //删除对ClassA的引用     
  13.     
  14.     this.name = sName;     
  15.     this.sayName = function(){     
  16.         alert(this.name);     
  17.     }     
  18. }    
  19.  </span>  

Java代码  复制代码   收藏代码
  1. function ClassA(sColor){   
  2.     this.color = sColor;   
  3.     this.sayColor = function (){   
  4.         alert(this.color);   
  5.     }   
  6. }   
  7.   
  8. function ClassB(sColor,sName){   
  9.     this.newMethod = ClassA;    //为ClassA赋予了方法newMethod   
  10.     this.newMethod(sColor);     //调用newMethod   
  11.     delete this.newMethod;      //删除对ClassA的引用   
  12.   
  13.     this.name = sName;   
  14.     this.sayName = function(){   
  15.         alert(this.name);   
  16.     }   
  17. }   
[java]  view plain copy
  1. <span style="font-size:16px;">function ClassA(sColor){  
  2.     this.color = sColor;  
  3.     this.sayColor = function (){  
  4.         alert(this.color);  
  5.     }  
  6. }  
  7.   
  8. function ClassB(sColor,sName){  
  9.     this.newMethod = ClassA;    //为ClassA赋予了方法newMethod  
  10.     this.newMethod(sColor);     //调用newMethod  
  11.     delete this.newMethod;      //删除对ClassA的引用  
  12.   
  13.     this.name = sName;  
  14.     this.sayName = function(){  
  15.         alert(this.name);  
  16.     }  
  17. } </span>  

所有的新属性和新方法都必须在删除了新方法的代码行后定义。否则,可能会覆盖超类的相关属性和方法. 

可以实现多继承 



call() 方法--- 与经典的对象冒充方法相似, 第一个参数用作 this 的对象。其他参数都直接传递给函数自身。 

Js代码 
Java代码  复制代码   收藏代码
  1. function ClassA(sColor){      
  2.     this.color = sColor;      
  3.     this.sayColor = function (){      
  4.         alert(this.color);      
  5.     }      
  6. }      
  7.      
  8. function ClassB(sColor,sName){      
  9.     ClassA.call(this,sColor);  //this让ClassA中的关键字this等于新创建的ClassB对象      
  10.                         //第二个参数sColor对两个类来说都是唯一的参数。      
  11.     this.name = sName;      
  12.     this.sayName = function(){      
  13.         alert(this.name);      
  14.     }      
  15. }     
  16.   
  17. function ClassA(sColor){   
  18.     this.color = sColor;   
  19.     this.sayColor = function (){   
  20.         alert(this.color);   
  21.     }   
  22. }   
  23.   
  24. function ClassB(sColor,sName){   
  25.     ClassA.call(this,sColor);  //this让ClassA中的关键字this等于新创建的ClassB对象   
  26.                         //第二个参数sColor对两个类来说都是唯一的参数。   
  27.     this.name = sName;   
  28.     this.sayName = function(){   
  29.         alert(this.name);   
  30.     }   
  31. }    
[java]  view plain copy
  1. <span style="font-size:16px;">function ClassA(sColor){     
  2.     this.color = sColor;     
  3.     this.sayColor = function (){     
  4.         alert(this.color);     
  5.     }     
  6. }     
  7.     
  8. function ClassB(sColor,sName){     
  9.     ClassA.call(this,sColor);  //this让ClassA中的关键字this等于新创建的ClassB对象     
  10.                         //第二个参数sColor对两个类来说都是唯一的参数。     
  11.     this.name = sName;     
  12.     this.sayName = function(){     
  13.         alert(this.name);     
  14.     }     
  15. }    
  16.   
  17. function ClassA(sColor){  
  18.     this.color = sColor;  
  19.     this.sayColor = function (){  
  20.         alert(this.color);  
  21.     }  
  22. }  
  23.   
  24. function ClassB(sColor,sName){  
  25.     ClassA.call(this,sColor);  //this让ClassA中的关键字this等于新创建的ClassB对象  
  26.                         //第二个参数sColor对两个类来说都是唯一的参数。  
  27.     this.name = sName;  
  28.     this.sayName = function(){  
  29.         alert(this.name);  
  30.     }  
  31. }  </span>  

apply() 方法--- 与call()相似,两个参数,用作 this 的对象和要传递给函数的参数的数组。 

Java代码  复制代码   收藏代码
  1. Js代码    
  2. function ClassA(sColor){      
  3.     this.color = sColor;      
  4.     this.sayColor = function (){      
  5.         alert(this.color);      
  6.     }      
  7. }      
  8.      
  9. function ClassB(sColor,sName){      
  10.     ClassA.apply(this,arguments);//只有超类中的参数顺序与子类中的参数顺序完全一致时才可以传递参数对象      
  11.     ClassA.apply(this,new Array(sColor));//如果不是,就必须创建一个单独的数组,按照正确的顺序放置参数。      
  12.      
  13.     this.name = sName;      
  14.     this.sayName = function(){      
  15.         alert(this.name);      
  16.     }      
  17. }     
  18.   
  19. function ClassA(sColor){   
  20.     this.color = sColor;   
  21.     this.sayColor = function (){   
  22.         alert(this.color);   
  23.     }   
  24. }   
  25.   
  26. function ClassB(sColor,sName){   
  27.     ClassA.apply(this,arguments);//只有超类中的参数顺序与子类中的参数顺序完全一致时才可以传递参数对象   
  28.     ClassA.apply(this,new Array(sColor));//如果不是,就必须创建一个单独的数组,按照正确的顺序放置参数。   
  29.   
  30.     this.name = sName;   
  31.     this.sayName = function(){   
  32.         alert(this.name);   
  33.     }   
  34. }   
[java]  view plain copy
  1. <span style="font-size:16px;">Js代码   
  2. function ClassA(sColor){     
  3.     this.color = sColor;     
  4.     this.sayColor = function (){     
  5.         alert(this.color);     
  6.     }     
  7. }     
  8.     
  9. function ClassB(sColor,sName){     
  10.     ClassA.apply(this,arguments);//只有超类中的参数顺序与子类中的参数顺序完全一致时才可以传递参数对象     
  11.     ClassA.apply(this,new Array(sColor));//如果不是,就必须创建一个单独的数组,按照正确的顺序放置参数。     
  12.     
  13.     this.name = sName;     
  14.     this.sayName = function(){     
  15.         alert(this.name);     
  16.     }     
  17. }    
  18.   
  19. function ClassA(sColor){  
  20.     this.color = sColor;  
  21.     this.sayColor = function (){  
  22.         alert(this.color);  
  23.     }  
  24. }  
  25.   
  26. function ClassB(sColor,sName){  
  27.     ClassA.apply(this,arguments);//只有超类中的参数顺序与子类中的参数顺序完全一致时才可以传递参数对象  
  28.     ClassA.apply(this,new Array(sColor));//如果不是,就必须创建一个单独的数组,按照正确的顺序放置参数。  
  29.   
  30.     this.name = sName;  
  31.     this.sayName = function(){  
  32.         alert(this.name);  
  33.     }  
  34. } </span>  

原型链--- 用另一类型的对象重写类的 prototype 属性。 

prototype 对象的任何属性和方法都被传递给那个类的所有实例。 子类的所有属性和方法都必须出现在 prototype 属性被赋值后,因为在它之前赋值的所有方法都会被删除。 

缺点:使用原型链,就无法使用带参构造函数了 

Java代码  复制代码   收藏代码
  1. Js代码    
  2. function ClassA(){      
  3. }      
  4.      
  5. ClassA.prototype.name = "nomad";      
  6. ClassA.prototype.sayName = function(){      
  7.     alert(this.name);      
  8. }      
  9.      
  10. function ClassB()      
  11. }      
  12. ClassB.prototype = new ClassA(); //要确保调用构造函数没有任何参数。      
  13.      
  14. ClassB.prototype.age = 23;      
  15. ClassB.prototype.sayAge = function(){      
  16.     alert(this.age);      
  17. }     
  18.   
  19. function ClassA(){   
  20. }   
  21.   
  22. ClassA.prototype.name = "nomad";   
  23. ClassA.prototype.sayName = function(){   
  24.     alert(this.name);   
  25. }   
  26.   
  27. function ClassB()   
  28. }   
  29. ClassB.prototype = new ClassA(); //要确保调用构造函数没有任何参数。   
  30.   
  31. ClassB.prototype.age = 23;   
  32. ClassB.prototype.sayAge = function(){   
  33.     alert(this.age);   
  34. }    
[java]  view plain copy
  1. <span style="font-size:16px;">Js代码   
  2. function ClassA(){     
  3. }     
  4.     
  5. ClassA.prototype.name = "nomad";     
  6. ClassA.prototype.sayName = function(){     
  7.     alert(this.name);     
  8. }     
  9.     
  10. function ClassB()     
  11. }     
  12. ClassB.prototype = new ClassA(); //要确保调用构造函数没有任何参数。     
  13.     
  14. ClassB.prototype.age = 23;     
  15. ClassB.prototype.sayAge = function(){     
  16.     alert(this.age);     
  17. }    
  18.   
  19. function ClassA(){  
  20. }  
  21.   
  22. ClassA.prototype.name = "nomad";  
  23. ClassA.prototype.sayName = function(){  
  24.     alert(this.name);  
  25. }  
  26.   
  27. function ClassB()  
  28. }  
  29. ClassB.prototype = new ClassA(); //要确保调用构造函数没有任何参数。  
  30.   
  31. ClassB.prototype.age = 23;  
  32. ClassB.prototype.sayAge = function(){  
  33.     alert(this.age);  
  34. }  </span>  

混合方式--- 对象冒充继承构造函数的属性,用原型链继承 prototype 对象的方法。 

Java代码  复制代码   收藏代码
  1. Js代码    
  2. function ClassA(aName){      
  3.     this.name = aName;      
  4. }      
  5.      
  6. ClassA.prototype.sayName = function(){      
  7.     alert(this.name);      
  8. }      
  9.      
  10. function ClassB(aName,aAge){      
  11.     ClassA.call(this,aName);      
  12. }      
  13.      
  14. ClassB.prototype = new ClassA();      
  15.      
  16. ClassB.prototype.sayAge = function(){      
  17.     alert(this.age);      
  18. }     
  19.   
  20. function ClassA(aName){   
  21.     this.name = aName;   
  22. }   
  23.   
  24. ClassA.prototype.sayName = function(){   
  25.     alert(this.name);   
  26. }   
  27.   
  28. function ClassB(aName,aAge){   
  29.     ClassA.call(this,aName);   
  30. }   
  31.   
  32. ClassB.prototype = new ClassA();   
  33.   
  34. ClassB.prototype.sayAge = function(){   
  35.     alert(this.age);   
  36. }    
[java]  view plain copy
  1. <span style="font-size:16px;">Js代码   
  2. function ClassA(aName){     
  3.     this.name = aName;     
  4. }     
  5.     
  6. ClassA.prototype.sayName = function(){     
  7.     alert(this.name);     
  8. }     
  9.     
  10. function ClassB(aName,aAge){     
  11.     ClassA.call(this,aName);     
  12. }     
  13.     
  14. ClassB.prototype = new ClassA();     
  15.     
  16. ClassB.prototype.sayAge = function(){     
  17.     alert(this.age);     
  18. }    
  19.   
  20. function ClassA(aName){  
  21.     this.name = aName;  
  22. }  
  23.   
  24. ClassA.prototype.sayName = function(){  
  25.     alert(this.name);  
  26. }  
  27.   
  28. function ClassB(aName,aAge){  
  29.     ClassA.call(this,aName);  
  30. }  
  31.   
  32. ClassB.prototype = new ClassA();  
  33.   
  34. ClassB.prototype.sayAge = function(){  
  35.     alert(this.age);  
  36. }  </span>  
其他继承方式: 

zInherit 库( http://www.nczonline.net/downloads ): 支持所有的现代浏览器( Mozilla 、 IE 、 Opera 、 Safari )及一些旧的浏览器( Netscape 4.x 、 IE 、 Mac )。(需要引入 zinherit.js (见附件)) 



zInherit 库给 Object 类添加了两个方法: 

----inheritFrom(): 负责复制指定类的所有方法, 接受一个参数,即要复制的方法所属的类 

----instanceOf(): instanceof 运算符的替代品 

Java代码  复制代码   收藏代码
  1. Js代码    
  2. <script type="text/javascript" src="~/zinherit.js"></script>      
  3. function ClassA(){      
  4. }      
  5.      
  6. ClassA.prototype.name = "nomad";      
  7. ClassA.prototype.sayName = function(){      
  8.     alert(this.name);      
  9. }      
  10.      
  11. function ClassB(){      
  12. }      
  13.      
  14. ClassB.prototype.inheritFrom(ClassA);       
  15.      
  16. ClassB.prototype.age = 23;      
  17. ClassB.prototype.sayAge = function(){      
  18.     alert(this.age);      
  19. }     
  20.   
  21. <script type="text/javascript" src="~/zinherit.js"></script>   
  22. function ClassA(){   
  23. }   
  24.   
  25. ClassA.prototype.name = "nomad";   
  26. ClassA.prototype.sayName = function(){   
  27.     alert(this.name);   
  28. }   
  29.   
  30. function ClassB(){   
  31. }   
  32.   
  33. ClassB.prototype.inheritFrom(ClassA);    
  34.   
  35. ClassB.prototype.age = 23;   
  36. ClassB.prototype.sayAge = function(){   
  37.     alert(this.age);   
  38. }   
[java]  view plain copy
  1. <span style="font-size:16px;">Js代码   
  2. <script type="text/javascript" src="~/zinherit.js"></script>     
  3. function ClassA(){     
  4. }     
  5.     
  6. ClassA.prototype.name = "nomad";     
  7. ClassA.prototype.sayName = function(){     
  8.     alert(this.name);     
  9. }     
  10.     
  11. function ClassB(){     
  12. }     
  13.     
  14. ClassB.prototype.inheritFrom(ClassA);      
  15.     
  16. ClassB.prototype.age = 23;     
  17. ClassB.prototype.sayAge = function(){     
  18.     alert(this.age);     
  19. }    
  20.   
  21. <script type="text/javascript" src="~/zinherit.js"></script>  
  22. function ClassA(){  
  23. }  
  24.   
  25. ClassA.prototype.name = "nomad";  
  26. ClassA.prototype.sayName = function(){  
  27.     alert(this.name);  
  28. }  
  29.   
  30. function ClassB(){  
  31. }  
  32.   
  33. ClassB.prototype.inheritFrom(ClassA);   
  34.   
  35. ClassB.prototype.age = 23;  
  36. ClassB.prototype.sayAge = function(){  
  37.     alert(this.age);  
  38. } </span>  



xbObjects: 为 JavaScript 提供更强的面向对象范型,不止支持继承,还支持方法的重载和调用超类方法的能力。 

(xbObjects.js见附件) 



几个方法: 

--registerClass(className, parentClassName):参数以字符串形式传递,如父类不明确,可以只用第一个参数 

--defineClass(className, prototype_func):className为字符串形式的类名,prototype_func为函数指针(函数名) 

--parentMethod(method,args...):接受任意多个参数,但第一个参数总是要调用的父类方法的名字(该参数必须是字符串,而不是函数指针),所有其他参数都被传给父类的方法。 

--- 

Js代码 
//1,必须注册类   
_classes.registerClass("Polygon");   
  
function Polygon(iSides) {   
    //2,在构造函数内调用defineClass()方法   
    _classes.defineClass("Polygon", prototypeFunction);   
    //3,   
    this.init(iSides);   
      
   //该函数用于初始化对象的所有属性和方法   
    function prototypeFunction() {   
       
        Polygon.prototype.init = function(iSides) {   
            this.parentMethod("init");   
            this.sides = iSides;               
        };   
       
        Polygon.prototype.getArea = function () {   
            return 0;   
        };       
       
    }   
}   
  
_classes.registerClass("Triangle", "Polygon");   
  
function Triangle(iBase, iHeight) {   
  
    _classes.defineClass("Triangle", prototypeFunction);   
       
    this.init(iBase,iHeight);   
       
    function prototypeFunction() {   
        Triangle.prototype.init = function(iBase, iHeight) {   
            this.parentMethod("init", 3);   
            this.base = iBase;   
            this.height = iHeight;   
        };   
           
        Triangle.prototype.getArea = function () {   
            return 0.5 * this.base * this.height;   
        };       
    }   
       
}   
  
_classes.registerClass("Rectangle", "Polygon");   
  
function Rectangle(iLength, iWidth) {   
  
    _classes.defineClass("Rectangle", prototypeFunction);   
       
    this.init(iLength, iWidth);   
       
    function prototypeFunction() {   
        Rectangle.prototype.init = function(iLength, iWidth) {   
            this.parentMethod("init", 4);   
            this.length = iLength;   
            this.width = iWidth;   
        }   
       
       Rectangle.prototype.getArea = function () {   
            return this.length * this.width;   
       };       
           
    }   
}  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Web Socket 是一种用于实现浏览器与服务器全双工通信的协议,支持双向实时通信。在 Java实现 Web Socket 聊天可以使用 Java API for WebSocket(JSR-356)实现。 以下是一个简单的 Web Socket 聊天室的示例: 1. 创建一个聊天处理程序 ChatHandler,继承javax.websocket.Endpoint 和 javax.websocket.MessageHandler.Partial 接口: ``` import java.io.IOException; import java.nio.ByteBuffer; import javax.websocket.Endpoint; import javax.websocket.EndpointConfig; import javax.websocket.MessageHandler; import javax.websocket.Session; public class ChatHandler extends Endpoint implements MessageHandler.Partial<String> { private Session session; @Override public void onOpen(Session session, EndpointConfig config) { this.session = session; session.addMessageHandler(this); } @Override public void onMessage(String message, boolean last) { try { // 发送消息给所有连接的客户端 for (Session s : session.getOpenSessions()) { if (s.isOpen()) { s.getBasicRemote().sendText(message, last); } } } catch (IOException e) { e.printStackTrace(); } } @Override public void onMessage(ByteBuffer message, boolean last) { throw new UnsupportedOperationException("Binary messages not supported."); } } ``` 2. 创建一个 WebSocket 端点 ChatEndpoint,继承javax.websocket.server.ServerEndpoint: ``` import javax.websocket.server.ServerEndpoint; @ServerEndpoint(value = "/chat", encoders = {MessageEncoder.class}, decoders = {MessageDecoder.class}) public class ChatEndpoint { // 该注解会自动创建 ChatHandler 实例,并将其添加到 WebSocket 会话中 } ``` 3. 创建一个消息编码器 MessageEncoder 和一个消息解码器 MessageDecoder,用于在客户端与服务器之间转换消息: ``` import javax.json.Json; import javax.json.JsonObject; import javax.websocket.EncodeException; import javax.websocket.Encoder; import javax.websocket.EndpointConfig; public class MessageEncoder implements Encoder.Text<Message> { @Override public String encode(Message message) throws EncodeException { JsonObject jsonObject = Json.createObjectBuilder() .add("sender", message.getSender()) .add("content", message.getContent()) .build(); return jsonObject.toString(); } @Override public void init(EndpointConfig config) {} @Override public void destroy() {} } ``` ``` import java.io.StringReader; import javax.json.Json; import javax.json.JsonObject; import javax.websocket.DecodeException; import javax.websocket.Decoder; import javax.websocket.EndpointConfig; public class MessageDecoder implements Decoder.Text<Message> { @Override public Message decode(String s) throws DecodeException { JsonObject jsonObject = Json.createReader(new StringReader(s)).readObject(); return new Message(jsonObject.getString("sender"), jsonObject.getString("content")); } @Override public boolean willDecode(String s) { try { Json.createReader(new StringReader(s)).readObject(); return true; } catch (Exception e) { return false; } } @Override public void init(EndpointConfig config) {} @Override public void destroy() {} } ``` 4. 创建一个消息类 Message,用于表示聊天消息: ``` public class Message { private String sender; private String content; public Message(String sender, String content) { this.sender = sender; this.content = content; } public String getSender() { return sender; } public void setSender(String sender) { this.sender = sender; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } } ``` 5. 在 HTML 页面中使用 JavaScript 创建 WebSocket 连接并发送和接收消息: ``` <script> var websocket = new WebSocket("ws://localhost:8080/chat"); websocket.onopen = function(event) { console.log("WebSocket connected."); }; websocket.onmessage = function(event) { var message = JSON.parse(event.data); console.log("Received message: " + message.content); }; function sendMessage() { var message = document.getElementById("messageInput").value; websocket.send(JSON.stringify({sender: "user", content: message})); console.log("Sent message: " + message); } </script> ``` 6. 将 ChatEndpoint、ChatHandler、MessageEncoder、MessageDecoder 和 Message 类打包成一个 WAR 文件,并部署到 Tomcat 或 Jetty 中。 这样就可以在浏览器中访问 HTML 页面,通过 WebSocket 实现实时聊天了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值