Dart + Flutter new object creation - flutter

In dart I can create an object and call a method in two ways:
First one:
ClassA a = new ClassA();
a.methodA();
Second one:
new classA().methodA();
Does it have any negative effect to keep doing this? Let's say I want to call 4-5 methods from ClassA in another class, would it have any negative effects, f.x. on performance by using the second way?

That's still the exact same object creation process, it's just a simple constructor call. The only difference is that in one case you're giving the result a name (a), in the other you're not.
It's not like you're saving memory by not saving the object to a variable. In either case, a reference to your new ClassA object needs to exist somewhere, (whether explicitly named or not), otherwise how would methodA know which object to operate on?
However, there is a difference between:
ClassA a = new ClassA()
a.methodA()
a.methodB()
a.methodC()
a.methodD()
a.methodE()
versus
new ClassA().methodA()
new ClassA().methodB()
new ClassA().methodC()
new ClassA().methodD()
new ClassA().methodE()
In the first case, you're reusing the same object a (from a single constructor call) as a target of all 5 instance method calls. In the latter case, you have 5 distinct objects (from 5 separate constructor calls), each as a target of a single method call. These can obviously have very different semantics.

Related

Pass a class name as string argument to create instance

Is there any possible way to pass a class name/path as String argument to call it in code in runtime?
Im working with some legacy code and i have no way to change it globally. Creating new integration to it suggest me to create new copy of class X, rename it, and pass new instance of Y i have created manually. My mind tells me to pass Y as some kind of argument and never copy X again.
I don't quite understand why you (think that) you need to do what you are trying to do (why copy class in the first place rather than just using it? why pass classname around instead of the class itself?), but, yeah, you can instantiate classes by (fully qualified) name using reflection.
First you get a handle to the class itself:
val clazz = Class.forName("foo.bar.X")
Then, if constructor does not need any arguments, you can just do
val instance = clazz.newInstance
If you need to pass arguments to constructor, it gets a bit more complicated.
val constructor = clazz.getConstructors().find { c =>
c.getParameters().map(_.getParameterizedType) == args.map(_.getClass)
}.getOrElse (throw new Exception("No suitable constructor found")
// or if you know for sure there will be only one constructor,
// could just do clazz.getConnstructors.headOption.getOrElse(...)
val instance = constructor.newInstance(args)
Note though, that the resulting instance is of type Object (AnyRef), so there isn't much you can actually do with it without casting to some interface type your class is known to implement.
Let me just say it again: it is very likely not the best way to achieve what you are actually trying to do. If you open another question and describe your actual problem (not the solution to it you are trying to implement), you might get more helpful answers.

Class vs. Struct in Swift (copying)

I am trying to understand the concept of why struct vs. class have difference results. Why is the result the same here but different on structs:
import UIKit
class Message {
var internalText: String = "This is some text"
}
// create new instance
var firstMessage = Message()
//if I assign, its a reference to the original instance
var secondMessage = firstMessage
secondMessage.internalText += " with some more text added on."
//print both
print(firstMessage.internalText)
print(secondMessage.internalText)
output:
This is some text with some more text added on.
This is some text with some more text added on.
Now if you change the above from declaration from "class" to "struct"
struct Message {
var internalText: String = "This is some text"
}
...
output becomes:
This is some text
This is some text with some more text added on.
Why in the class declaration does it change the firstMessage object. Are they the same objects? Is this a rule that if I assign a new object from the old object? Then I would have to declare secondMessage = Message() to make it a new instance.
Thanks in advance.
In Swift, classes are reference types, whereas structs are value types. Value types are copied on variable assignment, whereas reference types are not.
More explanation
The system stores instantiated classes and structs into the memory. There are two main sections of the memory involved in the storage of data, the stack, and the heap. The stack contains the local variables introduced in the current method or function, and the heap is used as a kinda external memory, storing larger values. The program can only access variables stored in the stack, so a reference to the value in the heap should be held in the stack.
When you instantiate a class object by using something like Message(), a free space is reserved in your memory's heap and a reference to it is held in the stack. When you assign the same variable to a new one, the reference is copied and both variables will refer to the same bytes in the heap, so changing one changes another too.
When using structs, all the space is being reserved on the stack and there is no such thing as a pointer or reference, so when assigning to a new variable, all the data gets copied (in fact, the system is smart enough to only copy the necessary values which are being changed).
You can see a nice tutorial covering these subjects here.
Why in the class declaration does it change the firstMessage object. Are they the same objects?
The example you gave is a really nice one because it succinctly illustrates the difference between class and struct, and you came about this close -> <- to answering your own question, even if you didn't realize it. As the other answers have explained, class creates a reference type, which means that when you assign an instance of a class to a variable, that variable gets a reference to the object, not a copy of it. You said so yourself:
//if I assign, its a reference to the original instance
var secondMessage = firstMessage
In your example, firstMessage and secondMessage are really references to the one object that you created. This kind of thing is done all the time in object oriented languages because it's often important to know that you're dealing with a specific object and not a copy, especially if you might want to make changes to that object. But that also brings danger: if your code can get a reference to an object and change it, so can some other code in the program. Shared objects that can be changed create all kinds of headaches when you start writing multithreaded code. When you added text to secondMessage, firstMessage also changed because both variables refer to the same object.
Changing the declaration of Message to struct makes it a value type, where assignment (for example) creates a new copy of the object in question instead of a new reference to the same object. When you added text to secondMessage after changing Message to a struct, the assignment secondMessage = firstMessage created a copy of firstMessage, and you only changed that copy.
Is this a rule that if I assign a new object from the old object?
Whether your assignment creates a copy of the object or a reference to it depends, as you've shown, on whether the thing being assigned has reference semantics (class) or value semantics (struct). So you need to be aware of the difference, but most of the time you don't need to think too hard about it. If you're dealing with an object where you don't care about the object's identity and are mainly concerned with its contents (like a number, string, or array), expect that to be a struct. If you care about which object you're dealing with, like the front window or the current document, that'll be a class.
Then I would have to declare secondMessage = Message() to make it a new instance.
Right -- if Message is a class, assigning one to a new variable or passing it into a method won't create a new one. So again, are you more likely to care about which message you're dealing with, or what is in the message?
Simple answer: Classes are reference types Structs are value types.
In the class, firstMessage is set to Message() which is an instance of the whole class Message. So when secondMessage gets set to equal firstMessage, secondMessage Doesn’t make a new class again, it just makes a note of where firstMessage is at and they both can now operate it. But because they both in the same location, the internalText will be the same for both.
While with the struct, since they are value types, secondMessage copies all the values from firstMessage and creates its own independent object of type Message.
Classes are reference types, meaning that the firstMessage and secondMessage variables you defined in your first snippet stores only a reference to the class instance you created. Imagine your object is located somewhere in your memory heap with an id (for example, id0001), then both firstMessage and secondMessage stores only the id, which is id0001, so they both refer to the same object in memory.
On the other hand, structs are value types, meaning that the struct variables store unique objects directly; unlike reference types, no sharing is going on. So when you are assigning a new struct variable to a previous struct variable, the object gets copied, and the two variables store two unique objects with different memory addresses (IDs).
For more information, check out the official doc on classes and structs.
Let us understand the same concept with an example,
Suppose you have a google sheet in which you are adding some text and at a time you share that sheet to some other person for editing or deleting purpose. So when the other person do any changes you can see at a time. This concept is followed in class.
Moreover, classes are reference types because here you are passing a reference(sheet).
However, you have downloaded that google sheet and send its copy to another person so at that time you are not able to see the changes until and unless the person sends back the sheet. And this is the same concept followed in struct. A struct is value type because we are passing a copy(downloaded sheet).
We can inherit class but cannot inherit struct
Think of structs as a Microsoft Excel file. You create a copy and send it to me. When I change my copy, your copy doesn't get changed.
Classes on the other hand are more like Google Sheets. When I make changes to the file you shared with me, you can see the changes.
Instances of structs make copies and have different places in memory
Instances of classes point to the same place in memory

Executing destructor for a value class object in Matlab

I need to control destruction of a value-class object in Matlab.
The problem is as following.
I have a some program (let's call it MyProg) that during execution creates a value-class object (lets call it MyValClass). MyValClass has a handle-class object as one of its properties (lets call it MyHandClass). That handle class initiates some events that MyProg listens to.
The problem appears is MyValClass object is destroyed (usually it happens on exceptions or user termination). I guess, that because there are still listeners listening to events of MyHandClass, the MyHandClass object is not destroyed, and remains in memory.
I would like to control the destruction of MyValClass object, so that I could implicitly delete its MyHandClass property. Is it possible?
Here is a bit of background on handle vs value classes:
Objects of a value class are not "destroyed", and they do not have a destructor method. Think of value classes as behaving like the variable a when you've set a = 1. a is not "destroyed" when you type clear a, there's just no variable a any more. Value objects are just data, like 1, and they don't get destroyed.
The above is true even if the value class has a method called delete. A delete method on a value class is just like any other method. It is not a destructor, and it does not get automatically called when the variable is cleared. It only gets called when you explicitly call it.
Handle classes always, whether you implement one or not, have a method called delete, which is a destructor method (i.e. is called when the object is destroyed). If you don't implement one, they will be given a default method called delete, which does nothing other than destroy the object. If you implement a delete method, MATLAB will run that when destroying the object. But there is always a delete method that is a destructor, even if you don't implement one.
So - to your question - if you wish to control the destruction of MyValClass, you must change it to become a handle class. If it's a value class, it is not destroyed and there's nothing to control.
There are other things you might be able to do instead of directly "controlling the destruction". For example, you create an onCleanup object. This is a class that does nothing but execute a user-specified function on its destruction (it's a handle class, so it can do this). So if your code exits because of an exception or user termination, the onCleanup destructor will execute. You could, for example, put some code in there that would explicitly find references to MyHandlClass and deleted them.
Hope that helps!
The destructor for value object may be necessary, for example, if the class is responsible for accessing data from file and you want to close file when your accessor goes out of scope. There are number of reasons why you would not want such class to be a handle class (e.g. weird behavior on array of objects)
Other reason is creating existing objects counter.
My solution is to define hidden property, delete_, and assign onCleanup(#()something) object to this property. The function, provided to onCleanup would close the files, decrement object counter etc....

Why do some Matlab class methods require "apparently" unnecessary output argument

After evolving my project code for months, I've finally hit a need to define a new class. Having to romp through my previous class definitions as a refresher of the conventions, I noticed that all constructors and property setters all have an output argument, even though nothing is assigned to it, e.g.:
function o = myConstructor( arg1, arg2, ... )
function o = set.SomeProperty( o, arg1 )
I've been looking through the documentation for upward of an hour without finding the explanation for this. It doesn't look like it depends on whether a function is defined in the class definition file or in its own separate m-file.
Can anyone please explain?
The best place to start is the documentation "Comparison of Handle and Value Classes". From the very top:
A value class constructor returns an object that is associated with the variable to which it is assigned. If you reassign this variable, MATLAB® creates an independent copy of the original object. If you pass this variable to a function to modify it, the function must return the modified object as an output argument.
A handle class constructor returns a handle object that is a reference to the object created. You can assign the handle object to multiple variables or pass it to functions without causing MATLAB to make a copy of the original object. A function that modifies a handle object passed as an input argument does not need to return the object.
In other words, value classes need to return a modified object (which is a new object distinct from the original), while handle classes don't. The constructor of either class will always have to return an object, since it is actually constructing it.
Some good additional reading is "Which Kind of Class to Use", which links to a couple helpful examples of each type of class object. Looking at the DocPolynom value class example, you can see that property set methods have to return the modified object, while the dlnode handle class example only requires an output for its constructor. Note that you could still return an object from a handle class method (if desired), but it's not required.

Different field instances in class and parent/Call super constructor with method

I am trying to call the super constructor from a class using a method. The whole setup looks like this:
class Straight(hand: Hand) extends Combination(Straight.makeHandAceLowIfNeeded(hand), 5)
object Straight {
private def makeHandAceLowIfNeeded(hand: Hand): Hand = {
...
}
}
While this does compile, it has some rather odd runtime behaviour. While debugging, I noticed that the Straight instances have the "hand" property defined twice. Can somebody tell me what is going on, and what the proper way is to call the super constructor with different arguments?
In my use case, I want to call the super constructor with a modified hand in which I replaced a card compared to the original constructor argument.
Debugger screenshot with duplicate field:
.
It's a perfectly fine way to call the superclass constructor. These are two private fields and they don't conflict, though you can rename one of them to avoid confusion during debugging (or if you want to access the superclass' value from the subclass). However, the field should only be generated for a class parameter if it's used outside a constructor, and in your case it doesn't appear to be. Did you simplify the definition of Straight?