OOP problem while creating an app HalvingCarousel - java

I have a superclass called DecrementCarousel which has a method that returns an object called CarouselRun. CarouselRun has its own methods which I need to override in HalvingCarousel, but I don't know how. DecrementCarousel:
public class DecrementingCarousel {
static int [] arr ;
static int capacity;
int counter = 0;
boolean alreadyExecuted = false;
boolean alreadyRun = false;
public DecrementingCarousel(int capacity) {
DecrementingCarousel.capacity = capacity;
arr = new int[capacity];
}
public boolean addElement(int element){
if (alreadyExecuted) return false;
if (counter < capacity && element > 0) {
arr[counter] = element;
counter++;
return true;
}
return false;
}
public CarouselRun run(){
alreadyExecuted = true;
if (alreadyRun) return null;
alreadyRun = true;
return new CarouselRun();
}
}
Here are methods in CarouselRun:
public class CarouselRun {
int position = 0;
public int next() {
int count = 0;
while (count < arr.length && arr[position %= arr.length] <= 0) {
position++;
count++;
}
if (count == arr.length) return -1;
return arr[position++]--;
}
public boolean isFinished() {
for (int var: arr) {
if (var > 0) return false;
}
return true;
}
}
How to override these CarouselRun methods in a subclass called HalvingCarousel? According to the task HalvingCarousel can only extend DecrementCarousel

To override behaviour of CarouselRun you need a child class, overriding its' methods. Then you need to override DecrementingCarousel.run() in order to return the subclass of CarouselRun.
public class AnotherCarouselRun extends CarouselRun {
#Override
public int next() {
//override behaviour as needed
return 0;
}
#Override
public boolean isFinished() {
//override behaviour as needed
return false;
}
}
Override methods in AnotherCarouselRun to suit your needs.
Then override behaviour of DecrementingCatousel.run()
public class HalvingCarousel extends DecrementingCarousel {
public HalvingCarousel(int capacity) {
super(capacity);
}
#Override
public CarouselRun run() {
//do other stuff
return new AnotherCarouselRun();
}
}
AnotherCarouselRun is a CarouselRun, so you are abiding to the contract of run(). Another option is to use anonymous class:
public class HalvingCarousel extends DecrementingCarousel {
public HalvingCarousel(int capacity) {
super(capacity);
}
#Override
public CarouselRun run() {
//do other stuff
return new CarouselRun() {
//this is anonymous class
#Override
public int next() {
//override behaviour as needed
return 0;
}
#Override
public boolean isFinished() {
//override behaviour as needed
return false;
}
};
}
}
This is virtually the same as first option, but you are subclassing CarouselRun as anonymous class. They are mostly used when you need the class only once.

Inheritance
This can be done like any other simple inheritance.
You just need to declare the class HavingCarousel as a child of CarouselRun using the extends keyword and then use annotation #Override to declare that you want to override the methods of the parent class.
Parent class:
public class CarouselRun {
int position = 0;
public int next() {
System.out.println("Carousel run implementation of next()");
return 1;
}
public boolean isFinished() {
System.out.println("Carousel run implementation of isFinished()");
return true;
}
}
Child class:
public class HalvingCarousel extends CarouselRun{
#Override
public int next() {
System.out.println("HavingCarousel implementation of next()");
return 2;
}
#Override
public boolean isFinished() {
System.out.println("HavingCarousel implementation of isFinished()");
return true
}
}
Interfaces
Looking at your code it could also be worth exploring interfaces instead of inheritance. Interfaces are generally more flexible and a class can implement many interfaces while it can only inherit from one parent class so interfaces should be used if there are no strong reasons opposing that like for example a huge portion of shared code which as far as I can see you will not be having.
Interface for a carousel
public interface ICarousel {
public int next();
public boolean isFinished();
}
CarouselRun implements the interface:
public class CarouselRun implements ICarousel {
int position = 0;
#Override
public int next() {
System.out.println("Carousel run implementation of next()");
return 1;
}
#Override
public boolean isFinished() {
System.out.println("Carousel run implementation of isFinished()");
return true;
}
}
HalvingCarousel implements the interface:
public class HalvingCarousel implements ICarousel{
#Override
public int next() {
System.out.println("HavingCarousel implementation of next()");
return 2;
}
#Override
public boolean isFinished() {
System.out.println("HavingCarousel implementation of isFinished()");
return true;
}
}
Further Reading
From reading your code I believe that you still need to read more on basic Java concepts like interfaces, classes, inheritance, static vs instance attributes and modifiers. For example I can't see why you would declare your array arr as static but then initialize it in the constructor and then apparently you are trying to access the array arr in a totally unrelated instance of class CarouselRun. This will not work and it does not really make sense, but as these are basic concepts I cannot explain all of this here.

