In Swift, I am trying to create a generic class that can extend another class, while inheriting from it. I am able to do it in C++ as follows, but is there a way to do the same in Swift?
class Atom {};
template<typename Base, typename Extension>
class Extend: Base {
Extension _value;
};
int main() {
return 0;
}
One approach I have been trying to apply is Protocol Oriented Design, but it doesn't seem to be able to take a class and extend it. The best I reached is something like creating the extension manually, and declaring that it does extend Atom, but at that point, I would just create another class and add to it the respective property manually.
One way to do it is by generating the code for the subclass at compile or run time. check these answers of these questions:
How to generate code dynamically with annotations at build time in Java?, and Generating, compiling and using Java code at run time?.
You can add a custom generic method to the base class that would be overridden by each subclass (in the generated code) and it may return Object. It would be a working approach, if it's worth the hassle.
Related
I was wondering if SystemVerilog has a generic class handler similar to how Java has an "Object" class or how C has a void*?
If so, what is it called? What I'm trying to do is have a class that when it is instantiated is passed a defined object, however it could be any object. So, I'm hoping that I can have an empty handler to this unknown data class (or generic) and I'm hoping that I don't have to create an empty data class and use one that is already part of the SystemVerilog library.
I should add that I'm not using UVM or any other methodologies, otherwise I would have just started from a uvm_component or uvm_object.
Java's Object class is the root base class of all classes. There is no such root class in SystemVerilog.
The UVM's uvm_object provides the functionality you are looking for and I suggest using it if for nothing else.
Disclaimer: I'm still learning Swift so forgive me if I haven't understood certain concepts/capabilities/limitations of Swift.
With the Swinject framework, if you wanted to bind a protocol to a class - it seems you have to return the class instance in a closure such as:
container.register(Animal.self) { _ in Cat() }
Is is possible to be able to instead pass in two types to the register() method and have the framework instantiate the class for you? It would need to recursively see if that class had any initializer dependencies of course (Inversion of Control).
This is possible in the PHP world as you have the concept of reflection, which allows you to get the class types of the dependencies, allowing you instantiate them on the fly. I wonder if Swift has this capability?
It would be much nicer to write this:
container.register(Animal.self, Cat.self)
This would also allow you to resolve any class from the container and have it's dependencies resolved also (without manually registering the class):
container.resolve(NotRegisteredClass.self)
Note: This only makes sense for classes that do not take scalar types as a dependency (as they need to be explicitly given of course).
The second case - resolving a type without the explicit registration - is currently not possible because of Swift's very limited support for the reflection.
However, there is a SwinjectAutoregistration extension which will enable you to write something very close to your first example:
container.autoregister(Animal.self, initializer: Cat.init)
I have a class XmlRecord. This class will deal with reading/writing to an xml file. At the moment, I have the following for that class:
class XmlRecord {
private val _file = new File("file.xml")
}
I want this class to somehow create the file if it doesn't exist. I know how to achieve this but I'm unsure how to design it in an Object Orientated way. I think I have two options:
Do I add a code to the constructor (or a call to a private method) that will create this file automatically if it doesn't exist. My problem with this method is that how do I unit test this as this code is effectively private code? Would I have to inject the File dependency so it could be mocked during testing?
Do I get the constructor to return an exception or implement a public method for the class so that the caller can use it to check if a file needs to be created? If so, the caller would then call another public method that would create the file. Again I think I would need to inject the dependency.
I hope that makes sense. I'm just trying to get a better grasp on designing my classes.
The presence of abstractions to accomplish DIP have other design
implications in an Object Oriented program:
All member variables in a class must be interfaces or abstracts.
All concrete class packages must connect only through interface/abstract classes packages.
No class should derive from a concrete class.
No method should override an implemented method.[5]
All variable instantiation requires the implementation of a Creational pattern as the Factory Method or the Factory pattern, or the more complex use of a Dependency Injection framework.
Dependency inversion principle
Is it possible to write ObjectScript method, which will create new class in namespace and compile it? I mean programmatically create new class and store it. If so, can I edit this class using ObjectScript later(and recompile)?
Reason: I have class structure defined in string variable and I need to add new class to namespace according this string.
Nothing is impossible. Everything in Caché can be created programmatically. And, Classes is not a execution. There are at least two ways to do it:
simple SQL Query CREATE TABLE, will create a class.
and as you already mentioned ObjectScript Code, which can do this.
All of definition of any classes defined in other classes. Which you can find in package %Dictionary.
The class itself defined in %Dictionary.ClassDefinition. Which have some properties, for defining any parts of classes. So, this is a simple code which create some class, with one property.
set clsDef=##class(%Dictionary.ClassDefinition).%New()
set clsDef.Name="package.classname"
set clsDef.Super="%Persistent"
set propDef=##class(%Dictionary.PropertyDefinition).%New()
set propDef.Name="SomeProperty"
set propDef.Type="%String"
do clsDef.Properties.Insert(propDef)
do clsDef.%Save()
And in latest versions, there is one more way for create/change class. If you have text of class as you can see it in Studio. Then, you can load it in Caché, with class %Compiler.UDL.TextServices
Yes, it is. You likely want to make use of %Dictionary.ClassDefinition and the related %Dictionary.*Definition classes (especially %Dictionary.PropertyDefinition, %Dictionary.MethodDefinition and %Dictionary.IndexDefinition) to create and/or modify your class. Provided your string contains some reasonable representation of the data, you should be able to create the class this way.
The actual class documentation is available at http://docs.intersystems.com/cache20141/csp/documatic/%25CSP.Documatic.cls?CLASSNAME=%25Dictionary.ClassDefinition
You can then compile the class by calling $system.OBJ.Compile("YourPackage.YourClass","ck").
(Note: If your string contains the exported XML definition of the class, you could also write the XML representation to a stream and then call $system.OBJ.LoadStream() to import the XML definition. I would only recommend this if you have an exported class definition to start with.)
I have an inherited class which i would like to point to from the base class. Example below
class Base
{
inherited* test;
};
class inherited: Base
{
};
the purpose of this is so that the base class (a character) contains a linked list of the inherited class (items)
ps apologies for any mistakes, i'm new to this site
It might be possible to trick the compiler into accomplishing this, but it's most certainly bad OOP design. If all you want to do is be able to store an instance of the inherited class but can treat it like the base class, then you can simply make inherited* test a base* test and it will accept pointers to either inherited or base (or any other subclass of base).
If you actually want base to treat that instance as inherited, you need to rethink your class hierarchy because you don't actually have an inheritance tree here.