Is it possible to make a child class that extends ArrayList? If so, how?
You can extend any class that is not final in Java. Having said that, you should avoid inheritance if there is no true is-a relationship. Consider composition for reuse. Read about Liskov substitution principle
Yes you can.
public class MyArrayList<E> extends ArrayList<E>
{
}
However, I'm not sure why you would want to do this.
As many other have said, yes, you can extend class ArrayList, but it is not something that you should normally do; it is not considered good practice in Java.
I'm mainly a Java programmer, but the past months I've also been working on C# code. It seems like it's a common idiom in C# to extend the standard collection classes if you need a collection of a specific type (I actually don't know if it is a common idiom in general - at least the people who wrote the code I'm working with are doing this all the time).
So if they have a class Person and they need a list of persons, they'd create a class PersonList that extends the C# equivalent of ArrayList<Person>.
The common idiom in Java would just to use ArrayList<Person> if you need a list of Person objects and not to create a specific subclass for this.
I'd advise you to stick to the common Java way of doing things, and not create your own subclasses of ArrayList or other collection classes.
ArrayList is not final class and it provides public constructor, so technically it can be extended.
But best practice is delegate rather than extend.
See: Decorator pattern
Just try it out. The class is not final, it's constructor is public, so you can. However, it's probably no good idea for a beginner.
Most of the time, it's no good idea for anyone. Imagine you add some functionality and get ExtList1 extends ArrayList. A college of yours adds a different independent functionality, so you have ExtList2 extends ArrayList. Now you want them both at once and you're out of luck.
Or you need the same feature with a different base list implementation (maybe LinkedList, though it's virtually always wrong to use it). Again, out of luck.
These are all cases when delegation wins. It needn't be more verbose when someone has created the base already.
I'd only inherit from ArrayList, if there was a very good reason for doing exactly this. Maybe some really extreme performance requirements based on proper JMH benchmarks.
As others said, extending java lang data structures is a very bad idea.
However, if you have some logic you want to isolate in a collection class, I would suggest bellow solution:
public class ProductCollection{
ArrayList<Product> products;
public Product getByCode(String code) {
// ... your logic goes here.
}
}
Related
I inherited some legacy Java (1.4) code and this design decision appears regularly. I can't understand if there's any purpose or reason to it.
public interface SoapFacade extends iConfigurable{ }
public class SoapFacadeBase implements SoapFacade{
...
}
public class SoapFacadeImpl extends SoapFacadeBase implements SoapFacade{
...
}
As I understand interfaces (and my experimentation has reinforced), there is no purpose to having both the parent and the child implement the same interface. In this scenario, everything from SoapFacade is implemented in SoapFacadeBase, but the method in iConfigurable is implemented in SoapFacadeImpl. However, that doesn't create a need to have SoapFacadeImpl implement SoapFacade.
Is there something I don't know about interfaces that would give this pattern some purpose or benefit? Are there underlying costs beyond lack of clarity that should drive refactoring it? Or should it simply be refactored for clarity/simplicity?
As I understand interfaces (and my experimentation has reinforced), there is no purpose to having both the parent and the child implement the same interface.
No. Technically, it is completely redundant.
It does however document the fact that you intend SoapFacadeImpl to be a SoapFacade and it ensures that you get a compile error, if you (or someone else) decides to remove implements SoapFacade from the base class.
You see this pattern everywhere in the standard Java Collections API. ArrayList implements List even though its base class (AbstractList) already, does. Same holds for HashSet / AbstractSet and the Set interface.
If you use the interface also as a marker. Class.getInterfaces(); will only return directly instanced interfaces.
I actually find that design pointless. Implemented interfaces, as you stated, are just inherited, so there's no need to copy and paste "implements SomeInterface" on the children classes.
It's not clearer, smarter, or whatsoever...
It is nonsense, don't do it.
Especially in a public API like java collections. It's absolutely nonsense.
Object oriented design is a pretty neat concept, but I'm struggling on how to wrap my head around most of its facets. I think the key to a good object oriented design is having a good grasp on how to look at it. I usually look at object-oriented this way:
Classes are Real-world entities or objects
Instance Fields are entity's attributes, ('has A')
Methods are like actions, verbs, Entity's abilities
Interfaces are like abilities that you can imbue on an object. It could also be an 'is A or can do' relationship whose implementations are not set in stone. Superman is a Krypton, being a Kryptonian comes with a set of special abilities, like flying, freeze-breath, etc. Superman fly different from Green Lantern and Goku and especially Batman, that is why Flight as interface is probably a good idea if you're creating a Fictional Universe.
public class SuperMan extends Man implements Kryptonian{}
public interface Kryptonian extends Flight, FreezeBreath{
public void fly();
public void coolBreath();
}
Problem comes along when you add Generics into the mix? Because the given type parameters somehow creates a contract between the class/interface and the type.
public interface Flight<T>{
public void fly(T t);
}
In this example, Flight is coupled with a T, T could be a superhero a bird or anything that can fly.But is that really how I should imagine it? Because that seems like the same as what plain interfaces do? Although, a parameterized interface is still an interface, the coupling with the type T is what really bothers me. Moreover, things also get complicated when you add bounded restriction on the parameter type.
public class Pidgey<T extends Bird> implements Flight<T>{}
what real-world concrete object can you identify T with? The above example is pretty wrong, although using the class parameter to also restrict the type of Flight is probably a good design, because Flight is still independent enough that other classes could still use it without any restriction. But the example itself is wrong. Pidgey is a Bird that can fly, but what what could T be? Well, T could be anything, it could be another object or abilities. The question is what are its implications, why put T there? What are real-world examples of doing so?
It's easy to understand when you talk about collections, since collections are like containers. You can create a wide variety of containers that holds different kinds of objects.
public class WaterBottle<T extends Liquid> implements UniqueCap{}
But I've seen Generics being used not just on a container-like objects? How could one design such objects, what did they consider?
Your analogies to the various features in OOP are definitely valid. Generics definitely make the most sense when talking about collections/containers/Hashmaps. They do have their uses in other places, though. For example, if a bank wants to process notes in many currencies, they can write
public class moneyProcessor
However, generics aren't required. In the context of your Flight interface, there wouldn't be much of a reason to use generics. Which brings me to another point:
Just because someone else does something one way doesn't mean you have to do it that way. OOP is very flexible for a reason. There's always more than one correct way. If a method takes an Object as a parameter, it's not the end of the world. Just make sure you can read it later. :)
Edit: and that others can read it too.
Its convention to use T when dealing with generics. it makes code readable as others reading your code will immediately know you're referring to a generic and nothing specific
I am pretty new to Java, so I may be using incorrect terminology. I am trying to gracefully extend a class to a new class which holds multiple instances of the superclass. For example, say I have a class
class Rose{
String smell;
Rose(String smell){this.smell=smell;}
void sniff(){ println("smells "+smell);}
}
And I want to define a class like...
class Bouquet extends Rose{
ArrayList<Rose> roses;
...
}
holding multiple roses. My actual code has something like 20 methods, and for most of them the extended method would be
void sniff(){
for( Rose one: roses) one.sniff();
}
Is there a way to construct bouquet in such a way that I don't need to explicitly define these silly loops? I'm not tied to ArrayList, I could even make a new super class if that's the way to go about it. However, it is important that I can send a bouquet instead of a rose argument to externally written methods.
EDIT:
Haha, I think my flower metaphor was a big fail. :) But your input is good; you guys have clarified my thinking a bit.
In my real problem, there are a set of operations that define how to add instances of the base class together into a new instance of the base class. Perhaps a better metaphor would be twisting a number of small fabric strands together into one rope. External methods should treat a rope and a strand exactly the same.
It does seem like extends is wrong, any other suggestions?
You dont really need to extend bouquet from roses. You extend only when there is an IS A relationship, like you have Flower class and Rose is a Flower. But bouquet is not a rose. Ideally you should have a bouquet class which HAS many roses. If there is a 1:N relationship, then you will have to loop through to get individual items.
Although we can implement anything to our desire, but there are few flaws in your class designs in regards to abstraction.
A bouquet is a collection of rose, so it shouldn't extend rose, but rather have it as a List inside it, which you have anyway. It doesn't make much sense to extend on rose and also have it as property inside bouquet. Instead, create a Base class called Flower and then extend that to create rose.
Define the sniff function inside Flower Class, making provision to override it in derived class, if you need to do that.
It would be wrong.
I would have voted Shamims answer up, if he hadn't introduced the flower class, which is not a reasonable assumption from your question.
ArrayList <Rose> bouquet;
might be all you need. But you can't use a Bouquet as a Rose. Bouquet.split (); could make sense, but Rose.split would be a very different thing.
The is-a question gives you a rough idea, whether inheritance is a reasonable thing. It's not always the final answer, but if it doesn't fit, it doesn't.
Okay, correct me if I'm wrong, but to me it seems quite obvious that the real question has nothing to do with flowers or roses, but the author is simply trying to create an example.
In a real application there could be an is-a relationship and the problem is valid. For example, I have had to use this pattern when handling callbacks: you have one MyCallback interface, a couple of concrete implementations, and to be able to register multiple callbacks you have a MultipleMyCallback class that has a list of MyCallback it delegates all calls to. You get exactly the same annoying for loop in every method.
I think you could do this via a Java dynamic proxy. Or if you're feeling adventurous even using something like CGLIB But I recommend against it. Just accept that this is a fact of life with Java and write the 20 methods and be done with it.
Without a lot of hacks, no, there is no easy way to do this. I'd highly recommend reading about this. Basically, you only want to use inheritance to enforce an is-a relationship - what this means is that your subclass should be substitutable for your base class in all situations. The natural question is therefore, is a bouquet a rose, and the answer here is no, it is not, thus inheritance is not suitable for the job.
In addendum to the answers posted, when it comes to naming your methods it will be better if you replace the sniff() method with getSmell().
A new collaborator of mine who was reviewing some code I'd written told me that she wasn't used to seeing interfaces used directly in Java code, e.g.:
public interface GeneralFoo { ... }
public class SpecificFoo implements GeneralFoo { ... }
public class UsesFoo {
GeneralFoo foo = new SpecificFoo();
}
instead, expecting to see
public interface GeneralFoo { ... }
public abstract class AbstractFoo implements GeneralFoo { ... }
public class SpecificFoo extends AbstractFoo { ... }
public class UsesFoo {
AbstractFoo foo = new SpecificFoo();
}
I can see when this pattern makes sense, if all SpecificFoos share functionality through AbstractFoo, but if the various Foos have entirely different internal implementations (or we don't care how a specific Foo does Bar, as long as it does it), is there any harm in using an interface directly in code? I realize this is probably a tomato/tomato thing to some extent, but I'm curious if there's an advantage to the second style, or disadvantage to the first style, that I'm missing.
If you have no need for an abstract class with certain details common to all implementations, then there's no real need for an abstract class. Complexity often gets added to applications because there is some perceived need to support future features that haven't yet been defined. Stick with what works, and refactor later.
No, she's inexperienced, not right. Using interfaces is preferred, and writing redundant abstract super classes for the sake of redundancy is redundant.
UsesFoo should care about the behaviour specified by the interface, not about the super class of its dependencies.
For me "she wasn't used to" is not good enough reason. Ask her to elaborate on that.
Personally I'd use your solution, because:
AbstractFoo is redundant and ads no value in current situation.
Even if AbstractFoo was needed (for some additional functionality), I'd always use lowest needed type: if GeneralFoo was sufficient, then I'd use that, not some class derived from it.
It depends only on your problem.
If you use interfaces only, then if all your classes have a same method, it would have to be implemented redundantly (or moved away to a Util class).
On the other hand, if you do write an intermediary abstract class, you solved that problem, but now your subclass may not be a subclass of another class, because of absence of multiple inheritance in Java. If it was already necessary to extend some class, this is not possible.
So, shortly - it's a trade off. Use whichever is better in your particular case.
There is not harm in directly using an interface in code. If there were, Java would not have interfaces.
The disadvantages of using an interface directly include not being able to reach and class-specific methods which are not implemented in the interface. For poorly written interfaces, or classes which add a lot of "other" functionality, this is undesirable as you lose the ability to get to needed methods. However, in some cases this might be a reflection of a poor design choice in creating the interface. Without details it is too hard to know.
The disadvantages of using the base class directly include eventually ignoring the interface as it is not frequently used. In extreme cases, the interface becomes the code equivalent of a human appendix; "present but providing little to no functionality". Unused interfaces are not likely to be updated, as everyone will just use the base abstract class directly anyway. This allows your design to silently rot from the viewpoint of anyone who actually tries to use the interface. In extreme cases, it is not possible to handle an extending class through the interface to perform some critical functionality.
Personally, I favor returning classes via their interface and internally storing in members them via their lowest sub-class. This provides intimate knowledge of the class within the class's encapsulation, forces people to use the interface (keeping it up-to-date) externally, and the class's encapsulation allows possible future replacement without too much fuss.
I'm curious if there's an advantage to the second style, or disadvantage to the first style, that I'm missing
That reasons for the first interfaces style:
Often, the design is such that the interface is the public interface of the concept while the abstract class is an implementation detail of the concept.
For example, consider List and AbstractList in the collection framework. List is really what clients are usually after; fewer people know about about AbstractList because its an implementation detail to aid suppliers (implementers) of the interface), not clients (users) of the class.
The interface is looser coupling, therefore more flexible to support future changes.
Use the one that more clearer represents the requirement of the class, which is often the interface.
For example, List is often used rather than AbsrtactList or ArrayList. Using the interface, it may be clearer to a future maintainer that this class needs some kind of List, but it does not specifically need an AbstractList or an ArrayList. If this class relied on some AbstractList-specific property, i.e. it needs to use an AbstractList method, then using AbstractList list = ... instead of List list = ... may be a hint that this code relies on something specific to an AbstractList .
It may simplify testing/mocking to use the smaller, more abstract interface rather than to use the abstract class.
It is considered a bad practice by some to declare variables by their AbstractFoo signatures, as the UsesFoo class is coupled to some of the implementation details of foo.
This leads to less flexibility - you can not swap the runtime type of foo with any class that implements the GeneralFoo interface; you can only inject instances that implement the AbstractFoo descendant - leaving you with a smaller subset.
Ideally it should be possible for classes like UsesFoo to only know the interfaces of the collaborators they use, and not any implementation details.
And of course, if there is no need to declare anything abstract in a abstract class AbstractFoo implements GeneralFoo - i.e. no common implementation that all subclasses will re-use - then this is simply a waste of an extra file and levels in your hierarchy.
Firstly I use abstract and interface classes plentifully.
I think you need to see value in using an interface before using it. I think the design approach is, oh we have a class therefore we should have an abstract class and therefore we should have interfaces.
Firstly why do you need an interface, secondly why do you have an abstract class. It seems she may be adding things, for adding things sake. There needs to be clear value in the solution otherwise you are talking about code that has no value.
Emperically there you should see the value in her solution. If there is no value the solution is wrong, if it cant be explained to you she does not understand why she is doing it.
Simple code is the better solution and refactor when you need the complexity, flexibility or whatever perceived value she is getting from the solution.
Show the value or delete the code!
Oh one more thing have a look at the Java library code. Does that use the abstract / interface pattern that she is applying .. NO!
I'm using an interface in java, that communicates with PureData. In order to do so, my classes have to extend a given class MaxObject. While designing my class, which is a cirular buffer, I discovered that I need to extend java's Iterator class. So I have to extend two classes at the same time.
My guess is that the only solution is to create two different classes and let one of them be a component of the other one. But, is it the only solution? Is it the best one?
Further, whenever I find myself needing inherit from two classes, is it a because of a bad design? Is there a design pattern to solve this class?
Thank you
Iterator is not a class, it's an interface. As such, you don't extend it, you implement it. You can implement any number of interfaces - the only limitation is that you can only extend one class.
In your case:
class MyClass extends MaxObject implements Iterator<Type>
edit: I should have read closer what's being extended. EboMike is right, you don't need to extend the Iterator class.
Sounds like the DDofD: http://javacodeonline.blogspot.com/2009/08/deadly-diamond-of-death.html
Iterator is an interface. From a theoretical point of view there's nothing against extending MaxObject and implementing Iterator.
Due to a lack of information I cannot say if it's a good idea to do this, but I have a bad feeling.