(DISCLAIMER: This is NOT a question about understanding the difference between abstract classes and interfaces. If you didn't get that, please read the title again. I am well-versed in the difference between a contract and a half-implemented subsystem.)
Let's take Java as just one example. It seems that there is little need for a distinct keyword interface, when from my point of view as a developer, the compiler spits out exactly the same thing, which in human-speak is, "You cannot utilise this until you derive (via implements or extends) a new class which implements its methods". Simple.
But there is one scenario which may prevent conflation of these two: When we need to implement more than one interface, since Java does not allow multiple inheritance (for classes). Surely it would be trivial to build the language in such a way that the compiler recognises when there are any method bodies or declared variables, and subsequently disallows multi-implements/extends where appropriate? Does order of precedence then present a problem?
Is this the only reason we have this syntactic differentiation?
P.S. One reason I ask this question is that this scenario can present quite a challenge in understanding for new OO programmers, and I think that handling this in a more streamlined fashion, at the language level, would greatly assist in more quickly grasping the conceptual differences.
Surely it would be trivial to build the language in such a way that the compiler recognises when there are any method bodies or declared variables, and subsequently disallows multi-implements/extends where appropriate?
Let's say you did do that. So your language lets you do this:
class Foo extends A, B, C {
}
And it doesn't complain as long as every method in B and C is abstract. Fine and dandy.
Now let's say that you didn't create B. It's in some other package someone else wrote. They don't know anything about your class Foo. When they made B, everything in it was abstract, but that was just a coincidence: they didn't happen to have anything concrete to put in there yet.
Later, they decide to add another method to B, which is concrete. Now, without realizing it, they've broken your class Foo.
One argument for having an explicit interface construct is that it makes the intent of the author of B clear to someone consuming it.
In general, I think your question is a good one. The language I work on, Dart, is actually close to what you're talking about: It has an explicit interface syntax now, but it's being removed in favor of pure abstract classes.
Related
I started writing some code for a 2D game, created a class "objets" trying to keep it as generic as possible. I have a few methods and attributes that are common to every kind of element (buldings, ppl, interface buttons, etc) like (w, h, x, y ...you know) but most of them only make sense when applied to and specific type of item.
So I would have to inherit a new class for every type of actor in the game?
Just wondering if this is a common practice, or maybe i should manage it in a different way.
Thanks in advance.
If you're introducing behaviour then subclass, however if the difference is attribute based then don't e.g.
Animal (has .colour and .makeSound) -> Dog (has .eatOwnPoop) -> RedDog (no, too specific, covered by colour)
Notice how I had ".makeSound" in Animal. I could have put .bark in dog, but then I'd have to put .meow in cat etc. The subclass can simply override and provide a concrete sound.
However, you can use interfaces to better cross-cut your code, but that's quite a lengthy topic and probably overkill for your needs (although it could help any unit testing you do).
It sounds like you are over-using inheritance. It is certainly a red flag when you simultaneously say "common attributes like ..." and "...only make sense when applied to a specific type." Also, it is a red flag that domain objects such as building share a common base class with an interface object like button. Finally, it is quite unusual to define your own objet (object?) class from which every class in your system derives. It's not inconceivable, but in combination with your other comments, it sounds like you've started down an unproductive path.
You might want to refer to a good tutorial on object-oriented design and analysis such as "Head First OOA&D"
You do not HAVE to do anything. Generally, it is useful to use derived classes if they exhibit some kind of commonality but become more specialised in nature requiring specific functionality at each level of inheritance. It is also good to use if you want to have polymorphic behaviour. You have asked a very open ended question but basically do not feel that you HAVE to use inheritance as not every problem requires it and indeed some people overuse inheritance, introducing it in places where it really is not needed. All in all, I would really recommend that if you haven't already that you read a good book on object oriented design as this will then get you to think about your code from a different perspective and greatly improve the way you view software and design it. It may sound like a cop out but this kind of question is very hard to answer without knowing all details of what you are doing.
In this video from Google IO 2009, the presenter very quickly says that signatures of methods should return concrete types instead of interfaces.
From what I heard in the video, this has something to do with the GWT Java-to-Javascript compiler.
What's the reason behind this choice ?
What does the interface in the method signature do to the compiler ?
What methods can return interfaces instead of concrete types, and which are better off returning concrete instances ?
This has to do with the gwt-compiler, as you say correctly. EDIT: However, as Daniel noted in a comment below, this does not apply to the gwt-compiler in general but only when using GWT-RPC.
If you declare List instead of ArrayList as the return type, the gwt-compiler will include the complete List-hierarchy (i.e. all types implementing List) in your compiled code. If you use ArrayList, the compiler will only need to include the ArrayList hierarchy (i.e. all types implementing ArrayList -- which usually is just ArrayList itself). Using an interface instead of a concrete class you will pay a penalty in terms of compile time and in the size of your generated code (and thus the amount of code each user has to download when running your app).
You were also asking for the reason: If you use the interface (instead of a concrete class) the compiler does not know at compile time which implementations of these interfaces are going to be used. Thus, it includes all possible implementations.
Regarding your last question: all methods CAN be declared to return interface (that is what you ment, right?). However, the above penalty applies.
And by the way: As I understand it, this problem is not restricted to methods. It applies to all type declarations: variables, parameters. Whenever you use an interface to declare something, the compiler will include the complete hierarchy of sub-interfaces and implementing classes. (So obviously if you declare your own interface with only one or two implementing classes then you are not incurring a big penalty. That is how I use interfaces in GWT.)
In short: use concrete classes whenever possible.
(Small suggestion: it would help if you gave the time stamp when you refer to a video.)
This and other performance tips were presented at Google IO 2011 - High-performance GWT.
At about the 7 min point the speak addresses 'RPC Type Explosion':
For some reason I thought the GWT compiler would optimize it away again but it appears I was mistaken.
If I have a function (say messUp that does not need to access any private variables of a class (say room), should I write the function inside the class like room.messUp() or outside of it like messUp(room)? It seems the second version reads better to me.
There's a tradeoff involved here. Using a member function lets you:
Override the implementation in derived classes, so that messing up a kitchen could involve trashing the cupboards even if no cupboards are available in a generic room.
Decide that you need to access private variables later on, without having to refactor all the code that uses the function.
Make the function part of an interface, so that a piece of code may require that its argument be mess-up-able.
Using an external function lets you:
Make that function generic, so that you may apply it to rooms, warehouses and oil rigs equally (if they provide the member functions required for messing up).
Keep the class signature small, so that creating mock versions for unit testing (or different implementations) becomes easier.
Change the class implementation without having to examine the code for that function.
There's no real way to have your cake and eat it too, so you have to make choices. A common OO decision is to make everything a method (unless clearly idiotic) and sacrifice the three latter points, but that doesn't mean you should do it in all situations.
Any behaviour of a class of objects should be written as an instance method.
So room.messUp() is the OO way to do this.
Whether messUp has to access any private members of the class or not, is irrelevant, the fact that it's a behaviour of the room, suggests that it's an instance method, as would be cleanUp or paint, etc...
Ignoring which language, I think my first question is if messUp is related to any other functions. If you have a group of related functions, I would tend to stick them in a class.
If they don't access any class variables then you can make them static. This way, they can be called without needing to create an instance of the class.
Beyond that, I would look to the language. In some languages, every function must be a method of some class.
In the end, I don't think it makes a big difference. OOP is simply a way to help organize your application's data and logic. If you embrace it, then you would choose room.messUp() over messUp(room).
i base myself on "C++ Coding Standards: 101 Rules, Guidelines, And Best Practices" by Sutter and Alexandrescu, and also Bob Martin's SOLID. I agree with them on this point of course ;-).
If the message/function doesnt interract so much with your class, you should make it a standard ordinary function taking your class object as argument.
You should not polute your class with behaviours that are not intimately related to it.
This is to repect the Single Responsibility Principle: Your class should remain simple, aiming at the most precise goal.
However, if you think your message/function is intimately related to your object guts, then you should include it as a member function of your class.
Firstly, this is just an Object Oriented Programming question and does not apply to any Language in particular.
This is quite embarassing for me. This incident happened # work and I was too shy to clarify this with my colleagues as it would indicate a poor understanding of Object Oriented Programming on my part. So here is the incident :
There is a class A which implements interface I. This interface has a method M. Class A has defined the body or rather implementation of this method.
Now I have a tool with which I can find out which other class or program uses, or in other words calls Class A -> method M.When I used this tool, it did not return any results; An indication which I took as no class is calling method M.
When I shared my observations with a senior colleague, he simply went to the interface I -> method M, and used the tool on this. It returned quite a few results. He told me that these are the classes or methods which call method M and asked me to proceed.
This result is obviously a list of those classes which implement interface I.
But what I didn't understand is that how is this the set of classes or methods which call Class A -> method M. Since I had confidently told my colleague that no class calls method M, after he showed me the result list, I was too embarassed to ask him how is that the result that I am looking for.
Any idea what my colleague is hinting at?
Regards,
Mithun
The whole idea behind having interfaces for the classes is so that the interfaces will be used to pass the instances. This is to provide loose coupling.
Now, since you do not actually pass the class around but the interface specific to that class,
eg :
void someMethod (ISomeClass intobject)
instead of
void someMethod (SomeClass obj)
so when you are trying to call a method within ISomeClass / SomeClass called myMethod in someMethod, it is actually
intobject.myMethod()
Hence, all usages of myMethod refer back to ISomeClass and not really to SomeClass
Edit: Maybe its just me, but I always believe that when you dont understand something, it is better to open your mouth to ask a question and be mistaken for a fool than to keep it shut and prove yourself to be one!
I think you should ask your guy what is going on. You shouldn't be afraid to admit you don't know; there is nothing wrong with not knowing, if you learn from it. I am wrong all the time and am not in the least embarrassed by it, if I can get to the next step and learn something.
I think what you are seeing is that nothing is using Class A -> M, but that there are other implementations of I which use M. The tool found where M is being used by other implementations.
When I used this tool, it did not return any results; An indication which I took as no class is calling method M.
Does no results mean that?
But what I didn't understand is that how is this the set of classes or methods which call Class A -> method M.
Is that really what the results mean?
How does this tool work? What do the results mean? Not sure if it's OOP you don't understand, or just this magic tool?
In java world (more precisely if you have no multiple inheritance/mixins) the rule of thumb is quite simple: "Favor object composition over class inheritance".
I'd like to know if/how it is changed if you also consider mixins, especially in scala?
Are mixins considered a way of multiple inheritance, or more class composition?
Is there also a "Favor object composition over class composition" (or the other way around) guideline?
I've seen quite some examples when people use (or abuse) mixins when object composition could also do the job and I'm not always sure which one is better. It seems to me that you can achieve quite similar things with them, but there are some differences also, some examples:
visibility - with mixins everything becomes part of the public api, which is not the case with composition.
verbosity - in most cases mixins are less verbose and a bit easier to use, but it's not always the case (e.g. if you also use self types in complex hierarchies)
I know the short answer is "It depends", but probably there are some typical situation when this or that is better.
Some examples of guidelines I could come up with so far (assuming I have two traits A and B and A wants to use some methods from B):
If you want to extend the API of A with the methods from B then mixins, otherwise composition. But it does not help if the class/instance that I'm creating is not part of a public API.
If you want to use some patterns that need mixins (e.g. Stackable Trait Pattern) then it's an easy decision.
If you have circular dependencies then mixins with self types can help. (I try to avoid this situation, but it's not always easy)
If you want some dynamic, runtime decisions how to do the composition then object composition.
In many cases mixins seem to be easier (and/or less verbose), but I'm quite sure they also have some pitfalls, like the "God class" and others described in two artima articles: part 1, part 2 (BTW it seems to me that most of the other problems are not relevant/not so serious for scala).
Do you have more hints like these?
A lot of the problems that people have with mix-ins can be averted in Scala if you only mix-in abstract traits into your class definitions, and then mix in the corresponding concrete traits at object instantiation time. For instance
trait Locking{
// abstract locking trait, many possible definitions
protected def lock(body: =>A):A
}
class MyService{
this:Locking =>
}
//For this time, we'll use a java.util.concurrent lock
val myService:MyService = new MyService with JDK15Locking
This construct has several things to recommend it. First, it prevents there from being an explosion of classes as different combinations of trait functionalities are needed. Second, it allows for easy testing, as one can create and mix-in "do-nothing" concrete traits, similar to mock objects. Finally, we've completely hidden the locking trait used, and even that locking is going on, from consumers of our service.
Since we've gotten past most of the claimed drawbacks of mix-ins, we're still left with a tradeoff
between mix-in and composition. For myself, I normally make the decision based on whether a hypothetical delegate object would be entirely encapsulated by the containing object, or whether it could potentially be shared and have a lifecycle of its own. Locking provides a good example of entirely encapsulated delegates. If your class uses a lock object to manage concurrent access to its internal state, that lock is entirely controlled by the containing object, and neither it nor its operations are advertised as part of the class's public interface. For entirely encapsulated functionality like this, I go with mix-ins. For something shared, like a datasource, use composition.
Other differences you haven't mentioned:
Trait classes do not have any independent existence:
(Programming Scala)
If you find that a particular trait is used most often as a parent of other classes, so that the child classes behave as the parent trait, then consider defining the trait as a class instead, to make this logical relationship more clear.
(We said behaves as, rather than is a, because the former is the more precise definition of inheritance, based on the Liskov Substitution Principle - see [Martin2003], for example.)
[Martin2003]: Robert C. Martin, Agile Software Development: Principles, Patterns, and Practices, Prentice-Hall, 2003
mixins (trait) have no constructor parameters.
Hence the advice, still from Programming Scala:
Avoid concrete fields in traits that can’t be initialized to suitable default values.
Use abstract fields instead or convert the trait to a class with a constructor.
Of course, stateless traits don’t have any issues with initialization.
It’s a general principle of good object-oriented design that an instance should always be in a known valid state, starting from the moment the construction process finishes.
That last part, regarding the initial state of an object, has often helped decide between class (and class composition) and trait (and mixins) for a given concept.