I have a class A which B inherits from. The inheritance includes a bunch of parameters, and they should all be initialized to some default values in both cases (whether we create an A object or a B object). I decided to put the initialization into the constructor of A, since the creation of B should create an A first. However, this doesn't seem to be happening automatically, and I was unable to figure out how to call the super constructor manually. Can some one help me out?
You already found the solution, but here are some more notes that might help you to understand your question better:
super is similar to self, they both represent the receiver of the message.
self starts the lookup of the following message in the receiver of the message.
super starts the lookup of the following message in the superclass where the implementing method is defined in.
self and super are not messages but implicit variables, therefor you cannot find them in the message finder.
OK never mind... You use the word super.
I guess that explains why there's no list of classes that define it in the method finder.
Related
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 ...
I have a single table inheritance mechanism and a controller method that creates objects based on a text type.
From my controller:
tile = Object.const_get(tile_data[:type]).new(params_from_tile(tile_data))
tile.save
inside my model base class I have several before create hooks:
before_create :set_handle, :upload
It appears none of my hooks are firing, does it have something to do with my use of Object.const_get to create my objects?
Edit: I've managed to work around this by not using Object.const_get().new now I'm just invoking my Tile.new directly, and there does not appear to be any negative repercussions, so yeah.
Theoretically, there is no difference how you access the class, both of these would behave exactly same:
Tile.new(params_from_tile(tile_data))
and
Object.const_get("Tile").new(params_from_tile(tile_data))
Your seeing bad behaviour may have to do with some other small thing missing.
May be tile_data[:type] in your example pointing to something else, did you make sure Tile record gets saved without callback. Can you try with Object.const_get("Tile") and see what happens.
I've changed this to invoke the baseclass directly:
Tile.new(params_from_tile(tile_data))
And now my hooks are being called as expected, so I'm not sure why this behaves this way, and would appreciate a better answer from someone who knows, but it appears that the answer is that using Object.const_get().new to create an object skips all hooks. On a side note, Invoking create on the baseclass with just a type attribute will still cause subclass hooks to fire, So thats nice.
After seeing the video here, i got confused about the use of final keyword.
Here below is an example image from the video
Here there are two classes Pet as parent class and Dog as child class, and we have function implementation of makeNoise(p) which takes Pet instance as parameter. But behind the scene compiler inserts few more lines to this method for checking class.
Since makeNoise(p) takes parameter as Pet instance, compiler should directly call the property "name" from the Pet class, as the method parameter is for this class.
Why would compiler be worried about the overriding the property in child class, because the parameter is a Pet instance and compiler knows it. isn't it?
My question may looks silly but if someone can explain it more clearly, i would appreciate it.
The parameter of makeNoise(p: Pet) must be a Pet, but it does not to be an immediate instance of Pet itself. Since Dog is a subclass of Pet, it is also a Pet. Therefore, in Swift it is perfectly valid for someone to pass a Dog instance into makeNoise, in which case the overridden version of noise will be called. Also, this dog may have chosen a different value for name.
Dynamic Type
This is called the 'dynamic type' of p. The compile-time type of p is Pet, but the compiler must account for the fact that the run-time type of p might be a Pet subclass that overrides something. This is called the 'dynamic type' of p. In Swift 1 and 2, which were in use at the time of WWDC 2015, use the .dynamicType syntax on an object to determine its runtime type. Swift 3 uses the type(of: object) global function. This is not something you'll need very often, but it demonstrates how the compiler allows subclasses to act as their parent and still override things.
final
final tells the compiler that either the class will not be subclassed, or the property or method will not be overridden. This way it won't need to check for overrides.
Changes in Swift 3
This year's WWDC 2016 session on Swift performance did not mention the final keyword once, if I remember correctly, however. While it is still available in Swift 3 and serves the same purpose, there are new ways to prevent subclassing and overriding. This is via Access Control. Swift 3 introduces the open keyword as distinct from public.
public – The object, property, method, etc. is accessible by anyone inside or outside the module
open – The class or method is not only accessible by anyone, but may also be subclassed (in the case of classes) or overridden (in the case of methods).
I am not sure if this, like final, communicates to the Swift compiler that it does not need to do its extra type checking.
I'm creating a wrapper class for an API because my application will need to call it with different credentials at different times. I started off passing the wrapper a method and arguments and then doing (basically) this when calling it
call
set_credentials
TheAPI::Thing.send(method, args)
ensure
reset_credentials_to_default
end
HOWEVER, I realized that a challenge here is if I need to chain methods; this way I can only call one at a time; so for example I wouldn't be able to to TheAPI::Thing.find(id).delete. (At least, not without re-calling the credentials setter, which is undesirable since I have to fetch a token).
Is there a way using ruby to collect the methods/args being chained onto an object? Or would I simply have to pass in some ugly ordered set of things?
EDIT: Surely activerecord's query builder does something like this, collecting the chained methods before returning, and then after they're all collected, ensuring that as a final step the query is built, called, and returned?
the way to do this is to define a proxy object and to pass that around instead of the actual thing.
In the object itself, hold a reference to the Thing and override method_missing: http://ruby-doc.org/core-2.1.0/BasicObject.html#method-i-method_missing
In the method missing do the thing you are doing today. In a nutshell this is what ActiveRecord is doing.
As far as chaining things, I don't believe it would be a problem as methods that can be chained usually return references to self. When you call the 2nd method in the chain, you actually have done the work for the first one and have an object that has the 2nd method in the chain. The only trick you need to pay attention to is that you want to return a reference to the proxy class that encapsulates the thing instead of the actual return of the thing if you want the chaining to succeed.
Give it a shot and ping me if you run into trouble and I can spin up a fully working example.
I am dealing with a large codebase that has a lot of classes and a lot of abstract methods on these classes. I am interested in peoples opinions about what I should do in the following situation.
If I have a class Parent-A with an abstract method. There will only be 2 children. If Child-B implements AbstractMethodA but Child-B does not as it doesnt apply.
Should I
Remove the abstract keyword from parent and use virtual or dynamic?
Provide a empty implementation of the method.
Provide an implementation that raises an error if called.
Ignore the warning.
Edit: Thanks for all the answers. It confirmed my suspicion that this shouldn't happen. After further investigation it turns out the methods weren't used at all so I have removed them entirely.
If AbstractMethodA does not apply to Child-B, then Child-B should not be inheriting from Parent-A.
Or to take the contrapositive, if Child-B inherits from Parent-A, and AbstractMethodA does not apply to the child, then it should not be in the parent either.
By putting a method in Parent-A, you are saying that the method applies to Parent-A and all its children. That's what inheritance means, and if you use it to mean something different, you will end up in a serious dispute with your compiler.
[Edit - that said, Mladen Prajdic's answer is fine if the method does apply, but should do nothing for one or more of the classes involved. A method which does nothing is IMO not the same thing as a method which is not applicable, but maybe we don't mean the same thing by "doesn't apply"]
Another technique is to implement the method in Child-B anyway, but have it do something drastic like always returning failure, or throw an exception, or something. It works, but should be regarded as a bit of a bodge rather than a clean design, since it means that callers need to know that the thing they have that they're treating as Parent-A is really a child-B and hence they shouldn't call AbstractMethodA. Basically you've discarded polymorphism, which is the main benefit of OO inheritance. Personally I prefer doing it this way over having an exception-throwing implementation in the base class, because then a child class can't "accidentally" behave badly by "forgetting" to implement the method at all. It has to implement it, and if it implements it to not work then it does so explicitly. A bad situation should be noisy.
If implementation in descendants is not mandatory then you should go for 1+2 (i.e. empty virtual method in ancestor)
I think that, generally speaking, you shouldn't inherit from the abstract class if you are unable to implement all of the abstract methods in the first place, but I understand that there are some situations where it still makes senseto do that, (see the Stream class and its implementations).
I think you should just create implementations of these abstract methods that throw a NotImplementedException.
You can also try using ObsoleteAttribute so that calling that particular method would be a compile time error (on top of throwing NotImplementedException of course). Note that ObsoleteAttribute is not quite meant to be used for this, but I guess if you use a meaningful error message with comments, it's alright.
Obligatory code example:
[Obsolete("This class does not implement this method", true)]
public override string MyReallyImportantMethod()
{
throw new NotImplementedException("This class does not implement this method.");
}
make it virtual empty in base class and override it in children.
You could use interfaces. Then Child-A and Child-B can both implement different methods and still inherit from Parent-A. Interfaces work like abstract methods in that they force the class to implement them.
If some subclasses (B1, B2, ...) of A are used for a different subset of its methods than others (C1, C2, ...), one might say that A can be split in B and C.
I don't know Delphi too well (not at all :) ), but I thought that just like e.g. in Java and COM, a class can 'implement' multiple interfaces. In C++ this can only be achieved by multiply inheriting abstract classes.
More concrete: I would create two abstract classes (with abstract methods), and change the inheritance tree.
If that's not possible, a workaround could be an "Adapter": an intermediate class A_nonB_ with all B methods implemented empty (and yielding a warning on calling them), and A_nonC_. Then change the inheritance tree to solve your problem: B1, B2, ... inherit from A_nonC_ and C1, C2,... inherit from A_NonB_.