Extending a java ArrayList - java

I'd like to extend ArrayList to add a few methods for a specific class whose instances would be held by the extended ArrayList. A simplified illustrative code sample is below.
This seems sensible to me, but I'm very new to Java and I see other questions which discourage extending ArrayList, for example Extending ArrayList and Creating new methods. I don't know enough Java to understand the objections.
In my prior attempt, I ending up creating a number of methods in ThingContainer that were essentially pass-throughs to ArrayList, so extending seemed easier.
Is there a better way to do what I'm trying to do? If so, how should it be implemented?
import java.util.*;
class Thing {
public String name;
public int amt;
public Thing(String name, int amt) {
this.name = name;
this.amt = amt;
}
public String toString() {
return String.format("%s: %d", name, amt);
}
public int getAmt() {
return amt;
}
}
class ThingContainer extends ArrayList<Thing> {
public void report() {
for(int i=0; i < size(); i++) {
System.out.println(get(i));
}
}
public int total() {
int tot = 0;
for(int i=0; i < size(); i++) {
tot += ((Thing)get(i)).getAmt();
}
return tot;
}
}
public class Tester {
public static void main(String[] args) {
ThingContainer blue = new ThingContainer();
Thing a = new Thing("A", 2);
Thing b = new Thing("B", 4);
blue.add(a);
blue.add(b);
blue.report();
System.out.println(blue.total());
for (Thing tc: blue) {
System.out.println(tc);
}
}
}

