How does inheritance work in groovy for closures? Is there anything special to be aware of? My application is to extend a plugin controller, that I need to leave alone should any updates come in for it.
Closure inheritance doesn't make much sense (in the way we tend to use them anyway). A closure in practice is an instance of the Closure class. If we created subclasses of Closure then we could subclass those, but we don't. For example in controllers, we define actions as inline instances, e.g.
def list = {
...
}
These are treated like methods in that we can call list(), but that's just syntactic sugar for list.call(), since call() is an instance method of the Closure class.
In Grails 2.0 the preferred approach to creating controller actions is to use methods, although closures are still supported for backwards compatibility. One of the primary reasons for this switch is to support overloading and overriding, which isn't possible (or at least practical) with inline closures. You can define a closure instance in a subclass with the same name as a base class instance, but you can't call super.list() since it will result in a StackOverflowError
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 ...
F# does not support the definition of protected methods. Here it is explained why
F# replaces virtualmethods with abstractmethods defined in abstract classes (see here).
I was wondering if there is a way to prevent access to abstract methods from outside the derived classes at all.
Like Patryk Ćwiek, I also don't think it's possible, but here's one alternative:
From Design Patterns we know that we should favour Composition over Inheritance. In my experience, everything you can do with Inheritance, you can also do with Composition. As an example, you can always replace Template Method with a Strategy.
A Template Method is a typical use of an abstract method, but if you replace it with a Strategy, you can (sort of) hide it from clients:
type Foo(strategy : IBar) =
member this.CreateStuff() =
// 1. Do something concrete here
// 2. Use strategy for something here
// 3. Do something else concrete here
// 4. Return a result
No outside client of Foo can invoke strategy, so that accomplishes the same goal as making a member protected.
You may argue that the original creator of Foo may keep a reference to strategy, and will still be able to invoke it. That's true, but protected members aren't really completely hidden either, because you can often derive from the class in question, which enables you to invoke the protected member.
Another point is that if you separate the creator of Foo from the client of Foo, the strategy will be unavailable to the client.
Suppose I want my class to do things on attribute access. I can of course do that in setters and getters:
class Foo {
set bar (v) {
// do stuff
}
}
However, if I want to attach the same behavior to multiple attributes, I'd have to explicitly define the same setters and getters for every one of them. (The use case I have in mind is an observable, i.e. a class that knows when its attributes are being changed).
What I'd like to do is something like:
class Foo {
var bar = new AttributeWithAccessBehavior();
}
Python does this with descriptors - what is the closest thing in Dart?
AFAIK there isn't anything with getter/setter syntax that you can reuse.
You could assign a function to a field, that you can access using call notation (), but you have to be careful to call the function instead of overriding the field assignment.
A similar but more powerful alternative are classes that can emulate functions (see https://www.dartlang.org/articles/emulating-functions/)
A class that has a call method can be used like a method.
This is similar to assigned functions mentioned above but in addition you can store state information.
If you implement actual getter/setter you can of course delegate to whatever you want, but that is obviously not what you are looking for.
For the use case you mentioned, there is the observe package.
I have no idea how exactly it solves the problem, but it works quite well.
Method 1:
def funtion1(){
//Code here
}
Method 2:
def function2={
//code here
}
actually what are the difference between defining these two type of method... And which one is good ..
Controller Actions as Methods
It is now possible to define controller actions as methods instead of using closures as in previous versions of Grails.
In fact this is now the preferred way of expressing an action.
So, if you use grails > 2.*, define actions as methods instead of as clothures.
Similar questions:
https://stackoverflow.com/a/1827035/1815058
https://stackoverflow.com/a/9205312/1815058
Well, the first one if a function and the second is a closure.
A Groovy Closure is like a "code block" or a method pointer. It is a piece of code that is defined and then executed at a later point. It has some special properties like implicit variables, support for currying and support for free variables.
I think that traditional methods is what you need. You probably should use closures in some special cases, but it's really big topic for thought.
So you better read about closures here and may be here.
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_.