In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article shows you how to understand Ext's extend from the perspective of Java. The content is concise and easy to understand. It will definitely brighten your eyes. I hope you can get something through the detailed introduction of this article.
In Java, we have the following facts when implementing inheritance:
1. Prepare two classes, which are linked with the extends keyword
2. If the superclass does not have a default constructor, you need to explicitly super and pass parameters in the subclass constructor. If it is the default constructor, you can also super, but the super virtual machine is automatic.
3, subclasses can be appended, overridden, overloaded methods, subclasses can have their own private properties, they are constructed in the subclass constructor
4, the field is the data, the method is in the code area, and the class establishes the method table. The object of the same class has its own data but shares the method code.
For example, there are two classes, Plane and Space,Plane for plane, Space for space, Space is a subclass of Plane, in java
/ * * allocate memory blocks according to the number of fields * when instantiating, the virtual machine calls the Plane.Plane method to pass the memory block as this and construction parameters, and initializes the data field. * create method table mapping * / class Plane {protected int x; protected int y; Plane (int x, int y) {this.x = x; this.y = y;} public void XY () {System.out.println (x * y) }} / * automatically have the behavior of the superclass, but the properties of the superclass need to be constructed by the superclass * the subclass can construct its own properties, add its own methods, and overwrite the methods of the superclass * * allocate a memory block according to all fields of the inheritance structure, and call Space.Space to pass this memory block as a this and a parameter together * give that part of the superclass to the superclass And initialize your own. * * create method table * / class Space extends Plane {private int z; Space (int x, int y, int z) {super (x, y); this.z = z;} public void XYZ () {System.out.println (x * y * z) }} public class Test {public static void main (String [] args) {Plane plane = new Plane (2Magol 3); plane.XY (); Space space = new Space (2Jing 3,4); space.XYZ ();}}
Then it is the same in js, the difference is that the code is put on the prototype of the constructor (can be understood as the class in Java), the prototype is an ideal place to place methods and immutable properties, the prototype is an object, the only difference between it and ordinary object is that it has a constructor attribute pointing to the constructor to which it depends, in java subclass to find properties and methods is done through a virtual machine, but in js it needs to be done through the prototype chain. In other words, the inheritance relationship is opaque to programmers, and we need to understand this prototype mechanism. There are two chains in the prototype mechanism, one is the prototype chain, the other is the constructor chain.
Following the java code above, we can write js as follows:
Var Plane = function (x, y) {this.x = x; this.y = y;}; Plane.prototype.XY = function () {alert (this.x * this.y);}; var Space = function (x, y, z) {/ / call the superclass constructor with this, there is no automatic super call for java, so call Plane.call (this, x, y) manually / Space.superclass.constructor.call (this, x, y); you can use a unified syntax / / to construct your own data this.z = z;}; Space.prototype.XYZ = function () {alert (this.x * this.y * this.z);}
The this of a function in JS refers to the caller of the function, and both java and js,this can be understood as the newly allocated piece of memory that holds the object. Through Space extends Plane in java, virtual machines maintain their inheritance relationships to complete the automatic lookup of inheritance relationships, but we need to deal with them manually in js. At this time, Space cannot call the XY method because they are not on the prototype chain. We can develop a function to simulate the java keyword extends, such as this function called extend, which completes the assembly of the prototype chain by executing extend (Plane,Space).
So how do you implement extend? First of all, it is important to understand that the relationship between the prototype chain, the subclass and the parent class on the prototype chain is Space.prototype._proto_ = = Plane.prototype. If you can't understand it, look at the class String. String.prototype._proto_ = = Object.prototype, that is, the prototype of String will be linked to the prototype of Object, and the link is done through the attribute of _ proto_. _ proto_ is a read-only property that can only be written through the constructor, so String is a subclass of Object.
Now that the prototype._proto_ of Plane is equal to the prototype._proto_ of Object,Space and the prototype._proto_ of Object, we need to transform this relationship in the extend function, that is, to complete the Space.prototype._proto_ = = Plane.prototype. We know that the _ proto_ of an object needs to be constructed by that constructor to point to the prototype of a constructor, so we just need to let Space.prototype = new Plane (). At this point, Space.prototype._proto_ = = Plane.prototype, instead of pointing to Object, the prototype also has an attribute constructor that points to the constructor where the prototype is located. Since Space.prototype has just been created by Plane, there is no such attribute yet, so we need to manually assign the value to it. The code is Space.prototype. Constructor = Space. In this way, extend's responsibility is done.
But there are two problems:
1, because the prototype of Space has been replaced in extend, its original method is gone.
2. The prototype of Space is constructed by Plane. Although it achieves Space.prototype._proto_ = = Plane.prototype, Plane also writes two pieces of junk data, both of which are undefined, which are meaningless, so it is necessary to delete them manually, so that the extend method cannot be used.
First of all, to solve * problems, we need to change our thinking a little bit. Taking advantage of the fact that functions are also data in js, we copy those methods of Space into an object, such as
Var sbm= {XYZ: function () {alert (this.x * this.y * this.z);}}
Pass this sbm to extend,extend and copy all the methods on sbm to the prototype of Space after replacing the prototype. Sbm is an object literal, using json syntax. Now the extend becomes three parameters, namely extend (sb,sp,sbm), sb is the subclass, sp is the superclass, and sbm is the method that the subclass puts on the prototype.
For the second problem, the essential reason is that the Plane function has to complete some data initialization, it is a superclass, we can't control it, we only care about the prototype of Plane, not what data it constructs, so we can take out its prototype alone and define a clean function, which does nothing but set the prototype of this clean function as the prototype of Plane. Then use this clean function to construct an object, so that the object is clean, and the _ proto_ points to Plane.prototype. With these two methods, we can begin to implement the extend as follows:
Var extend = function (sb, sp, sbm) {var F = function () {}, sbp,spp = sp.prototype; F.prototype = spp; / / grafted with a clean function to get the subclass prototype sbp = sb.prototype = new F (); sbp.constructor = sb / then specify a constructor to refer back to the subclass / / copy the properties on the sbm to the prototype of the subclass for (var p in sbm) {sbp [p] = sbm [p];}}
Then the code to finish inheriting Plane from Space is as follows:
Extend (Space, Plane, {XYZ: function () {alert (this.x * this.y * this.z);}}); var spaceObject = new Space (2,3,4); spaceObject.XY (); / / call the superclass method spaceObject.XYZ () successfully
OK, when we get here, we basically finish the task, completely from the direction of java. We now use the features of js to optimize to make it easier to use extend.
We said that we must write two classes in java, each class must write its own fields, constructors, methods, etc., in our implementation of the extend function, we do pass in the subclass, the parent class, but we have one more parameter, that is, the method set of the subclass, that is, the sbm,*** parameter sb itself is a function, can we also put this function into the sbm? So extend becomes two parameters, namely extend (sp,sbm). Now extend returns a function, and the function returned is a subclass of sp, which is completely feasible. Let's call it extend2.
Var extend2 = function (sp, sbm) {var sb = sbm.constructor; / / if there is no explicit constructor, then the subclass calls the superclass constructor if (sb = = Object) {sb = function () {sp.apply (this, arguments);}; extend (sb, sp, sbm); return sb;}
We say that we want to put the constructor of the subclass on the sbm, and the key we put on it is called constructor, which means the constructor, and every object in js has a constructor attribute, which points to the constructor of this object. Sbm is originally an Object object, and its constructor points to Object. This constructor is on the prototype associated with sbm. Now we set the constructor of a subclass on sbm, which means that sbm has its own constructor.
Now what we need to do in extend2 is to extract the constructor, and then restore to three parameters to call the previous extend, in java our subclass can not have a constructor, as long as the parent class also has a default constructor, then here, sbm may not contain constructor, then we need to do a function that calls the constructor of the parent class, which is automatic in java. So when sbm.constructor is Object, it means that sbm does not specify a constructor. At this time, the
Sb = function () {sp.apply (this, arguments);}
That is, the parent constructor is called. This is fine by passing the sb,sp,sbm to extend.
Our new inheritance syntax at this time is as follows:
Var NewSpace = extend2 (Plane, {constructor: function (x, y, z) {Plane.call (this, x, y); this.z = z;}, XYZ: function () {alert (this.x * this.y * this.z);}}) Var newObject = new NewSpace (3,4,5); newObject.XY (); newObject.XYZ ()
It is more or less the same as the implementation of prototype.js and mootolls.
/ / properties are directly passed to `create` method var Person = Class.create ({initialize: function (name) {this.name = name;}, say: function (message) {return this.name +':'+ message;}}); var Animal = new Class ({initialize: function (age) {this.age = age) }, say: function () {alert (this.age);}}); var Cat = new Class ({Extends: Animal, initialize: function (name, age) {this.parent (age) / / calls initalize method of Animal class this.name = name;}})
We're almost done here, but careful readers will find that we copy all the attributes of sbm to the prototype of the subclass in extend. Isn't it about copying constructor to the prototype? It doesn't matter if the sbm contains the constructor, because the constructor of the prototype of the subclass needs to point to this constructor, but if there is no constructor on the sbm, then you have to copy the Object to the prototype of the subclass. The answer is no. The for in loop we use when copying cannot iterate the default constructor.
Now let's take a look at Ext.extend. There should be no problem at all. We used two methods extend,extend2,Ext to merge it into one method Ext.extend, so it determines the parameters passed in and transforms them, so that Ext.extend supports calls with two parameters and three parameters. For copying attributes, Ext makes a utility function called Ext.apply, and for copying attributes of an object to a class prototype, Ext makes a utility class called Ext.override.
Ext.extend = function () {/ / inline overrides copies the object attributes passed in to this var io = function (o) {for (var m in o) {this [m] = o [m];}}; / / oc is actually the Object function var oc = Object.prototype.constructor Return function (sb, sp, overrides) {/ / if the second parameter is an object rather than a class, it is called with two parameters, the * * parameter is the parent, and the second parameter is the object if (typeof sp = = 'object') {overrides = sp; / / replace the third parameter with the object sp = class / / assign the second parameter as the parent class sb = overrides.constructor! = oc? Overrides.constructor: function () {sp.apply (this, arguments);} / / the constructor of the subclass is either named constructor or directly calls a function of the superclass constructor / / the constructor not only constructs itself but also calls the two parameters * 1 inherited from the constructor} / * * of the superclass. Write a constructor and initialize some fields. Then call the superclass constructor and write a json object that overrides the superclass method or the appended method * and then calls extend (sub,sup, {over1:f,over2:f,addf:f}) like the syntax of java * SubClass extend SuperClass {* SubClass () {* super () * 2 can be understood as simulating java, but since the constructor is also data, you can put the constructor into that jdon object as well. Just agree on a name * such as constructor, and then call * extend (sup, {constructor:f,over1:f,over2:f,addf:f}) * / var F = function () {}, sbp, spp = sp.prototype F.prototype = spp; sbp = sb.prototype = new F (); / / above use clean function grafting to get the subclass prototype sbp.constructor = sb; / / and then specify a constructor to refer back to the subclass, so the big work becomes sb.superclass = spp / / specify a static field on the subclass to point to the superclass prototype, so that the superclass constructor sub.superclass.constructor.call (this, config) / * * can be accessed in the subclass constructor. This code is defensive. When you implement inheritance by yourself, the constructor pointing problem on the prototype may occur. So if you find that the constructor of a superclass * is object, either the superclass is Object, or there is an error, so reset it again, just in case, this code we will mention when analyzing the Observable of Ext * / if (spp.constructor = = oc) {spp.constructor = sp. A static rewriting method above the subclass. Note that js is not overloaded and can be used to rewrite the function sb.override = function (o) {Ext.override (sb, o);} on the subclass prototype. / / reference a superclass prototype on the subclass prototype with a closure, referencing a function sbp.superclass = sbp.supr = (function () {return spp;}); / / placing an override function on the subclass prototype that can be used to override the concrete instance object sbp.override = io / / overwrite or add functions Ext.override (sb, overrides) on the subclass prototype; / / put a static inheritance method directly on the subclass, which seems to implement multiple inheritance sb.extend = function (o) {return Ext.extend (sb, o);}; return sb;};} ()
Now using Ext's extend to implement our previous inheritance code is as follows
Var Plane = function (o) {this.x = o.x; this.y = o.y;}; Plane.prototype.XY = function () {alert (this.x * this.y);}; var Space = Ext.extend (Plane, {constructor: function (o) {Space.superclass.constructor.call (this, o) This.z = o.z;}, XYZ: function () {alert (this.x * this.y * this.z);}}); var space = new Space ({xpur2) Space.XYZ ()
Now let's take a look at the inheritance highlight of Ext, Observable, which is under the Ext.util package, which means observer, using observer mode, EDA mode, UI components use this observation-and event-based mechanism to communicate and render.
All UI components inherit this class, so let's look at its constructor
EXTUTIL.Observable = function () {var me = this, e = me.events; if (me.listeners) {me.on (me.listeners); delete me.listeners;} me.events = e | {};}
This constructor takes no arguments, and in java, the construction of this parent class can automatically call the default constructor, but note here that if (me.listeners) relies on the construction behavior of subclasses, which seems to be a taboo in object-oriented principles, but it is understandable that if an inheritance embodiment is completely maintained by a team, they make inheritance rules and inheritance specifications at the same time The listeners here can not be provided in the subclass, and you can let the constructed object call the on method to add the listener. Similarly, the events here will be assigned an empty object if the subclass is not constructed. Then the Observable constructor does two things, one is to see whether the subclass has a listener on the object, if so, it calls the on method of the object to bind the event and listener, and the other is to see whether the subclass has placed events on the object, and if not, set the events property of the object to an empty object. In other words, subclasses can do nothing at all. Subclasses are only responsible for their own data construction and behavior overrides or appends. Events is a container for Ext.util.Event objects after binding to listeners. See this line of code: me.events [eventName] = ce = new EXTUTIL.Event (me, eventName) That is, in Ext, a living object that responds to events has an Event container that holds listeners to which events the object can respond to and which listeners are invoked after the event is triggered.
The methods placed on the Observable prototype are inherited by the subclass, and objects of the subclass can call these methods at run time, as follows:
There is a static variable and some methods on the prototype, which are all related to events and listening. note that the prototype of Observable is a new object direct quantity, and its constructor property must point to Object, not Observable. Isn't there bug? I found that alert (Ext.util.Observable.prototype.constructor = = Ext.util.Observable) through code inspection; the result is indeed true. The answer lies in the defensive code of Ext.extend. Let's go back and have a look.
Now let's write a class that inherits Obervable, but not a UI component, but a domain model, such as a forum post, which will run out of a modified event after it is modified, and the listener captures this event and saves the change to the database, as follows:
ForumThread = Ext.extend (Ext.util.Observable, {constructor: function (config) {this.name = config.name; / / put listeners into the superclass attribute this.listeners = config.listeners; this.events = {"change": true} / / set events to the domain model, and you can also / * this.addEvents ({"change": true}) as described above. * / / call the superclass to construct the superclass invariant ForumThread.superclass.constructor.call (this, config)}, / / the domain behavior will trigger the event changeName: function (newName) {alert ("original topic name is:" + this.name) This.name = newName; alert ("the changed topic name is:" + this.name); this.fireEvent ("change", this); / / trigger event}}) Ext.onReady (function () {var forumThread = new ForumThread ({name: 'the idea of upgrading the Jdon framework to the DCI framework' / / inject the listener handler listeners: {change: function (thread) {alert ('receive event) when constructing the domain model The new name will be saved asynchronously:'+ thread.name) }); / / Domain behavior calls forumThread.changeName ("the idea of upgrading the Jdon framework to a DCI framework, integrating JdonMVC");})
If the event setting and listening binding is done directly in the subclass, then there is no need to explicitly call the superclass constructor
ForumThread = Ext.extend (Ext.util.Observable, {constructor: function (config) {this.name = config.name; this.events = {"change": true}; this.on (config.listeners) }, / / Domain behavior, triggers the event changeName: function (newName) {alert ("original topic name is:" + this.name); this.name = newName; alert ("changed topic name is:" + this.name); this.fireEvent ("change", this) / / trigger event}}); the above is how to understand the extend of Ext from the perspective of Java. Have you learned the knowledge or skills? If you want to learn more skills or enrich your knowledge reserve, you are welcome to follow the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.