Nothing in that answer discourages extending ArrayList; there was a syntax issue. Class extension exists so we may re-use code.
The normal objections to extending a class is the "favor composition over inheritance" discussion. Extension isn't always the preferred mechanism, but it depends on what you're actually doing.
Edit for composition example as requested.
public class ThingContainer implements List<Thing> { // Or Collection based on your needs.
List<Thing> things;
public boolean add(Thing thing) { things.add(thing); }
public void clear() { things.clear(); }
public Iterator<Thing> iterator() { things.iterator(); }
// Etc., and create the list in the constructor
}
You wouldn't necessarily need to expose a full list interface, just collection, or none at all. Exposing none of the functionality greatly reduces the general usefulness, though.
In Groovy you can just use the #Delegate annotation to build the methods automagically. Java can use Project Lombok's #Delegate annotation to do the same thing. I'm not sure how Lombok would expose the interface, or if it does.
I'm with glowcoder, I don't see anything fundamentally wrong with extension in this case--it's really a matter of which solution fits the problem better.
Edit for details regarding how inheritance can violate encapsulation
See Bloch's Effective Java, Item 16 for more details.
If a subclass relies on superclass behavior, and the superclass's behavior changes, the subclass may break. If we don't control the superclass, this can be bad.
Here's a concrete example, lifted from the book (sorry Josh!), in pseudo-code, and heavily paraphrased (all errors are mine).
class CountingHashSet extends HashSet {
private int count = 0;
boolean add(Object o) {
count++;
return super.add(o);
}
boolean addAll(Collection c) {
count += c.size();
return super.addAll(c);
}
int getCount() { return count; }
}
Then we use it:
s = new CountingHashSet();
s.addAll(Arrays.asList("bar", "baz", "plugh");
And it returns... three? Nope. Six. Why?
HashSet.addAll() is implemented on HashSet.add(), but that's an internal implementation detail. Our subclass addAll() adds three, calls super.addAll(), which invokes add(), which also increments count.
We could remove the subclass's addAll(), but now we're relying on superclass implementation details, which could change. We could modify our addAll() to iterate and call add() on each element, but now we're reimplementing superclass behavior, which defeats the purpose, and might not always be possible, if superclass behavior depends on access to private members.
Or a superclass might implement a new method that our subclass doesn't, meaning a user of our class could unintentionally bypass intended behavior by directly calling the superclass method, so we have to track the superclass API to determine when, and if, the subclass should change.

I don't think extending arrayList is necessary.
public class ThingContainer {
private ArrayList<Thing> myThings;
public ThingContainer(){
myThings = new ArrayList<Thing>();
}
public void doSomething(){
//code
}
public Iterator<Thing> getIter(){
return myThings.iterator();
}
}
You should just wrap ArrayList in your ThingContainer class. ThingContainer can then have any processing methods you need. No need to extend ArrayList; just keep a private member.
Hope this helps.
You may also want to consider creating an interface that represents your Thing Class. This gives you more flexibility for extensibility.
public Interface ThingInterface {
public void doThing();
}
...
public OneThing implements ThingInterface {
public void doThing(){
//code
}
}
public TwoThing implements ThingInterface {
private String name;
public void doThing(){
//code
}
}

Here is my suggestion:
interface ThingStorage extends List<Thing> {
public int total();
}
class ThingContainer implements ThingStorage {
private List<Thing> things = new ArrayList<Thing>();
public boolean add(Thing e) {
return things.add(e);
}
... remove/size/... etc
public int total() {
int tot = 0;
for(int i=0; i < size(); i++) {
tot += ((Thing)get(i)).getAmt();
}
return tot;
}
}
And report() is not needed actually. toString() can do the rest.

Related

OOP - Interface inheriting an abstract class alternative

Let's say that I have an interface IMazeRoom
This interface has a function getAdjacentRooms()
Furthermore, Mazerooms have to be instanciated as IMazeRoom room1 etc.
(All of the above cannot be changed)
Let's say these classes are implementing the interface:
TrapRoom, FreeRoom, MobRoom, TreasureRoom
I want to the following functions/variables to be used in all of those subclasses
Players[] playersInRoom, setSize(), isAdditionValid(Player p)
I want to use inheritence with the three functions/variable above without modifying the interface, or duplicating the code throughout the four subclasses.
What I have tried so far
Making an abstract interface MazeRoom which implements IMazeroom, and is implemented by the four subclasses. This does not work as a constraint of this project is that the rooms have to be instantiated as IMazeroom room and doing this would lead to instantiation Mazeroom room If I wanted to use the new functions meantioned above. Also IMazeRooms cannot be modified.
Ideas
I could probably just use another interface with the functions I want to include, which would be implemented by IMazeroom, but this seems weird as this constraint should be here to teach me something, and I do not see the value in just using another interface. Furthermore, using another interface would not really cut down on code duplication, I am looking for something more like a abstract class
(The above is a completely different example from my homework task, as I want to attemp the task on my own)
Edit: Since we cannot change the interface, you can use a DefaultRoom class that implements IMazeRoom.
public class DefaultRoom implements IMazeRoom {
protected Players[] playersInRoom;
/* your standard method implementations */
public boolean isAddtionValid(Player p) {
...
}
}
public interface IMazeRoom {
...
}
Since you have to instantiate it via IMazeRoom myIMazeRoomObject = new DefaultRoom(), as long as you know which kind of Room you are handling, you can simply cast it back:
try {
DefaultRoom myRoom = (DefaultRoom) myIMazeRoomObject;
} catch(ClassCastException ex) {
// we didn't get a DefaultRoom object and now we have to handle that
}
Sidenote: The important thing to note is, that the interface only implements the necessary method getAdjacentRoom, as such it only constitutes information to some (arbitrary) layout that relies on getAdjacentRooms().
Your secondary constraints (immutable interface + instantiation) make it necessary to circumvent something that shouldn't happen with proper OO architecture.
You can seperate the common concrete implemetation into a abstact class and keep the interface.
Rough example based on "I am not allowed to change the interface though":
IMazeRoom:
public interface IMazeRoom {
Set<IMazeRoom> getAdjacentRooms();
}
Common concrete implemetation:
public abstract class CommonRoom {
private final int size;
private final Set<Player> playersInRoom;
private final Set<IMazeRoom> adjacentRooms;
protected CommonRoom(int size, Set<Player> playersInRoom, Set<IMazeRoom> adjacentRooms) {
this.size = size;
this.playersInRoom = playersInRoom;
this.adjacentRooms = adjacentRooms;
}
public int getSize() {
return size;
}
public Set<Player> getPlayersInRoom() {
return playersInRoom;
}
public Set<IMazeRoom> getAdjacentRooms() {
return adjacentRooms;
}
public boolean isAdditionValid(Player player) {
// Some kind of implementation returning true or false...
return !playersInRoom.contains(player);
}
}
TrapRoom:
public class TrapRoom extends CommonRoom implements IMazeRoom {
public TrapRoom(int size, Set<Player> playersInRoom, Set<IMazeRoom> adjacentRooms) {
super(size, playersInRoom, adjacentRooms);
}
}
TreasureRoom:
public class TreasureRoom extends CommonRoom implements IMazeRoom {
public TreasureRoom(int size, Set<Player> playersInRoom, Set<IMazeRoom> adjacentRooms) {
super(size, playersInRoom, adjacentRooms);
}
}
... same implementation as TreasureRoom for additional rooms.
Comment: Now all rooms are treated as IMazeRoom...

Creating objects of same type as subclass

I am designing a Genetic Algorithms library, and am currently constructing the Genome class. This class includes several methods for creating, mutating, crossing, and evaluating genomes, and will be central to this library. This abstract class has two subclasses StaticGenome and VariableGenome. These classes provide additional functionality for fixed or variable length genomes.
Ultimately, crossing any two genomes should be independent of the Genome Type. That being said, the method singlePointCrossover(Genome parent2) takes in two genomes, and returns a new Genome object, which is a special combination of the two parent genomes. However, because Genome is an abstract class, I cannot instantiate a new Genome object as it's offspring.
How can I return a new object of the same type as the subclass, from the superclass?
Any assistance would be greatly appreciated.
The Genome class:
public abstract class Genome <ElementType> {
private String name;
private List<AbstractGenomeElement<ElementType> > elements;
// Mutation Methods //////////////////////////////////////////////
public AbstractGenomeElement<ElementType> mutateElement(AbstractGenomeElement<Integer> element) {
return this.mutateElementAtIndex(this.getElements().indexOf(element));
}
public AbstractGenomeElement<ElementType> mutateElementAtIndex(int i) {
return this.getElement(i).mutate();
}
// Crossover Methods //////////////////////////////////////////////
public Genome<ElementType> singlePointCrossover(Genome<ElementType> genome2){
return multiPointCrossover(genome2, 1);
}
public Genome<ElementType> twoPointCrossover(Genome<ElementType> genome2){
return multiPointCrossover(genome2, 2);
}
public Genome<ElementType> multiPointCrossover(Genome<ElementType> genome2, int crosses){
List<AbstractGenomeElement<ElementType>> newElements= new ArrayList<AbstractGenomeElement<ElementType>>();
Integer nums[] = new Integer[length-1];
for (int i = 0; i < length-1; i++) { nums[i] = i+1; }
List<Integer> shuffled = Arrays.asList(nums);
Collections.shuffle(shuffled);
shuffled = shuffled.subList(0, crosses);
boolean selectFromParentA = true;
for(int i = 0; i < length; i++){
if(shuffled.contains((Integer)i)){
selectFromParentA = !selectFromParentA;
}
if(selectFromParentA) newElements.add(this.getElement(i));
else newElements.add(genome2.getElement(i));
}
// Code fails at this point. "Can not instantiate the type Genome"
return new Genome<ElementType>(name, newElements);
}
}
The two subclasses:
public class StaticGenome<ElementType> extends Genome<ElementType> {
}
public class VariableGenome<ElementType> extends Genome<ElementType> {
}
And the main method I am using for testing:
public static void main(String [] args){
Genome<IntegerElement> genomeA = new StaticGenome<IntegerElement>("Genome A", 50);
Genome<IntegerElement> genomeB = new StaticGenome<IntegerElement>("Genome B", 50);
Genome<IntegerElement> offspring = genomeB.uniformCrossover(genomeA.elementCrossover(genomeA.multiPointCrossover(genomeB, 3)));
offspring.setName("Offspring");
System.out.println(offspring);
}
You could introduce the following method to the abstract class and implement it in the subclasses.
protected abstract Genome<ElementType> newInstance(String name, List<AbstractGenomeElement<ElementType>> elements);
when subclasses implement this they can return the correct instance. i.e: a new instance of their own kind. In your cross over method you could then call this method instead of doing 'new Genome'
You can return a subclass from an overriden method, it's called co-variant return type
abstract class Genome {
abstract Genome singlePointCrossover(Genome parent2);
}
class StaticGenome extends Genome {
#Override
StaticGenome singlePointCrossover(Genome parent2) {
...
}
}
class VariableGenome extends Genome {
#Override
VariableGenome singlePointCrossover(Genome parent2) {
...
}
}
If I am correct, the question is: given some Genome object (that will be some subclass of the abstract class Genome), how can we instantiate a new instance of that subclass?
Well, I don't know if this is the best way, but it's what I've come up with:
public Genome<ElementType>
multiPointCrossover(Genome<ElementType> genome2, int crosses){
// Snip...
Genome g;
try {
g = genome2.getClass()
.getConstructor(String.class, List.class)
.newInstance();
} catch (Exception e) {
// Can throw quite a few exceptions...
}
return g;
}
http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Class.html#getConstructor(java.lang.Class...)
http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/reflect/Constructor.html#newInstance(java.lang.Object...)
Note: I think Dev Blanked's solution is cleaner and simpler to work with. This is just what I came up with when they posted.
I think you need to introduce one more class in between Genome and Static/VariableGenome classes. I am not an expert of microbiology so cannot recommend a good logical name to it. But if you have a new child class(lets say newGenomeClass) of your Genome and acting as a Parent of your Static/VriablGenome classes then you can have your method like this:
public newGenomeClass singlePointCrossover(newGenomeClass parent1,newGenomeClass parent2).
Hope it helps!

java return from private method to public

I have a public method and a private method. they are both supposed to return int values. The private method is the one that does all the work and the public is the one that is called from the main program. How can I return the results returned from the private method by the public method?
its like this
public int longer()
{
longer(a.length);
}
private int longer(int n)
{
int index
//find largest index recursively
//make recursive call longer(n-1)
return index;
}
I want to pass it up to the public method and then return it from there. Would I just return it from the public method by saying return longer.index; or something along those lines?
i guess i should clarify. n isnt index. idnex is being calculated based on whats being passed into the method. the public and the private is because its going to be a recursive method. i'll edit what i posted above to make itm ore accurate of what im trying to do. passing in an array and recursively working on it.
public int longer()
{
return longerInternal(a.length);
}
private int longerInternal(int n)
{
int index
//find largest index recursively
//make recursive call longer(n-1)
return index;
}
From your public method, you can call down into the private method. I renamed the private method so that there was not a naming collision for your methods. A simple implementation should look something like this:
public class MyClass {
private int[] a;
public MyClass(int[] _a) {
a = _a;
}
public int longer()
{
return longerInternal(a.length);
}
private int longerInternal(int n)
{
int index;
//do recursive call
return index;
}
}
And it can be called like this:
MyClass myClass = new MyClass(new int[]{1,2,3,4,5,10});
int result = myClass.longer();
First, you probably need better function names.
You'd call your public function getLonger(int n) and then pass it to your private longer(int n) function. When this function is done, it will return to getLonger(int n) and then back to the caller.
You mentioned in an answer to a comment that the "caller does not need to have access to all internal workings of a class."
To me that suggests that you want to use an interface.
Create an interface that describes the class that will contain that secret algorithm:
package com.stevej;
public interface Longer {
public int longer();
}
Implement that interface using your secret algorithm:
package com.stevej;
public class LongerImpl implements Longer {
private int longer(int n){
return 0; // whatever
}
#Override
public int longer() {
return longer(5); // whatever
}
}
Now the caller only creates objects using the interface definition, guaranteeing that there are no exposed methods that he can access by accident. That implementation is hooked to that interface-defined object:
package com.stevej;
public class LongerProcessor {
Longer longerImpl = new LongerImpl();
public LongerProcessor() {
super();
}
public int longer() {
return longerImpl.longer();
}
}
Now you can rewrite the implementation of Longer as often as you like. As long as the interface definition never changes, the caller (LongerProcessor) will never have a problem. Heck, you could have two or more different implementations (LongerImplRecursive, LongerImplBruteForce, and so on), each implementing Longer, and all in use in different places in the same program:
package com.stevej;
public class LongerProcessor {
Longer longerImpl;
public LongerProcessor(boolean useRecursive) {
super();
if (useRecursive){
longerImpl = new LongerImplRecursive();
}else{
longerImpl = new LongerImplBruteForce();
}
}
public int longer() {
return longerImpl.longer();
}
}
How cool is that? Since you tagged this question as "homework", I'm wondering if the problem is supposed to engage you to think about separating the contract (interface) from the implementation (implementing class).

How to set inherited variable in java?

public class Atribut {
int classid;
#Override public String toString() {
return Integer.toString(classid);
}
}
I have made this class which overrides method toString(). I plan on making many subclasses with different classid. The problem is I dont know how to set the variable classid to work in toString method.
public class cas extends Atribut{
int classid=2;
}
The problem is if I make an cas object and toString method it returns "0" not "2".??
My preferred technique for this kind of thing is to use constructor arguments:
public class Parent {
// Using "protected final" so child classes can read, but not change it
// Adjust as needed if that's not what you intended
protected final int classid;
// Protected constructor: must be called by subclasses
protected Parent(int classid) {
this.classid = classid;
}
#Override
public String toString() {
return Integer.toString(classid);
}
}
public class Child extends Parent {
public Child() {
// The compiler will enforce that the child class MUST provide this value
super(2);
}
}
Much as #java_mouse recommended, just use the parent class's variable.
public class Atribut {
protected int classid;
public Atribut() {
classid = 0;
}
#Override
public String toString() {
return Integer.toString(classid);
}
}
public class Cas extends Atribut{
public Cas() {
classid = 2;
}
}
Set classid's value in the constructor and then you can use the superclass's toString() just fine.
When you shadow the variable, the one in the parent class is used in methods there.
If you want to do this, I would do this
class Atribut {
int classid = 0;
protected int classid() { return classid; } // points to Attribut.classid
public String toString() {
return Integer.toString(classid());
}
}
Then in your child class, you can override the method
class cas {
int classid = 2;
protected int classid() { return classid; } // points to cas.classid
}
Why do you want to shadow a variable in child class if it is already available in the parent? why not using the same variable?
if you use the same variable, the issue is resolved automatically. Don't duplicate the attribute if it has to be inherited.
I think most of the answers here narrow down to style preference.
For such small examples, most of the provided solutions would work just fine.
However, let's assume that you have an inheritance tree that is several levels deep. In such a scenario, it might be challenging to understand the source of each property, so using setters, getters, and references to the superclass might come in handy. My personal choice would be as follows:
public class Atribut {
private int firstProp;
private int thirdProp;
public int getFirstProp() {
return firstProp;
}
public void setFirstProp(int firstProp) {
this.firstProp = firstProp;
}
....
#Override
public String toString() {
return Integer.toString(this.getFirstProp()) +
Integer.toString(this.getThirdProp());
}
}
public class Cas extends Atribut {
private int secondProp;
public Cas() {
super.setFirstProp(1);
this.setSecondProp(2);
super.setThirdProp(3);
}
}
An alternative implementation, using the approaches provided above would result in the this Cas class:
public Cas() {
super(1, 3)
secondProp = 2;
}
This second solution is a bit harder to read and is less descriptive about what properties are you setting.
For those reasons, that is the style that I prefer. Also, to reiterate, the benefits of the first approach become more evident for more complex examples.

