When a class that contains code is instantiated, is the code is the class shared automatically by other instantiations of that same class? Eg. The data in the class that is instantiated may be minimal; however the code could be very significant. If the code is not "automatically" shared, is there a way to achieve that other than separating the code from the class data?
Sure.
Classes have the state and the behavior.
The state is encoded in member variables of the class. Each instance has its own copy of variables, thus its own state.
The behavior is specified by the methods implemented in the class ('methods' here stand for all static, non-static methods, setters and getters). Implementation is shared by all instances of the class, so all instances behave the same, but actual results and side-effects depend on instance state, obviously.
Related
I am passing the first object of a List myList[] from Class A to a stateful class B that is a separate page in my application. The passed object is therefore created as immutable since flutter prefers immutable classes and immutable classes need const constructors, variables in which must be final. In the B class, I later call a function that modifies the object from the List, and objects in a list aren't immutable. But since I have already passed the object, I can't see the updated value. I solved this issue by making: the value - non-final, the constructor - not const, and therefore the class - mutable. Another way I could solve it is to just use global variables instead.
My question is - Is there a way to reinstantiate class B? I.e., go to class A, navigate to page B by passing the (now updated) first object of List myList[] ?
Perhaps you could try using a State manager like Provider. From my understanding, you're trying to share variables across different widgets. Using a state management library seems to do exactly what you want.
We have an app that makes fairly extensive use of TIniFile. In the past we created our own descendant class, let's call it TMyIniFile, that overrides WriteString. We create one instance of this that the entire app uses. That instance is passed all around through properties and parameters, but the type of all of these is still TIniFile, since that is what it was originally. This seems to work, calling our overridden method through polymorphism, even though all the variable types are still TIniFile. This seems to be proper since we descend from TIniFile.
Now we are making some changes where we want to switch TMyIniFile to descend from TMemIniFile instead of TIniFile. Those are both descendants of TCustomIniFile. We'll also probably be overriding some more methods. I'm inclined to leave all the declarations as TIniFile even though technically our class is no longer a descendant of it, just to avoid having to change a lot of source files if I don't need to.
In every tutorial example of polymorphism, the variable is declared as the base class, and an instance is created of the descendant class and assigned to the variable of the base class. So I assume this is the "right" way to do it. What I'm looking at doing now will end up having the variables declared as, what I guess you'd call a "sibling" class, so this "seems wrong". Is this a bad thing to do? Am I asking for trouble, or does polymorphism actually allow for this sort of thing?
TIniFile and TMemIniFile are distinct classes that do not derive from each other, so you simply cannot create a TMemIniFile object and assign it to a TIniFile variable, and vice versa. The compiler won't let you do that. And using a type-cast to force it will be dangerous.
You will just have to update the rest of your code to change all of the TIniFile declarations to TCustomIniFile instead, which is the common ancestor for both classes. That is the "correct" thing to do.
The compiler is your friend - why would you lie to it by using the wrong type ... and if you do lie to it why would you expect it to know what you want it to do?
You should use a base class that you derive from, like TCustomIniFile. I would expect compile issues if you are trying to make assignments which are known at compile time to be wrong.
The different classes have different signatures so the compiler needs to know which class it is using to call the correct method or access the correct property. With virtual methods the different classes setup their own implementation of those methods so that the correct one is called - so using a pointer to a base type when you call the virtual method it calls that method in the derived type because it is in the class vtable.
So if the code does compile, it's very likely that the compiler will not be doing the right thing ...
What happens to a procedure when it is declared with the keyword dynamic?
And what is the effect of declaring it with the keyword static?
This question can be answered by reading the documentation.
The dynamic keyword introduces a method that can be overridden polymorphically. Semantically it is interchangeable with virtual, but the is implemented in a different manner. Read about it here: http://docwiki.embarcadero.com/RADStudio/en/Methods#Virtual_and_Dynamic_Methods
To make a method virtual or dynamic, include the virtual or dynamic
directive in its declaration. Virtual and dynamic methods, unlike
static methods, can be overridden in descendent classes. When an
overridden method is called, the actual (run-time) type of the class
or object used in the method call--not the declared type of the
variable--determines which implementation to activate.
To override a method, redeclare it with the override directive. An
override declaration must match the ancestor declaration in the order
and type of its parameters and in its result type (if any).
...
In Delphi for Win32, virtual and dynamic methods are semantically
equivalent. However, they differ in the implementation of method-call
dispatching at run time: virtual methods optimize for speed, while
dynamic methods optimize for code size.
In general, virtual methods are the most efficient way to implement
polymorphic behavior. Dynamic methods are useful when a base class
declares many overridable methods that are inherited by many
descendent classes in an application, but only occasionally
overridden.
Class static methods are like class methods in that they are invoked on the class rather than an instance. The difference between class static and class methods is that class methods are passed a Self pointer that contains the class, and class static methods are not. This means that class methods can be polymorphic and class static methods cannot. Read about it here: http://docwiki.embarcadero.com/RADStudio/en/Methods#Class_Static_Methods
Like class methods, class static methods can be accessed without an object reference. Unlike ordinary class methods, class static methods have no Self parameter at all. They also cannot access any instance members. (They still have access to class fields, class properties, and class methods.) Also unlike class methods, class static methods cannot be declared virtual.
With all due respect, I refer you to this question: How can I search for Delphi documentation?
I need to do some custom data binding and I tried to use the #BindUsing annotation on a class (http://grails.org/doc/latest/api/org/grails/databinding/BindUsing.html), however, it's being ignored. I am under the assumption that since the annotation is used on the class that would mean that every time a data binding happens and that class is involved, the BindingHelper class would be used, but it's never actually called. Is there something that I'm missing or doing wrong?
Here's the class definition where UserBinding is a class that implements the BindingHelper interface:
#BindUsing(UserBinding)
class User extends SomeOtherClass
{
...
Also am I correct in understanding that basically creating a ValueConverter and using #BindUsing on a class accomplish the same thing?
BindUsing on a class is not used often and there seems to be a bug reported around that already. [From the link] The problem could be that there are multiple request parameters with the same name it might be using the helper only for the first one.
Using a property level #BindUsing annotation should be simpler to implement and is less likely to fail (even when there are multiple entries in the params map with the same name).
I have my main form. Form_Main
It creates two instances of two classes.
Candle_Data : TCandle_Data;
Indicator_2700 : TIndicator_2700;
In order for Indicator_2700 to properly compute its values it must have access to the candle data in the obect Candle_Data from inside one of its methods. Thus how can Indicator_2700 access data inside Candle_Data? Does Form_Main have to pass it as a argument at Constructor time?
Both Class declarations are in their own unit file.
You could use any of the following (non-exhaustive) methods:
Pass the object reference as a parameter to any methods that need it. Of course you need to get hold of Candle_Data so the suitability of this approach really depends who the caller is.
Pass the Candle_Data object reference to the constructor of the other object and then store it in a private member field.
Make the object reference a public property of the single instance of the main form and access it that way.
We don't really have enough information to advise you which is best but the starting point is always to prefer parameters and local variables over global state.
TIndicator_2700 could have a property to link it to the instance of TCandle_Data that is relevant to its own instance or you should supply it as an argument to the method that needs to access the data.
You could certainly pass the TCandle_Data instance into the constructor of Indicator_2700, and store a reference within the resulting instance until you needed it.
Both class declarations are in their own unit file.
That suggests that both have nothing to do with the other. But still you want one to have knowledge about the other. It sounds like a little design mixup, but that doesn't need to be the case.
There are multiple solutions, here are three of them, each with its own purpose:
Place both classes in the same unit, only if both classes have a common theme/subject (e.g. TCar and TAirplane in the unit Transport),
Use one unit in the other unit, only if both units represent different subjects, but one may depend on the other (e.g. unit Transport uses unit Fuel: TCar needs TDiesel, but TDiesel doesn't need a TCar). This only works one-way. Delphi prevents using in both ways with a compiler error: "Circular unit reference to 'Fuel'". The only workaround is to use the second unit in the implementation section, but that usually is considered a big nono.
Declare a new base-class in a new unit, only if the base-class has a common subject, but the final descendants do not (e.g. TFuel is used by all transportation classes like TCar, TAirplane and THorse, but TFood (a descendant of TFuel) is only used by THorse and TPerson).
As for how to link both classes together, see the already given answers.