In an ideal OO design, should inherited objects implicity call super() on each of his methods? - oop

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().

Related

Why does ByteBuddy route method delegation to the "wrong" method in this scenario?

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.

How to assign value to an implementation of an interface, but the interface doesn't have setter method?

I have an interface: Show, and i have the implementation class calls ShowImpl, and also i have a implementation class calls ManageShowImpl. I have completed all the methods inside ManageShowImpl. Now i am doing Junit testing. The method i defined in the ManageShowImpl, for example: addShows(Show... shows), now i want to assign values to the show array: Show[], but in the interface: Show, i don't have setter method(which is not supposed inside interface), can some expert tell me how can i add the value to Show[].
If I understood correctly your issue, I think you can simply set values in your constructor:
public class ShowImpl implements Show{
private Show[] shows;
public ShowImpl(Show... shows){
this.shows = shows;
}
#Override
public void someInterfaceMethod(){
// ...
}
}
(I am not a junit expert, or even a beginner, but maybe I can inspire a few to answer. I have done a fair amount of testing.)
Given a class with a constructor, you can always create an instance, fill it with whatever data you want, and test it any way you want. Interfaces are a lot more limited. Testing aside, this is a very good thing. It limits the damage someone can do if they get hold of an interface implementation; it safely encapulates the data. But you cannot test an interface in isolation. You need to create an instance of an implementing class first. At that point you should fill in your array. Then pass it to a test method as an interface instance to test the interface.

"Abstract" methods in Yii Behaviors

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

Should a newly created class "start" itself during construction?

Context: .NET, C#, but the question is about OOP in general.
When I write a class that should act as a "service", like a socket listener, or a timer, I see two approaches when it comes to coding it:
Create a constructor, and inside the constructor, immediately start the background task. For instance:
public class MyTimer
{
private readonly TimeSpan interval;
public MyTimer(TimeSpan interval)
{
this.interval = interval;
StartTicking();
}
private void StartTicking()
{
// do the ticking logic
}
}
Create a constructor that accepts the class' settings, and add an explicit method for starting up:
public class MyTimer
{
private readonly TimeSpan interval;
public MyTimer(TimeSpan interval)
{
this.interval = interval;
}
public void StartTicking()
{
// do the ticking logic
}
}
I tend to think that the second approach is better:
A. The constructor is used only for creating a valid instance, keeping it minimal and clean.
B. The developer who actually uses my class is less astonished.
C. The hardware resources are not overused, since the "service" class does not immediately use them.
What do you think? Is it only a matter of coding style, or is it more than that?
Keep your constructor minimal, and require the calling code to call a specific function in order to do anything but the most simple initialization. This is what the Stopwatch class does in .NET, for instance.
Besides avoiding surprises for the person invoking the constructor, this also allows you to make better use of Dependency Injection (i.e. having your class injected into the constructor of a class that needs it, but which doesn't want to use it right way).
I've also found that certain types of bugs are more difficult to catch when they occur in constructors than when they are in some other method.
Don't start running in your constructor.
Users of your API won't expect that, and it makes your class harder to use
From an exception handling standpoint, you want to be able to report an error that happens when constructing an object, separately from an error that happens during execution.
It prevents sharing instances of your object, if you ever wanted to do something like a static factory singleton pattern.
I would second StriplingWarrior's point that there are many good reasons, like dependency injection, where object creation needs to happen first so that some other class can run it later.
Nearly every service-type class that I've seen exposes methods to start and stop it. If it is auto-starting, it is usually very explicitly so (the class name might be MyAutostartingTimer or something..)

Whats the correct way of creating objects?

For example, i see myself doing things like this latley, when i create an object, if it has a logical path of tasks then
public Class Link
{
public Link(String value)
{
callMethodA(value)
}
public void callMethodA(String data)
{
CallMethodB(doSomethingWithValue)
}
...
...
}
Here you can see, as soon as you instantiate the object, yours tasks get completed automatically.
The other way i can see of doing it is by creating an object, that doesnt link via the constructor, then calling methods individually.
Which was is right and why?
Thanks
Either way we can implement.
Recommended way is to do tasks like initialization stuffs within the constructor and rest of the things can be implemented by way of calling the method with its reference object.
for such scenario one should go for Factory pattern
for example:
Calendar.getInstance();
Constructor should do ALL that requires to make an object complete. That is, if without calling method callMethodA , if the object is incomplete then callMethodA must be called from constructor itself. If the callMethodA is optional API then the user of class Link can call the method when he wants.
I prefer second method. Constructor's job is to initialize the class members. Any modification to change the state of the object needs to be done seperately by member functions.
As long as the objects that are created do not have nothing in common the current way of creating them is fine. Factory Method or Abstract Factory pattern makes sense when there's similarity between created objects. They'll help you isolate the parts that are always the same and moving parts that define differences between objects.
It depends on business logic involved. Both ways are practical. If you want to simply initiate instance specific data, then better to do it in constructor method itself which is more logical and simple. It will save calling other methods explicitly unnecessarily. If instanciating your data is based on certain buisiness condition, then it is good to have main functionality in separate method and then conditionally call it from constructor. This is easy to manage in such scenario.
A constructor is meant to bring the object in the correct initial state. So use it for that purpose. As a general rule of thumb, only use a constructor to set properties. Basic calculations are also ok.
I would not recommend calling very time consuming methods, or methods that are likely to throw exceptions (like calling a webservice or access a file).
When you need to do very special things to bring the object in its initial state, make the constructor private and use a static method to create the object.