Why should I use interface in this situation in Java?

I'm trying to understand the basics of Java OOP concepts so I've a question about the interfaces as it confuses me a little. Below I was playing around with two classes. One which implements the SizeComparable interface and the other which doesn't but works too.
public interface SizeComparable {
int isHigher(SizeComparable obj);
}
public class Interesting implements SizeComparable {
private int height;
public Interesting(int height) {
this.height = height;
}
public int getHeight() {
return height;
}
public int isHigher(SizeComparable obj) {
Interesting otherInteresting = (Interesting)obj;
if(this.getHeight() > otherInteresting.getHeight()) {
return 1;
} else {
return 0;
}
}
public static void main(String[] args) {
Interesting i1 = new Interesting(182);
Interesting i2 = new Interesting(69);
int result = i1.isHigher(i2);
System.out.println("Is i1 higher than i2? Result: " + result);
}
}
How is the code above better than the code bellow? Personally I don't understand because the code bellow those it's job great too. Am I missing some concepts behind the interface idea?
public class Interesting {
private int height;
public Interesting(int height) {
this.height = height;
}
public int getHeight() {
return height;
}
public int isHigher(Interesting obj) {
if(this.getHeight() > obj.getHeight()) {
return 1;
} else {
return 0;
}
}
public static void main(String[] args) {
Interesting i1 = new Interesting(182);
Interesting i2 = new Interesting(69);
int result = i1.isHigher(i2);
System.out.println("Is i1 higher than i2? Result: " + result);
}
}
I was trying to understand it (here), but I'm still unsure about this. Sorry if the question is a little silly, i just want to understand it completely.
If you have Interesting, Boring, Indifferent and Crazy classes which all represent some objects comparable by height, then all of them can implement the SizeComparable interface and thus be comparable to each other.
Without the interface you would need n methods in each class to compare it with itself and all the others.
At the beginning it probably won't make much sense, however when you will start injecting dependencies, start testing or will write more than one implementation of interface, than it will really give you boost.
Also it allows for multiple inheritance. Sometimes you want thing like comparable - very generic interface that may be used by a lot of classes in your system. That will come with bigger systems and larger class hierarchies.
Right now just trust rest of java world, and use them interfaces :)
and good luck
An interface is a contract that any class wishing to implement the interface agrees to follow. The reason for using an interface is to allow some other class or method to access the interface functions without requiring that the your class inherit from a common class... I'll modify your example to make it clearer:
public interface HeightCapable {
int getHeight();
}
public class Interesting implements HeightCapable {
private int height;
public Interesting(int height) {
this.height = height;
}
public int getHeight() {
return height;
}
}
public class SomeOtherClass {
public boolean isHigher(HeightCapable obj1, HeightCapable obj2) {
// ... do something interesting
if (obj1.getHeight() > obj2.getHeight()) {
return true;
}
}
In the example above, any class implementing the HeightCapable interface can call SomeOtherClass.isHigher(). Without the interface, any class wishing to call SomeOtherClass.isHigher() would need to inherit from a common class. Java lacks multiple inheritance.
If you want to have your SizeComparable objects comparable not to all other SizeComparable objects, but only to those of some type, you could use generic types.
interface SizeComparable<X> {
/**
* returns true if this object is higher than that object.
*/
boolean isHigher(X that);
}
Then you could create your implementations like this:
public class Interesting implements SizeComparable<Interesting> {
...
public boolean isHigher(Interesting obj) {
return this.getHeight() > obj.getHeight();
}
}
Or, you could even have another interface
public interface HeigthHaving extends SizeComparable<HeightHaving> {
/**
* returns the height of this object.
*/
public int getHeigth();
/**
* compares this object's height with another objects height.
* #return true if this.getHeight() > that.getHeight, else false.
*/
public boolean isHigher(HeightHaving that);
}
Now every implementation of HeightHaving must implement the isHigher(HeightHaving) method (this would be the case even if we did not repeat it here), and should do that according to the specification here. Other SizeComparable implementations are not affected of this, though.
The good thing here is that now for example sort algorithms can sort lists/arrays of any type X implementing SizeComparable, so you don't have to write it again for every new type of object you may want to sort by height.
(In fact, there is already a similar interface Comparable<X> in the standard API. Maybe you want to use this instead of your SizeComparable.)
By the way, for a isXXX method usually a boolean return type is quite more sensible than an integer.

Categories

Resources