I have a GenericContainer class and a FIFOContainer class that extends the generic one. My problem appears when trying to use the takeout() method. It does not recognize that I hold values in my FIFOContainer ArrayList.
I suspect this has something to do with how I defined the constructors but for the life of me cannot figure it out how to solve it.
A solution I thought of is defining a getter in the GenericContainer class and passing the value in the FIFOContainer class but I feel like this should not be needed.
public abstract class GenericContainer implements IBag {
private ArrayList<ISurprise> container;
public GenericContainer() {
this.container = new ArrayList<ISurprise>();
}
#Override
public void put(ISurprise newSurprise) {
this.container.add(newSurprise);
}
#Override
public void put(IBag bagOfSurprises) {
while (!bagOfSurprises.isEmpty()) {
System.out.println(bagOfSurprises.size());
this.container.add(bagOfSurprises.takeout());
}
}
#Override
public boolean isEmpty() {
if (this.container.size() > 0) {
return false;
}
return true;
}
#Override
public int size() {
if (isEmpty() == false) {
return this.container.size();
}
return -1;
}
}
public class FIFOContainer extends GenericContainer {
private ArrayList<ISurprise> FIFOcontainer;
public FIFOContainer() {
super();
this.FIFOcontainer = new ArrayList<ISurprise>();
}
public ISurprise takeout() {
if (isEmpty() == false) {
this.FIFOcontainer.remove(0);
ISurprise aux = this.FIFOcontainer.get(0);
return aux;
}
return null;
}
}
Thing is: fields are not poylmorphic (see here for example).
Your problem: basically your isEmpty() will use the container in the base class, and the other method will us the container in the subclass.
Yes, there are two containers in your class.
A better approach could be to (for example) do this in the base class GenericContainer:
protected abstract List<ISurprise> getContainer();
In other words: a subclass could provide its own container, and base methods as isEmpty() could use that one:
#Override
public final boolean isEmpty() {
return getContainer().isEmpty();
}
To allow for more degrees of freedom, that method could also have a slightly different signature, such as protected abstract Collection<ISurprise> to be more flexible about the actual implementation.
( hint: I made the method final, as that is the whole idea of methods defined in an abstract base class: that subclasses do not overwrite them )
( and bonus hints: try to minimize the amount of code that you write. you don't do someBool == true/false, you don't need to do getSize() == 0 when that list class already offers you an isEmpty() method )
You shouldn't create new arraylist in FIFOContianer. you already have list from GenericContainer.
So right now, when you are calling put it adds item to the container list in the parent class. when calling takeout you are accessing other list (FIFOcontainer) which you created in the child class.
just remove FIFOcontainer and keep using container:
public ISurprise takeout() {
if (isEmpty() == false) {
this.container.remove(0);
ISurprise aux = this.container.get(0);
return aux;
}
return null;
}
Related
I am making a component-based system for a game engine in Java.
I have different system classes to take care of different things, e.g., PhysicsSystem, RenderSystem, EditorSystem and so on. All classes inherits from BaseSystem, which in turn implements an interface ISystem.
I would like all of my system classes to have an ArrayList, but the type in each of them may differ, meaning that the RenderSystem might have a list of RenderComponents, while the PhysicsSystem has a list of PhysicsBodyComponents.
Is it possible to define a generic or abstract list in either the BaseSystem class or the ISystem interface that all the derived classes then implements? I have little experience with generics, so I am a bit confused by this.
This is my current code. As you can see, I created a second list for the derived class, which is kind of a waste.
interface ISystem
{
boolean AddToSystem(Component c);
}
abstract class BaseSystem implements ISystem
{
// can I make this list generic, so it can store any type in derived classes?
// e.g., Component, IRenderable, IPhysics, etc.
protected List<Component> _componentList;
}
class RenderSystem extends BaseSystem
{
// need to make a second list that stores the specific render components
List<IRenderable> _renderList = new ArrayList<IRenderable>();
void Update()
{
for (IRenderable r : _renderList)
r.Render(); // this code is specific to the IRenderable components
}
#Override
public boolean AddToSystem(Component c)
{
boolean succesfullyAdded = false;
if (c instanceof IRenderable)
{
succesfullyAdded = true;
_renderList.add((IRenderable) c);
} else
throw new RuntimeException("ERROR - " + c.Name() + " doesn't implement IRenderable interface!");
return succesfullyAdded;
}
}
Sure, assuming that all your components implement IComponent use something like this:
interface ISystem<ComponentType extends IComponent> {
public boolean AddToSystem(ComponentType c);
}
If you do not want to have a hard type dependency, you can remove the extends IComponent, but it will make handling lists of systems harder.
I think you need something like this
private static abstract class AbstractClass<T> {
final List<T> objects = new ArrayList<T>();
}
private static class ComponentHolder extends AbstractClass<Component> {
public void add(final Component c) {
objects.add(c);
}
public Component getComponent(final int index) {
return objects.get(index);
}
}
In your example, it would be something like this:
abstract class BaseSystem<T> implements ISystem
{
protected List<T> _componentList = new ArrayList<T>();
}
class RenderSystem extends BaseSystem<IRenderable>
{
void Update()
{
for (IRenderable r : _componentList)
r.Render(); // this code is specific to the IRenderable components
}
#Override
public boolean AddToSystem(Component c)
{
boolean succesfullyAdded = false;
if (c instanceof IRenderable)
{
succesfullyAdded = true;
_componentList.add((IRenderable) c);
} else
throw new RuntimeException("ERROR - " + c.Name() + " doesn't implement IRenderable interface!");
return succesfullyAdded;
}
}
I'm not quite sure how to ask this question without posting the whole code here (it's quite a bit), but I'll try my best.
I have an enum class which implements an interface. The purpose of the whole program is to represent a bunch of integer numbers in Fields. So there is a concrete class TrueField which is derived from abstract class AbstractField that has the implementation of a method called boolean sameAs(Field that). That method also exists (it has to, because of the interface) in the enum class:
enum SimpleField implements Field{
Empty(),Zero(0),Binary(0,1),Unsigned(Integer.MAX_VALUE);
private Field simpleField;
SimpleField(int... intArray){
simpleField = new TrueField(intArray);
}
#Override
public boolean sameAs(Field that){
return that.sameAs(simpleField);
}
}
Implementation from TrueField:
public class TrueField extends AbstractField{
private final int[] intArray;
TrueField(int... thatArray){
intArray = thatArray;
}
#Override
public int at(int index){
if(index<0 || index>=intArray.length){
throw new IndexOutOfBoundsException();
}
return intArray[index];
}
#Override
public int length(){
return intArray.length;
}
...
AbstractField:
public abstract class AbstractField implements Field{
#Override
public abstract int length();
#Override
public boolean sameAs(Field that){
if(that==null)
throw new RuntimeException("that is null");
boolean result = true;
if(length()==that.length()){
for(int i=0;i<length();i++){
if(at(i)!=that.at(i))
result = false;
}
}
else
result = false;
return result;
}
#Override
public String toString(){
String result = "";
for(int i=0;i<length();i++){
result += at(i);
if(length()-i>1)
result += ",";
}
return "["+result+"]";
}
}
My question is, when I do something like this in my main method:
Field sf = SimpleField.Binary;
Field sf2 = SimpleField.Binary;
Field tf = new TrueField(1,2);
System.out.println(sf.sameAs(sf2));
...obviously the method sameAs in the enum class gets called. But why isn't it calling itself again so it is recursive? As there is dynamic binding because of the interface the JVM sees that sf is the dynamic type SimpleField.Binary and the static type Field. I don't quite understand what's going on and why it isn't calling itself again. I hope I've explained my question clear enough.
It's not recursive because your sameAs method in the SimpleField enum calls the sameAs method of the parameter object, which is not a SimpleField, it's a TrueField.
So the sameAs method is being run as declared in the Field class.
On further inspection, it could be recursive, but only if the declaration in the TrueField class was recursive also, which we can see that it is not, now that this code has been added above.
The method isn't recursive because it's not calling itself.
#Override
public boolean sameAs(Field that){
return that.sameAs(simpleField);
}
This method is using the argument to call sameAs. The argument may very well be the same enum, but it's still not calling itself.
This is an example of a simple recursive method:
public long factorial(int value) {
return value == 0 ? 1 : factorial(value-1);
}
In this, there's no extra reference to use to call the method again; I'm just invoking it once more with a slight change in parameters.
I have imported an API which includes an Enumeration. Now in a different class, I need to invoke a method which takes Enumeration as argument.
getValueDateByTenorType(Enumeration tenure)
But I have no idea how can I pass Enumeration as we cannot instantiate an Enumeration.
If the enum is in the same class you can pass the enum as shown below.
public class CollegeTenure{
public enum TENURE{
HALF_YEARLY, FULL_PROFESSORSHIP;
}
public void getValueDateByTenorType(TENURE tenure){
if( TENURE.HALF_YEARLY.equals( tenure ) ) {
System.out.println("Half Yearly tenure");
} else if( TENURE.FULL_PROFESSORSHIP.equals( tenure ) ) {
System.out.println("Full Professorship tenure");
}
}
public static void main(String[]args) {
CollegeTenure collegeTenure = new CollegeTenure();
collegeTenure.getValueDateByTenorType(TENURE.HALF_YEARLY);
}
}
enum can also be defined in another class as public
public class Constants{
public enum TENURE{
HALF_YEARLY, FULL_PROFESSORSHIP;
}
}
public class CollegeTenure2{
public void getValueDateByTenorType(Constants.TENURE tenure){
if( Constants.TENURE.HALF_YEARLY.equals( tenure ) ) {
System.out.println("Half Yearly tenure");
} else if( Constants.TENURE.FULL_PROFESSORSHIP.equals( tenure ) ) {
System.out.println("Full Professorship tenure");
}
}
public static void main(String[]args) {
CollegeTenure2 collegeTenure2 = new CollegeTenure2();
CollegeTenure2.getValueDateByTenorType(Constants.TENURE.FULL_PROFESSORSHIP);
}
}
It depends on what you want to do with that Enumeration/Function, (provide more information for a more detailed answer) but most generally speaking, you have either to use any existing class that implements the Enumeration interface, (e.g. Collections.enumeration(myList)) or you have to build one on your own. This would be done as follows:
// User defined type specific Enumeration
// implements java.util.Enumeration Interface
class MyEnumeration<T> implements Enumeration<T>
{
#Override
public boolean hasMoreElements()
{
// provide boolean function to check if your Enumeration
// has more elements
return false;
}
#Override
public T nextElement()
{
// provide function that returns the next element
return null;
}
}
This class can then be passed to your API function (yet, you still have to know what is done inside this function to know what your Enumeration should contain):
getValueDateByTenorType(new MyEnumeration<String>());
You can add as many functions as you want to create or modify your Enumeration class, but you have to provide the two interface methods hasMoreElements and nextElement. For more information, review the documentation about Enumerations
and Interfaces.
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.
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.