I've been developing Yii application. And I'm wondering if it's possible to declare in model behavior some kind of "abstract" method. I know that it impossible to use directly following declaration:
abstract class FantasticBehavior extends CActiveRecordBehavior
{
public abstract function doSomethingFantastic();
}
because we need an instanse of this class. But also I know that Yii is full magic:)
I just want to make owner class to redeclare method from the behavior in obligatory order. Sure, I can use interface in addition to behavior but ...
Sorry if I've missed something to tell or something is not clear. Just ask and I'll try to explain what I mean.
Does anybody know something about this?
Thanks in advance.
UPD
I do understand that Yii is just PHP. It doesn't extend PHP. It is superstructure over it. And it doesn't have multiple inheritance since PHP doesn't.
I do understand behavior method can't be declared using abstract keyword. That is why I have written word "abstract" in quotes. But whatever. I know how behaviors work.
My question was if I can somehow oblige model(e.g. child of CActiveRecord) to declare some method.
For example, for my purposes I can do something like this:
class FantasticBehavior extends CActiveRecordBehavior
{
public function doFantasticThings()
{
$this->owner->prepareForFantastic();
// some code
}
}
Therefore, if I attach this behavior to my model and call method doFantasticThings this method will try to call method prepareForFantastic from model(owner). And if model doesn't have method prepareForFantastic declared new exception will be thrown because non-declared method are called.
Looks like I've answered my question myself :) What do you think about this?
UPD2
Yes, I know that if we don't call "abstract" method we won't know that it is not declared. It is a "charm" of interpretable languages :) We don't know if there is any error untill the code is run. Although, it would awesome if we could know about this as earlier as possible. For example, once instance of FantasticBehavior-class is attached to the model we could throw some child of CException to show what required methods must be declared in model. To achive this we can use something like listed below:
class FantasticBehavior extends CActiveRecordBehavior
{
public function attach($owner)
{
if(!/*$owner has declared methods list this->abstractMethods*/)
{
throw new CAbstractMethodNotDecalared('....');
}
parent::attach($owner);
}
public function abstractMethods()
{
return array('prepareForFantastic');
}
}
We need to override method attach from class CBehavior and check if "abstract" methods declared. Method abstractMethods is used to get list "abstract" method.
I don't know if there is attachBehavior event exists. If so, we can use it instead of overriding attach method.
Using this idea Base class for behaviors with "abstract" methods.
What do you think about this?
Maybe in future I'll make extention for Yii and become famous and rich? :))
This might be a little confusing to explain...
No, you cannot "attach" abstract methods to your CActiveRecord model using Yii's Behaviors. All Behavior's do is some clever overrides of __call(), __get() and __set() that give the illusion of multiple inheritance. (This is a good article about it). Behaviors do not provide true "multiple inheritance" support for core language features like abstract classes and interfaces. So if you attach that Behavior and add doSomethingFantastic() to your CActiveRecord class, you will still get an error.
You can, of course, declare abstract Behaviors that other Behaviors extend. So if you created another SuperFantasticBehavior Behavior that extended FantasticBehavior and implemented doSomethingFantastic() in it, you'll be fine. But it won't force you to declare the doSomethingFantastic() method in the CActiveRecord itself.
For a little deeper understanding: The way Yii's CComponent::_call() override is structured, when you call a method it will first see if any of the behaviors have that method, and call the method on the class itself.
Behavior's seem cool at first (mixins!), but sometimes it's just better to remember that PHP is a single class inheritance language and keep is simple. ;)
UPDATE:
The difference is that if you could use abstract methods in this case you'd see a "Class must implement method" error when you try to run your code (any code), and your IDE would highlight the error. This is more of a "compile" time error (not that it really exists in an interpreted lang like PHP).
Instead you'll see a "non-declared method" error (as you mention) at runtime. But you won't see it until that method is actually called, meaning you don't get that nice early warning like an abstract definition would give you. And if that method is never called, you won't get the error, which to means it's not really "obliging" the declaration in the same way an abstract def would.
Sorry if my initial answer was starting out at too basic of a level, I just wanted to be sure there was no misunderstanding. It's an interesting discussion, and made me think more about what an abstract declaration really does. Thanks, and happy coding! :)
Cheers
Related
I am putting together a very simple ByteBuddy delegate/proxy class.
The intention is (again, very simple) to proxy a class such that any of its non-final, non-private, non-static methods and so forth get routed to equivalent methods on its proxiedInstance field as returned by its getProxiedInstance method. (There should be exceptions made for the usual suspects: equals, hashCode, wait and notify and so on.)
I've set up my proxy class using the subclass strategy. I've also defined two methods, getProxiedInstance and setProxiedInstance, along with a private field named proxiedInstance of the proper type. I've done this using the FieldAccessor.ofBeanProperty() strategy. I've omitted that here for brevity and clarity. The class does in fact contain this field and these two methods.
Then I've defined the method interception like this, statically importing the relevant ElementMatchers methods:
builder
.method(not(isFinal()).and(not(isStatic())).and(not(isPrivate()))
.and((isPublic().and(named("toString")).and(takesArguments(0)).and(returns(String.class)))
.or((not(isDeclaredBy(Object.class)).and(not(named("getProxiedInstance"))).and(not(named("setProxiedInstance"))))))
)
.intercept(MethodDelegation.toMethodReturnOf("getProxiedInstance"));
In English: not final, not static, not private, and either the public String toString() method inherited from Object (or overridden), or any other method not declared by Object.class and not named getProxiedInstance or setProxiedInstance.
Suppose I have a class like this:
public class Frob {
public String sayHello() {
return "Hello!";
}
}
When I create a proxy class for it, instantiate it, and then call toString() on the proxy, I get Hello!.
This suggests to me somehow that the recipe I've quoted above is somehow routing toString() to sayHello().
From reading the MethodDelegation javadocs, it seems that maybe sayHello on the target/delegate object is picked for delegation because it is more specific than the method invoked on the proxy (toString). I guess name matching is lower priority than that.
I think this use case I have is relatively simple. How do I best accomplish it?
The best I could do, which works, but seems perhaps a little clunky or verbose, was this:
builder = builder
.method(not(isDeclaredBy(Object.class))
.and(not(isFinal()))
.and(not(isStatic()))
.and(not(isPrivate()))
.and(not(named("getProxiedInstance")))
.and(not(named("setProxiedInstance"))))
.intercept(MethodDelegation.toMethodReturnOf("getProxiedInstance"))
.method(is(toStringMethod))
.intercept(invoke(toStringMethod).onMethodCall(invoke(named("getProxiedInstance"))));
(toStringMethod is the Method resulting from Object.class.getMethod("toString").)
I think using MethodCall is a better approach to this. MethodDelegation is meant for "catch all proxies" where you inject corresponding dispatchers into what is often a single delegate method, maybe two. Method call is also much more performance since it does not need to do the analysis but just reroutes to a method of a compatible type.
I have been getting Delphi compiler warnings about Method 'Create' hides virtual method of base.
I have reviewed several Stack Overflow links (see below), and I don't understand the logic behind this warning, and why it is considered bad coding practice. I'm hoping others can help me understand
I will include some sample code:
type
TMachine = class(TPersistent)
private
public
Horsepower : integer;
procedure Assign(Source : TMachine);
end;
...
procedure TMachine.Assign(Source : TMachine);
begin
inherited Assign(Source);
Self.Horsepower := Source.HorsePower;
end;
This causes the compiler warning.
[dcc32 Warning] Unit1.pas(21): W1010 Method 'Assign' hides virtual method of base type 'TPersistent'
I have been ignoring this warning because it didn't make any sense to me. But that got me in trouble in another way (see my other post here: Why does Delphi call incorrect constructor during dynamic object creation?) so I have decided to try to understand this better.
I know that if I use the reserved word reintroduce, the error will go away, but I have seen it repeatedly posted that this is a bad idea. As Warren P wrote here (Delphi: Method 'Create' hides virtual method of base - but it's right there), "IMHO, if you need reintroduce, your code smells horrible".
I think I understand what is meant by "hiding". As David Heffernan said here (What causes "W1010 Method '%s' hides virtual method of base type '%s'" warning?):
What is meant by hiding is that from the derived class you no longer have access to the virtual method declared in the base class. You cannot refer to it since it has the same name as the method declared in the derived class. And that latter method is the one that is visible from the derived class.
But I am somewhat confused because it seems that ancestor method is not really hidden, because a derived class can always just use the inherited keyword to call the method in the base class. So 'hidden' really means 'somewhat hidden'?
I think I also understand that using the reserved word override will prevent the compiler warning, but the procedure signature has to be the same (i.e. no newly added parameters). That I can't use that here.
What I don't understand is why hiding is something to be warned about. In my code example above, I would not want users of TMachine.Assign() to instead somehow use TPersistent.Assign(). In my extended class, I have extended needs, and therefore want to them to use the new and improved function. So it seems like hiding the older code is exactly what I want. My understanding of a virtual method is one where the correct method is called based on the actual type of an object at run time. I don't think that should have any bearing in this case.
Additional code, to be added to example code above
TAutomobile = class(TMachine)
public
NumOfDoors : integer;
constructor Create(NumOfDoors, AHorsepower : integer);
end;
...
constructor TAutomobile.Create(ANumOfDoors, AHorsepower : integer);
begin
Inherited Create(AHorsepower);
NumOfDoors := ANumOfDoors;
end;
This adds new compiler warning message: [dcc32 Warning] Unit1.pas(27): W1010 Method 'Create' hides virtual method of base type 'TMachine'
I especially don't understand problems that arise with using new constructors with additional parameters. In this post (SerialForms.pas(17): W1010 Method 'Create' hides virtual method of base type 'TComponent'), the wisdom seems to be that a constructor with a different name should be introduced, e.g. CreateWithSize. This would seem to allow users to pick and choose which constructor they want to use.
And if they choose the the old constructor the extended class might be missing some needed information for creation. But if, instead, I 'hide' the prior constructor, it is somehow bad programming. Marjan Venema wrote about reintroduce in this same link: Reintroduce breaks polymorphism. Which means that you can no longer use meta classes (TxxxClass = class of Tyyy) to instantiate your TComponent descendant as its Create won't be called. I don't understand this at all.
Perhaps I need to understand polymorphism better. Tony Stark wrote in this link (What is polymorphism, what is it for, and how is it used?) that polymorphism is: "the concept of object oriented programming.The ability of different objects to respond, each in its own way, to identical messages is called polymorphism." So am I presenting a different interface, i.e. no longer an identical message, and thus this breaks polymorphism?
What am I missing? In summary, isn't hiding base code a good thing in my examples?
The danger here is that you might call Assign on a base class reference. Because you did not use override then your derived class method is not called. You have thus subverted polymorphism.
By the principle of least surprise you should use override here, or give your derived class method a different name. The latter option is simple. The former looks like this:
type
TMachine = class(TPersistent)
public
Horsepower : integer;
procedure Assign(Source : TPersistent); override;
end;
...
procedure TMachine.Assign(Source : TPersistent);
begin
if Source is TMachine then begin
Horsepower := TMachine(Source).Horsepower;
end else begin
inherited Assign(Source);
end;
end;
This allows your class to co-operate with the polymorphic design of TPersistent. Without using override that would not be possible.
Your next example, with virtual constructors is similar. The entire point of making a constructor virtual is so that you can create instances without knowing their type until runtime. The canonical example is the streaming framework, the framework that processes .dfm/.fmx files and creates objects and sets their properties.
That streaming framework relies on the virtual constructor of TComponent:
constructor Create(AOwner: TComponent); virtual;
If you want a component to work with the streaming framework, you must override this constructor. If you hide it, then the streaming framework cannot find your constructor.
Consider how the streaming framework instantiates components. It does not know about all the component classes it needs to work with. It cannot, for instance consider third party code, the code you write. The Delphi RTL cannot know about types defined there. The streaming framework instantiates components like this:
type
TComponentClass = class of TComponent;
var
ClassName: string;
ClassType: TComponentClass;
NewComponent: TComponent;
....
ClassName := ...; // read class name from .dfm/.fmx file
ClassType := GetClass(ClassName); // a reference to the class to be instantiated
NewComponent := ClassType.Create(...); // instantiate the component
The ClassType variable holds a meta class. This allows us to represent a type which is not known until runtime. We need the call to Create to be dispatched polymorphically so that the code in the component's constructor is executed. Unless you use override when declaring that constructor, it won't be.
Really, all of this boils down to polymorphism. If your understanding of polymorphism is not firm, as you suggest, then you will struggle to appreciate any of this. I think your next move is to get a better grip on what polymorphism is.
There are different benefits for using inheritance. In your examples you do it to avoid coding the same things again and again. So if TMachine has Horsepower field already and some methods and now you need more advanced TAutomobile with NumOfDoors, you make it TMachine descendant.
If you now always treat them differently, i.e in some code you use exactly TMachine (machine := TMachine.Create(...), machine.Assign(AnotherMachine) etc. ) and in another code you use TAutomobile and they never get mixed
then you're all right, you can ignore these warnings or 'mute' them with reintroduce.
But there is usually another aspect of inheritance: keeping uniform interface, or as it's sometimes called: 'contract'. Separating interface from implementation.
For example, form is able to free all the objects which belong to it, no matter what these objects are, that's because of Destroy method which gets overrided. Form doesn't care about your implementation, but it knows: to free the object it just have to call Destroy, that easy. If you don't override Destroy, that's extremely bad: no way TForm will call you as TMachine.Destroy. It'll call you as TObject.Destroy, but it won't lead to your TMachine.Destroy, so you get a memory leak. In most cases when some method wasn't overriden it's just because programmer forgot to do it, thus a warning: it's very helpful one. If programmer didn't forget it but that was intentionally, reintroduce keyword is used. This way programmer tells: "Yes, I know what I do, this is intentionally, don't disturb me!"
TPersistent.Assign is another procedure which is frequently called from base class, not derived (that is: we don't want to pay attention to implementation, we just want to copy an object, whatever it is). For example, TMemo has Lines: TStrings, but TStrings is an abstract class, while the actual implementation is TStringList. So, when you write Memo1.Lines.Assign(Memo2.Lines), the TStrings.Assign method is used. It may implement this assign through another methods: clear itself first and then add line after line. Some TStrings descendant may want to speed-up process by some block copy of data. Of course it has to use exactly Assign(Source: TPersistent) method and override it, otherwise it is never called (inherited is called instead).
Classic implementation of Assign is like this:
procedure TMachine.Assign(Source : TPersistent);
begin
if Source is TMachine then
Horsepower := TMachine(Source).Horsepower
else inherited Assign(Source);
end;
That's the case when inherited shouldn't be called first thing. Here it is 'the last resort': it's called last if nothing else helped. It makes one final try: if your class don't know how to assign, maybe that Source knows how to AssignTo your class?
For example, TBitmap was coded long, long ago. After that TPngImage was developed to work with, well, PNG. You want to put PNG into bitmap and write: Bitmap.Assign(PngImage). No way TBitmap may know how to deal with PNG: it didn't exist back then! But TPngImage writer knew that may happen and implemented AssignTo method which is able to convert it to bitmap. So TBitmap as the last straw calls TPersistent.Assign method and that in turn calls TPngImage.AssignTo and that works like a charm.
Is this side of inheritance needed in your program is up to you. If there is again lots of dublicating code (the one which deals with machines and another with automobiles) or there are lots of conditions, then something is wrong and some good polymorphism might be of help.
I need to have a static constructor. I was always wondering why there is no support for this functionality.
I need to run a function once when the class is loaded, currently the way I've seen it done is just include a bunch of code in the file after the class declaration. That kinda works until you need to modify protected or private members of the class, then you would need to define a function on the class itself then call it from down there which all gets the job done but seems hacky to me.
What I went ahead and did was in my loader class after the include statement I added this little bit:
if (method_exists($class, 'onLoad')) {
$class::onLoad();
}
I am having my doubts about that, though, because there may be quite a number of classes included in a request. And this is on each request, so eventually this may add up to some processor time - which leads me to the question I want to ask, since not many classes will even have an onLoad method:
Would you consider this to be a reasonable addition to my framework?
EDIT: Regarding the suggested possible duplicate question - I am not asking for singleton this is not a static class it can be instantiated freely.
There's no reason your "SomeClass.class.php" file can't look like this:
class SomeClass {
public static function onLoad() {
// ...
}
// ...
}
SomeClass::onLoad();
Whether or not this is a Good Idea is up for debate, but I don't see anything overly wrong with initialisation code added in this way to the class file.
That is, when child.update() is called, should the instance of a derived class implicity call all his superclasses's update() on itself before?
There's no good answer (in the languages I know). Sometimes you want to replace the super method. Sometimes you want to slip something in before it executes, and sometimes after. It does seem the extending class needs to know more about the details of the class it's overriding than it should have to. (This gets awkward with closed-source systems.) Also, the base class really wants to control the behaviour of the calling class sometimes, to force the super method to be called, which isn't right either. I think the best thing is for the super class to document its overridable methods as best it can so the overriding programmer can guess what to do.
The closest I've come to handing this properly and rightly is to make the target method so it cannot be overridden, then have it call a method or methods that do nothing but that can be overridden. Then the overriding class can override whichever methods interest it without being able to undermine the superclass.
The ultimate programming language will have a fool-proof solution to this problem.
No. Someone might need to override update() and wants to prevent exactly any call from a parent. In that case in implicit call would not only hurt performance it also might do things you don't want to.
It really depends on what the superclass / base-class function does. Sometimes I call it first, sometimes I call it last. Sometimes I call it conditionally, and once in a while, I don't call it at all.
Many times (this is coming from a C# background), the base class function just raises an event, and the child class overrides that method to get the event-like functionality. There are cases where the child doesn't want that event to be raised:
class Base {
public event EventHandler UnhandledError;
protected virtual void OnUnhandledError(Error error) {
if (UnhandledError != null)
UnhandledError(this, EventArgs.Empty);
}
}
class Derived : Base {
protected override void OnUnhandledError(Error error) {
if (HandleError(error))
return; // We took care of it. Don't raise the event.
// We couldn't handle it. Let the base class raise the event.
base.OnUnhandledError(error);
}
}
You are not wrapping a class into another, you are inheriting from a super-class.
Overriding super-class methods you should call super.method() only when you need to extend behavior of parent method().
I find myself creating a significant number of wrapper classes, purely because I want to mock out the behaviour of
Classes that don't lend themselves well to the RhinoMocks isolation model (for instance like DirectoryInfo or WindowsIdentity)
Native Win API methods (I normally collect all the methods I need into a single class and wrap the native calls as a class method)
I then find myself appending the class that is wrapped with a 'W' (to indicate that it's a wrapper) and so I end up with DirectoryInfoW (as opposed to DirectoryInfoWrapper which seems rather verbose). Similarly, I end up with wrapped native methods called NativeMethods.DuplicateTokenW.
What would be a good rule of thumb to follow when naming wrapper classes?
Naming conventions are whatever works for the team that you're working with. As long as everyone's ok with a particular convention, then it's ok.
I tend to prefer the more verbose version though, i.e. DirectoryInfoWrapper, rather than having a single letter that doesn't explain anything to anyone who's not familiar with the code. But that's just me.
I'll agree with aberrant80 , if everyone agrees with the convention you are using, then it'll work.
I personally prefer using names that are shorter and descriptive to the class's purpose. At least at the interface level. If you're using a mock framework, then IDirectory or IDirectoryInfo would be a decent set of names, while DirectoryInfoW or DirectoryInfoWrapper would be an interface implementer.
A better example might be wrapping an HttpRequest; define an IRequest to state 'this is what is important to my application', then Request, HttpRequestWrapper, Request, etc would be implementers.
So, to summarize, try and use descriptive, non-overly-verbose interface names.
Just as a side note, I found a more aesthetically pleasing (well, to me) way of wrapping native method calls:
public class NativeMethods
{
// made virtual so that it can be mocked - I don't really want
// an interface for this class!
public virtual bool RevertToSelf()
{
return WinApi.RevertToSelf();
}
...
private static class WinApi
{
[DllImport("advapi32.dll")]
public static extern bool RevertToSelf();
...
}
}
i.e. avoid name collision by encapsulating native method calls in a private nested class.
No 'good' solution to the wrapper class naming issue though, I'd probably go with aberrant80's suggestion and explicitly call my wrappers wrappers.
If you are using C++, you can use namespaces and then just re-use the same class name. For example:
namespace WrapperNamespace
{
class MyClass {...};
}
namespace InternalNamespace
{
class MyClass {...};
}