Related

When to use super or override in methods when you extend from a class?

Hi I'm new to java and I currently have two classes(useForce and Attack) that are working fine but these two classes share a lot of code.To reduce duplicated code I extended use Force class from Attack class but I'm not sure how to modify the code?
For example in my attack.java
public class Attack extends SWAffordance implements SWActionInterface {
some code here...
#Override
public boolean canDo(SWActor a) {
SWEntityInterface target = this.getTarget();
return !a.isDead() && target.getHitpoints()>0;
}
#Override
public void act(SWActor a) {
SWEntityInterface target = this.getTarget();
boolean targetIsActor = target instanceof SWActor;
SWActor targetActor = null;
int energyForAttackWithWeapon = 1;//the amount of energy required to attack with a weapon
if (targetIsActor) {
targetActor = (SWActor) target;
}
But the same two methods in my useForce.java is
public class UseForce extends Attack {
some code here....
#Override
public boolean canDo(SWActor a) {
return a.getForcepoints()>=minUsePoints;
}
#Override
public void act(SWActor a) {
SWEntityInterface target = this.getTarget();
boolean targetIsActor = target instanceof SWActor;
SWActor targetActor = null;
int energyForForceAttack = 2;//the amount of energy required to use force
if (targetIsActor) {
targetActor = (SWActor) target;
}
As you can see these two share many similar lines of code in act method except in Attack.java int energyForAttackWithWeapon = 1 whereas in useForce int energyforAttackWithWeapon=2...
How do I use super or override to reduce the lines of duplicated code?Any help will be appreciated.
EDIT:If I use a thirdparty class to extract the duplicated code, how do I do it because Attack already extends from SWAffordance?
The template method pattern could help to solve your duplication issue.
It allows to define a common algorithm in a base class while leaving the subclasses to custom some parts of the algorithm.
So define both common concrete operations and custom operations to define by subclasses in an abstract class : AbstractAttack.
public abstract class AbstractAttack extends SWAffordance implements SWActionInterface {
public abstract int getEnergyForAttack();
public abstract boolean canDo(SWActor a);
public void act(SWActor a) {
SWEntityInterface target = this.getTarget();
boolean targetIsActor = target instanceof SWActor;
SWActor targetActor = null;
int energyForAttack = getEnergyForAttack();
... // use energyForAttack
if (targetIsActor) {
targetActor = (SWActor) target;
}
}
}
Now Attack and Other subclasses inherit from AbstractAttack to benefit from concrete operations and also implement theirs own specificities :
public class DefaultAttack extends AbstractAttack {
#Override
public boolean canDo(SWActor a) {
SWEntityInterface target = this.getTarget();
return !a.isDead() && target.getHitpoints()>0;
}
#Override
public int getEnergyForAttack(){
return 1;
}
}
public class UseForce extends AbstractAttack {
#Override
public boolean canDo(SWActor a) {
return a.getForcepoints()>=minUsePoints;
}
#Override
public int getEnergyForAttack(){
return 2;
}
}

Enumeration interface. Default methods implementation

Good evening, consider the following:
public class TestEnum implements Enumeration<String> {
private Enumeration<String> files;
private TestEnum(Vector<String> files) {
this.files = files.elements();
}
public Enumeration<String> getFiles() {
return files;
}
#Override
public boolean hasMoreElements() {
return files.hasMoreElements();
}
#Override
public String nextElement() {
return files.nextElement();
}
public static void main(String[] args) {
Vector<String> vector = new Vector<>();
vector.add("1");
vector.add("2");
vector.add("3");
vector.add("4");
vector.add("5");
TestEnum obj = new TestEnum(vector);
while(obj.getFiles().hasMoreElements()) {
System.out.println(obj.getFiles().nextElement());
}
}
}
I don't understand, where is nextElement() and hasMoreElements() methods default implementation when operating whit enumeration of strings?
I know that methods implementation should be created on programmers own and it have been created , but in line:
return files.nextElement();
I call the method nextElement() on "files" object that has another implementation? If method has my implementation then it should be call nextElement() indefinitely? Or I'm wrong?
Sorry, guys, I have found it:
public Enumeration<E> elements() {
return new Enumeration<E>() {
int count = 0;
public boolean hasMoreElements() {
return count < elementCount;
}
public E nextElement() {
synchronized (Vector.this) {
if (count < elementCount) {
return elementData(count++);
}
}
throw new NoSuchElementException("Vector Enumeration");
}
};
}
In Vector class

how to convert this ArrayListClass to abstract class

I am learning Java and don't understand why this code generates the following error: "ArrayListClass is abstract; cannot be instantiated. Help would be appreciated.
import java.util.*;
public class ArrayListClass {
protected Object[] list;
protected int maxSize;
protected int length;
public ArrayListClass() {
maxSize = 100;
length = 0;
list = new Object[maxSize];
}
public ArrayListClass(int size) {
maxSize = size;
list = new Object[maxSize];
length = 0;
}
public boolean isEmpty() {
return length == 0;
}
public boolean isFull() {
if (length == maxSize)
return true;
else
return false;
}
public int listSize() {
return length;
}
public int maxListSize(){
return maxSize;
}
public void print() {
System.out.print("The list contains:");
for(int i = 0; i < length; i++)
System.out.print(list[i] + " ");
System.out.println();
}
public boolean isItemAtEqual(int location, Object item) {
return (list[location].equals(item));
}
public void insertEnd(Object item) {
if(!isFull())
list[length++] = item;
}
public static void main(String [] args) {
ArrayListClass dac = new ArrayListClass(5);
dac.insertEnd(4);
dac.insertEnd(5);
dac.insertEnd(6);
dac.print();
System.out.println("dac.isItemAtEqual(0,9)"+dac.isItemAtEqual(0,9));
System.out.println("dac.isItemAtEqual(1,9)"+dac.isItemAtEqual(1,9));
}
}
You can not instantiate any abstract class in any programming language. Basic construct of abstract is, it is merely blueprint, not a real object. It provides the template of a class and will provide the form or outline of the class to the concrete classes that implement the class ('extend' the class...)
So you can not instantiate ArrayListClass, as this gives a blueprint. If you extend this class say DerievedArrayListClass extends ArrayListClass, then you will be able to instantiate DerievedArrayListClass .
package com;
abstract class ArrayListClass{
protected Object [] list;
protected int maxSize;
protected int length;
public ArrayListClass(){
maxSize = 100;
length = 0;
list = new Object [maxSize];
}
public ArrayListClass(int size){
maxSize=size;
list=new Object [maxSize];
length=0;
}
public boolean isEmpty(){
return length==0;
}
public boolean isFull(){
if(length==maxSize)
return true;
else
return false;
}
public int listSize(){
return length;
}
public int maxListSize(){
return maxSize;
}
abstract void print();
public boolean isItemAtEqual(int location, Object item)
{
return (list[location].equals(item));
}
public void insertEnd(Object item){
if(!isFull())
list[length++] = item;
}
}
public class ArrayListClassImpl extends ArrayListClass{
public ArrayListClassImpl(int i) {
super(i);
}
public void print(){
System.out.print("The list contains:");
for(int i = 0; i < length; i++)
System.out.print(list[i] + " ");
System.out.println();
}
public static void main(String [] args){
ArrayListClass dac = new ArrayListClassImpl(5);
dac.insertEnd(4);
dac.insertEnd(5);
dac.insertEnd(6);
dac.print();
System.out.println("dac.isItemAtEqual(0,9)"+dac.isItemAtEqual(0,9));
System.out.println("dac.isItemAtEqual(1,9)"+dac.isItemAtEqual(1,9));
}
}
Your code is fine . it is getting compiled and executed without any error on my eclipse and output is :
The list contains:4 5 6
dac.isItemAtEqual(0,9) false
dac.isItemAtEqual(1,9) false
If you convert the class to abstract, you must create a separate class that implements your abstract class.
The implementing class must override the unimplemented methods in the abstract class and can optionally override any or all of implemented methods in the abstract class
An abstract class can have a *mix of implemented and unimplemented methods. An interface class can only contain unimplemented methods.
You instantiate the class that implemenents the abstract class, but you can't instantiate the abstract class itself, because abstract classes, and interface classes are considered templates or blueprints that describe the form that the implementation must follow. It's like a recipe. You can't bake the recipe itself, you must bake the ingredients.
Working example of creating, implementing and instantiating an abstract Java class...
Shape.java: abstract class
public abstract class Shape { // Indicates this is an abstract class
protected static String shapeType = "generic shape";
abstract void draw(); // Implementing class *MUST* provide (due to 'abstract' keyword)
void logGreeting() { // Children can *optionally* override this implementation
System.out.println("I want to say hello");
}
void logDescription() { // Children can *optionally* override this implementation
System.out.println("This shape is a " + shapeType);
}
}
Circle.java: implementing class
public class Circle extends Shape { // Extends (e.g. implements) abstract class
public Circle() {
shapeType = "Circle";
}
public void logGreeting() { // Overrides implementation already in abstract class
System.out.println("This is my overridden greeting message");
}
public void draw() { // Provides implementation for *unimplemented* abstract method
// This is a NOP for example only (normally you'd put code here)
}
}
TestAbstract.java: instantiating class
public class TestAbstract extends Circle {
public static void main(String args[]) {
Circle circle = new Circle(); // instantiates implementing class
circle.logGreeting();
circle.logDescription();
circle.draw();
}
Compile the code:
javac Shape.java
javac Circle.java
javac TestAbstract.java
Execute the code:
java TestAbstract.java
Output:
This is my overridden greeting message
This shape is a Circle

How is having a wrapper class equals composition as described Joshua Bloch?

I am reading the book effective java by Joshua Bloch. on the item 16 of "favor composition over inheritance", he gives an example of using HashSet and querying how many elements have been added since it was created(not to be confused with current size, which goes down when an element is removed). he provided the following code and here the getAddCount return 6, which I can understand. This should return 3 actually. (this is because HashSet's addAll method is implemented on top of its add method)
import java.util.HashSet;
public class InstrumentedHashSet<E> extends HashSet<E> {
// The number of attempted element insertions
private int addCount = 0;
public InstrumentedHashSet() {
}
public InstrumentedHashSet(int initCap, float loadFactor) {
super(initCap, loadFactor);
}
#Override
public boolean add(E e) {
addCount++;
return super.add(e);
}
#Override
public boolean addAll(Collection<? extends E> c) {
addCount += c.size();
return super.addAll(c);
}
public int getAddCount() {
return addCount;
}
public static void main(String[] args) {
InstrumentedHashSet<String> s = new InstrumentedHashSet<String>();
s.addAll(Arrays.asList("Snap", "Crackle", "Pop"));
System.out.println(s.getAddCount());
}
}
Now he explains a way to fix this, using wrapper classes (composition and forwarding). here is where I am having hard time to understand. he provides the following two classes
public class ForwardingSet<E> implements Set<E> {
private final Set<E> s;
public ForwardingSet(Set<E> s) {
this.s = s;
}
public void clear() {
s.clear();
}
public boolean contains(Object o) {
return s.contains(o);
}
public boolean isEmpty() {
return s.isEmpty();
}
public int size() {
return s.size();
}
public Iterator<E> iterator() {
return s.iterator();
}
public boolean add(E e) {
return s.add(e);
}
public boolean remove(Object o) {
return s.remove(o);
}
public boolean containsAll(Collection<?> c) {
return s.containsAll(c);
}
public boolean addAll(Collection<? extends E> c) {
return s.addAll(c);
}
public boolean removeAll(Collection<?> c) {
return s.removeAll(c);
}
public boolean retainAll(Collection<?> c) {
return s.retainAll(c);
}
public Object[] toArray() {
return s.toArray();
}
public <T> T[] toArray(T[] a) {
return s.toArray(a);
}
#Override
public boolean equals(Object o) {
return s.equals(o);
}
#Override
public int hashCode() {
return s.hashCode();
}
#Override
public String toString() {
return s.toString();
}
}
AND
import java.util.*;
public class InstrumentedSet<E> extends ForwardingSet<E> {
private int addCount = 0;
public InstrumentedSet(Set<E> s) {
super(s);
}
#Override
public boolean add(E e) {
addCount++;
return super.add(e);
}
#Override
public boolean addAll(Collection<? extends E> c) {
addCount += c.size();
return super.addAll(c);
}
public int getAddCount() {
return addCount;
}
public static void main(String[] args) {
InstrumentedSet<String> s = new InstrumentedSet<String>(
new HashSet<String>());
s.addAll(Arrays.asList("Snap", "Crackle", "Pop"));
System.out.println(s.getAddCount());
}
}
how this works? In the main method, I create an instance of HashSet and using addAll method, I add all the elements of list. but the HashSet invokes its addAll method (which in turn uses its add method), which should be the same as in the first in correct example and I should get value of 6, however this gives me 3.
In
public class InstrumentedHashSet<E> extends HashSet<E> {
you're adding directly to the HashSet because the addAll() is delegating to the super implementation
InstrumentedHashSet<String> s = new InstrumentedHashSet<String>();
s.addAll(Arrays.asList("Snap", "Crackle", "Pop"));
System.out.println(s.getAddCount());
The addAll() internally calls add() which defers to your #Override implementation of add() because of polymorphism
#Override
public boolean add(E e) {
addCount++;
return super.add(e);
}
that increments the count and prints 6 (3 + 1 + 1 + 1).
In
public class InstrumentedSet<E> extends ForwardingSet<E> {
you are adding to
private final Set<E> s;
because the addAll() is delegating to it, so
public static void main(String[] args) {
InstrumentedSet<String> s = new InstrumentedSet<String>(
new HashSet<String>());
s.addAll(Arrays.asList("Snap", "Crackle", "Pop"));
System.out.println(s.getAddCount());
}
and prints 3. Here the add() is being called on the Set<E> s, not on your instance.
The conclusion is that if you are inheriting, you need to understand the side-effects. Do the super method calls invoke any other method calls internally? If so, you need to act appropriately.
Inheritance (start from bottom)
s.add() // s is your InstrumentedHashSet instance, because of polymorphism (inheritance), this adds to the count
this.add() // this is the internal call inside the HashSet#addAll()
super.addAll(...) // this calls the HashSet implementation of addAll which calls add() internally
s.addAll(Arrays.asList("Snap", "Crackle", "Pop")); // s is your InstrumentedHashSet instance
Composition
this.add() // this is the internal call to add() inside the Set implementation
s.addAll() // s is the Set<E> instance
super.addAll(...) // this calls the ForwardingSet implementation of addAll()
s.addAll(Arrays.asList("Snap", "Crackle", "Pop")); // s is your InstrumentedSet instance
InstrumentedSet#getAddCount() returns 6 because the size of the array (3) is added twice!
//InstrumentedSet
public boolean addAll(Collection<? extends E> c) {
addCount += c.size(); //here
return super.addAll(c); //and here!
}
super.addAll(c); calls the add() Method.
More detailed:
InstrumentedSet#addAll -> ForwardingSet#addAll (because of super.addAll) -> HashSet#addAll() (because this is what you give it in the main) -> InstrumentedSet#add (because of polymorphism)
If you want a fix: remove addCount += c.size();
InstrumentedSet#addAll returns 3 because it calls this:
InstrumentedSet#addAll() (adds 3) -> ForwardingSet#addAll (because of super) -> HashSet#addAll (because forwardingset has a field of type HashSet) -> HashSet#add

Are we actually instantiating an Abstract class here?

// Concrete implementation built atop skeletal implementation
static List<Integer> intArrayAsList(final int[] a) {
if (a == null)
throw new NullPointerException();
return new AbstractList<Integer>() {
public Integer get(int i) {
return a[i]; // Autoboxing
}
#Override
public Integer set(int i, Integer val) {
int oldVal = a[i];
a[i] = val; // Auto-unboxing
return oldVal; // Autoboxing
}
public int size() {
return a.length;
}
};
}
So far I knew we can not instantiate an abstract class at all . But what aren't we doing the same thing here with return new AbstractList<Integer>() ? I am confused .
No, you are creating an anonymous class. You are subclassing your abstract class and you provide an implementation and instantiate it at the same time.
If you try this:
return new AbstractList<Integer>();
you will get an error since you won't be providing a concrete implementation.
If you are confused you can always check out the official tutorials. Here it is:
Java Inner Classes
You are creating an anonymous class which is inheriting the abstract class.
You need to implement all abstract methods of the Abstract class into the anonymous class.
No, it is not instantiating an abstract class, since the code provides an implementation to that class. It is like an anonymous inner class.
Just as information, all types of inner classes generates a .class file after the compilation process. So, the code:
Test.java
public class Test {
abstract class Foo {
abstract void foo();
}
public Foo bar() {
return new Foo() {
#Override
void foo() {
System.out.println( "foo!!!" );
}
};
}
public static void main( String[] args ) {
new Test().bar().foo();
}
}
Will generate:
Test.class: The public class of the file (Test.java)
Test$Foo.class: The abstract inner class inside the Test class.
Test$1.class: The anonymous inner class coded inside the bar method.
No, you are creating an anonymous class.
Your Code:
return new AbstractList<Integer>() {
public Integer get(int i) {
return a[i]; // Autoboxing
}
#Override
public Integer set(int i, Integer val) {
int oldVal = a[i];
a[i] = val; // Auto-unboxing
return oldVal; // Autoboxing
}
public int size() {
return a.length;
}
};
Is Equivilent to:
...
return new myNewClass()
...
public class myNewClass extends AbstractList<Integer>{
public Integer get(int i) {
return a[i]; // Autoboxing
}
#Override
public Integer set(int i, Integer val) {
int oldVal = a[i];
a[i] = val; // Auto-unboxing
return oldVal; // Autoboxing
}
public int size() {
return a.length;
}
}

Categories

Resources