Is it possible to set a property on an instance of a class like so;
MyCls item = new MyCls();
item['propName'] = propValue;
No. Apex does not support indexing notation on any object - custom classes, Map instances, or sObjects.
You can use the get() and put() methods on the Map and sObject built- classes to access fields by name or Map values. However, doing so on an sObject loses you compile-time field checking, and typically requires a lot of casting in statically-typed Apex. It's preferable to use standard access when possible.
This does not apply to custom classes unless you implement your own accessor methods.
Related
I am learning qemu and qom recently. I am perplexed when I meet the conception of ObjectClass and Object. I already understand that ObjectClass stands for class while Object means instance of class. However, what I want to know is What kind of information should store in ObjectClass and what's going on in Object.
As far as I am concerned, like C++ or Java, Object just the same as what's define in Class and be used in real logic. In this case, Class seems like a template which produce Object the real be used.
In qemu, everything seems different. We define these two in two struct, and they have different properties, which leads to separation of Class and Object. Does it means I can use one ObjectClass to produce many Object that differ with each other? And secondly, why should I do this? Are there any advantages of this pattern? In detail, what's the role ObjectClass and Object plays in qemu respectively? And what about their relationship? If I want to design a new device, What should I do in initialization of MyObjectClass and MyObject?
What's more, I notice that qemu will initialize every ObjectClass by TypeImpl, which is initialized by TypeInfo defined by developer.
TypeInfo => ModuleEntry => TypeImpl => ObjectClass => Object
Of course they do different things. TypeInfo converts to ModuleEntry before main function is executed(__attribute__((constructor))), which contains initial functions of ObjectClass and Object. Why we need this mechanism? On the other words, what if we just create ObjectClass instead of create TypeImpl and create ObjectClass after that? Any advantages?
This is part of QEMU's object model (QOM), which is documented in the developer section of the documentation. You should read that, and also look through include/qom/object.h for more details of the object model.
In QOM, for any class there is one class struct -- for the base Object type the class struct is ObjectClass. There are then multiple objects created at runtime, each of which is a struct Object. This applies also for subtypes of Object, like DeviceState, whose class struct is DeviceClass. The class struct holds fields which are common to every instance of that object type, notably including the function pointers which are the equivalent of methods. The object struct holds all the fields which are per-instance. Because each Object contains a pointer to the corresponding ObjectClass, you can always get from a pointer to an instance of an object to its class information.
Because we're implementing an object-oriented model in C, we have to have everything be explicit -- in C++ and Java, because the object model is part of the language the compiler can sort out under the hood a lot of the things QOM has to manage manually with class structs and object structs and so on.
More generally, if your aim is "write a new device" I would recommend that you do not spend any time looking into the internals of the QOM implementation. Instead you should look at how other devices similar to yours are implemented and at what the patterns of code are that they use to declare and use a new device type.
I am working on a ClojureScript wrapper for qx.mobile and would like to programmatically build a cljs type hierarchy mirroring the qx class hierarchy.
Is there a way to get all the subclasses of a qooxdoo class?
How about a programmatic way to query the superclass of a class?
I am already putting qx.Class.getProperties to good use.
Thx, kt
The programmatic way of getting the superclass of a given class is documented at http://demo.qooxdoo.org/current/apiviewer/#qx.Class
<classname>.superclass
or getting the name of the superclass as a string
<classname>.superclass.classname
which means that e.g.
qx.ui.core.Widget.superclass.classname
will return the string "qx.ui.core.LayoutItem".
Regarding the programmatic way to retreive all subclasses of a class:
This is currently not possible without iterating the whole class hierarchy/tree and testing the objects against being subclasses of the given class.
We discussed at https://gitter.im/qooxdoo/qooxdoo that it maybe would be usefull to create an array for each class holding the subclasses. This could be added to the code of the private method __createClass in qx.Class.
We would like to encourage everyone who needs this (or other) functionalities to join us on https://github.com/qooxdoo/qooxdoo/ and help extending qooxdoo by creating a pull requests. Thank you.
After digging arround a bit in qx.Class we decided to implement a method qx.Class.getSubclasses which returns a hash object with all subclasses of a given class.
var subclasses = qx.Class.getSubclasses(qx.ui.core.Widget);
gets all subclasses of qx.ui.core.Widget.
Landed in qooxdoo master with commit https://github.com/qooxdoo/qooxdoo/pull/9037
I've been trying to find some info on difference between instantiating form fields through static method and the new keyword. Can somebody tell me what are the practical implications, limitations, between new MyFormField and MyFormField::create() esp. with regards to SilverStripe
Using the create factory method would check for overloads (set via Object::useCustomClass()) and return an instance of the custom class in that case.
This method first for strong class overloads (singletons & DB
interaction), then custom class overloads. If an overload is found, an
instance of this is returned rather than the original class. To
overload a class, use Object::useCustomClass()
So using the create method rather than instantiating the Object yourself would provide a possibility to overload the used Class without altering the code.
see
http://api.silverstripe.org/3.1/class-Object.html#_useCustomClass
http://api.silverstripe.org/3.1/class-Object.html#_create
So, I'm trying to learn how to use Backbone and I keep switching back and forth between using the defaults object and the initialize method. If I use the method, it's with "this.set()" to set attributes, etc. Otherwise those attributes are set in the default object.
I've looked around on google and I can't seem to find a recommended way or "common" pattern of when to use defaults or when to use initialize. I can make my code work both ways and both yield an object with the desired attributes, but it bugs me because i'm unsure if i'm using it incorrectly.
You would use the defaults object for all "static" data as you can only define them once for a model class. You will need the initialize method if you have to add dynamic per instance properties. For example:
initialize: function() {
this.set({displayName: this.get('firstname') + this.get('lastname')});
}
I got this problem,
"The deserializer has no knowlege of any type that maps to this contract"
After googling, I reached this post
The deserializer has no knowlege of any type that maps to this contract
where the answer says, the base class have to declare "KnownTypes" like
[DataContract, KnownType(typeof(Subclass)) ...],
If I have to declare this in my parent class, [DataContract, KnownType(typeof(Subclass))], doesn't it break the principles of OO Design that parent class doesn't have to know about subclass?
What is the right way of doing this?
The serializer is designed in a way that, if it serializes an object, it should be able to read it back. If you attempt to serialize an object with a declared type of 'Base', but an actual type of 'Derived' (see example below), if you want to be able to read back from the serialized object an instance of 'Derived', you need to somehow annotate the XML that the instance is not of the type of which it was declared.
[DataContract]
public class MyType
{
[DataMember]
public object obj = new Derived();
}
The serialized version of the type would look something like the XML below:
<MyType>
<obj actualType="Derived">
<!-- fields of the derived type -->
</obj>
</MyType>
When the type is being deserialized, the serializer will look at the "actualType" (not actual name) attribute, and it will have to find that type, initialize it, and set its properties. It's a potential security issue to let the serializer (with in Silverlight lives is a trusted assembly and has more "rights" than the normal user code) to create arbitrary type, so that's one reason for limiting the types which can be deserialized. And based on the design of the serializer (if we can serialize it, we should be able to deserialize it), the serialization fails for that reason as well.
Another problem with that is that the serialized data is often used to communicate between different services, in different computers, and possibly with different languages. It's possible (and often it is the case) that you have a class in a namespace in the client which has a similar data contract to a class in the server side, but they have different names and / or reside in different namespaces. So simply adding the CLR type name in the "actualType" attribute won't work in this scenario either (the [KnownType] attribute helps the serialzier map the data contract name / namespace to the actual CLR type). Also, if you're talking to a service in a different language / platform (i.e., Java), CLR type names don't even make sense.
Another more detailed explanation is given at the post http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,a3775eb1-b441-43ad-b9f1-e4aaba404235.aspx - it talks about [ServiceKnownType] instead of [KnownType], but the principles are the same.
Finally, about your question: does it break that OO principle? Yes, that principle is broken, that's a price to pay for being able to have lose coupling between the client and services in your distributed (service-oriented) application.
Yes it breaks the principles of OO design. This is because SOA is about sharing contracts (the C in ABC of services) and not types, whereas OO is about type hierarchies. Think like this the client for a service may not be even in an OO language but SOA principles can still be applied. How the mapping is done on server side is an implementation issue.