I am trying to better my understanding Java interfaces and have the following problem with some very basic, code.
The following creates two classes which implement the same interface. I then create two ArrayLists to hold objects of these two classes. I then want to create a single enhanced-for loop which goes through each list and performs the method originally defined in the interface.
I thought that i could use a loop which instead of taking in a specific class type as its parameter could use an Interface type instead, This would then allow me to use any class which implements that interface, but it seems i have made mistake.
How would i go about creating a for loop which allowed only classes which implement an interface to be operated on?
interface Valueing{
double getValue();
}
class Coin implements Valueing
{
private double coinVal = 0.0;
Coin(double initVal){
coinVal = initVal;
}
public double getValue(){
return this.coinVal;
}
}
class Note implements Valueing
{
private int noteVal = 0;
Note(int initVal){
noteVal = initVal;
}
public double getValue(){
return (double)noteVal;
}
}
public class IFaceBasics{
public static void main(String[] args){
ArrayList<Coin> myChange = new ArrayList<Coin>();
myChange.add(new Coin(0.01));
double totalChange = sumValues(myChange);
ArrayList<Note> myNotes = new ArrayList<Note>();
myNotes.add(new Note(5));
double totalNotes = sumValues(myNotes);
}
public double sumValues(ArrayList<Valueing> a){
double totalSum = 0;
for(Valueing avg : a)
{
totalSum += avg.getAverage();
}
return totalSum;
}
}
Thanks for any feedback.
You've almost got it right, you'd just need to change
public double sumValues(ArrayList<Valueing> a){
to
public double sumValues(ArrayList<? extends Valueing> a){
<? extends Valueing> means "Valueing or any of its sub-types", so this would let the method accept an ArrayList<Coin> or ArrayList<Note> as well as ArrayList<Valueing>.
Related
I've been trying to figure out if theres a way to pass a string to a factory or constructor and create the correct object without having to map the string to an object, or without having a bunch of if/else statements or switch statements.
Keep in mind, this is a simple example so I can apply what I learn to more complicated situations in web apps, etc.
let's take a simple calculator app, written in JAVA, as an example
assuming this is command line, and a person can pass in 3 values
- first number
- math operation (+ , - , / , x)
- second number
and we have an interface
public interface ArithmeticOperation {
public double performMathOperation(double firstNum, double secondNum);
}
with 4 classes that implement it
public class AdditionOperation implements ArithmeticOperation {
public double performMathOperation(double firstNum, double secondNum) {
return firstNum + secondNum;
}
}
// public class Subtraction operation returns firstNum - secondNum
// etc...
and we have our actual Calculator class and UserInput class
public class UserInput {
public UserInput(double firstNum, double secondNum, String operation) {
this.firstNum = firstNum;
// etc...
}
}
public class Calculator {
public UserInput getInput() {
// get user input, and return it as a UserInput object
// return a UserInput object
}
public performOperation() {
UserInput uInput = getInput();
double answer = ArithmeticOperationFactory
.getSpecificOperation(uInput.operation)
.performMathOperation(uInput.firstNum, uInput.secondNum);
// send answer back to user
}
}
finally, the place where the question mostly revolves around, the factory
public class ArithmeticOperationFactory {
public static ArithmeticOperation getSpecificOperation(String operation) {
// what possibilities are here?
// I don't want a map that maps strings to objects
// I don't want if/else or switch statements
// is there another way?
}
}
also, if theres a better way to architect a system like this or a design pattern that can be applied, please share. I'm really trying to learn some good object oriented design
There is a different way. I'm not sure it's better.
We have to go back to the interface and add another method so that the class can identify the operator.
public interface ArithmeticOperation {
public boolean isOperator(String operator);
public double performMathOperation(double firstNum, double secondNum);
}
We code the concrete methods like this:
public class AdditionOperation implements ArithmeticOperation {
#Override
public boolean isOperator(String operator) {
return operator.equals("add");
}
#Override
public double performMathOperation(double firstNum, double secondNum) {
return firstNum + secondNum;
}
}
We put all of the ArithmeticOperation classes in a List
List<ArithmeticOperation> operations = new ArrayList<>();
operations.add(new AdditionOperation());
...
Finally, we perform the operation like this.
double answer = 0D;
for (ArithmeticOperation operation : operations) {
if (operation.isOperator(currentOperator) {
answer = operation.performMathOperation(firstNum, secondNum);
break;
}
}
I would implement it using switch case. This is Factory Design Pattern.
class ArithmeticOperationFactory {
public static ArithmeticOperation getSpecificOperation(String operation) {
switch (operation) {
case "ADD":
return new AdditionOperation();
case "SUBTRACT":
return new SubtractOperation();
// You can define the rest of the operation here.
default:
throw new UnsupportedOperationException("OPeratino is not supported: " + operation);
}
}
}
You can also define Enum for each operation and use them in switch-case.
There is no method which is much better than solutions you have seen before. You can only make it slightly more elegant. In essence you can have:
Bunch of if/else/switch (probably least elegant but fast)
if("typeAsString").equals("operation"){
return new SomeType()
}
Map
Map<String, Class<? extends YourType> map = new HashMap<>();
You can make it bit better with dependency injection or you can make each subclass to add its own entry in this map. I'd favor keeping configuration away from factory class and moving it to subclasses.
Kind of chain of responsibility
You have to create Collection of all your subtypes. Each subtype has to have method like isItCorrectSubtype(). Client class has to iterate through whole collection and check which implementation is correct
#Autowired
List<InterfaceOfYourTypes> allSubtypes;
..
public void doStuff(){
for(InterfaceOfYourTypes subtype: allSubtypes){
if(subtype.isCorrectSubtype()){
//create instance
}
}
}
What are you asking for is a mapping operation because you have a String as input and you want an Object implementing and interface (ArithmeticOperation) back. If a mpa dose not fit you needs you must "configure" the mapping in a different way, this is my suggestion:
Change the interface to
public interface ArithmeticOperation {
public double performMathOperation(double firstNum, double secondNum);
public double getName();
}
Your add operation will result as the following one:
public class AdditionOperation implements ArithmeticOperation {
public double performMathOperation(double firstNum, double secondNum) {
return firstNum + secondNum;
}
public double getName() {
return "+";
}
}
In you method factory all you need is to find all the classes implementing the ArithmeticOperation interface; something like:
public class ArithmeticOperationFactory {
private List<ArithmeticOperation> availableOperations=null;
//to be called at application startup
public static void findAvailableOperations() {
// a strategy for finding implementations that fills
// availableOperations
}
public static ArithmeticOperation getSpecificOperation(String operation) {
for (ArithmeticOperation arithmeticOperation : availableOperations) {
if (operation.equalsIngoreCase(arithmeticOperation.getName)) {
return arithmeticOperation;
}
}
}
Here are some method you can yous to implement findAvailableOperations:
If you are using Spring you can get the api getBeansOfType and retrieve all the implementations (I'm assuming you are configuring the concrete operations as Spring beans).
If you are not using spring you can scan the classpath in order to find the classes that implement your interface; you can start from this project or this one.
Another solution is to put the implementation class names into a file (.properties, .xml, .json, etc), read the class names and create them via reflection.
You could use a Factory like this
public class ArithmeticOperationFactory {
public static ArithmeticOperation getSpecificOperation(String operation) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
return (ArithmeticOperation) resolveClass(operation).newInstance();
}
private static Class resolveClass(String className) throws ClassNotFoundException {
return Class.forName(className);
}
}
I'm working on a java based game with a friend and I've noticed he's taking an approach that concerns me, in terms of maintainability.
For a class representing a playable Character, instead of just creating 1 method which sets an object's property, he's creating separate methods which set the property to a specific value.
Which of these 2 options would be the best to follow going forward?
Option 1
public void runFast() {
this.character.speed = 5.0f
}
public void walk() {
this.character.speed = 2.0f
}
public void stop() {
this.character.speed = 0.0f;
}
Option 2
public void setSpeed(float speedTemp) {
this.character.speed = speedTemp;
}
Why not use an enum to set the speed - then you can still have
void setSpeed(Speed speed) {
this.character.speed = speed.getAmount();
}
with:
enum Speed {
FAST(5.0f), WALK(2.0f), STOP(0.0f);
private final float amount;
private Speed(flaot a) { this.amount = a; }
public float getAmount() {
return amount;
}
}
That way, you can quickly update the values, but still have a predefined amount. Its flexible and easy to maintain. You might want to save the enum instead of the float.
My Solution would be to use Enums instead,
it is cleaner and has more context and easily extensible if you have more to do with your speed maxHeartRate in the future.
public class Character {
private Speed speed;
public Speed getSpeed() {
return speed;
}
public void setSpeed(Speed speed) {
this.speed = speed;
}
};
public enum Speed {
STOP(0),
RUN(5.5),
WALK(2.5);
double value;
Speed(double value) {
this.value = value;
}
public double getValue() {
return value;
}
};
IMHO the best option would be to declare constants/enums, and use the option 2.
Example (constants) :
public static final float STOP = 0.0f;
public static final float WALK = 2.0f;
public static final float FAST = 5.0f;
setSpeed(STOP|WALK|FAST);
Example (enums) :
public enum Speed
{
FAST(5.5f),
STOP(0),
WALK(2.5f);
float value;
Speed(float pValue)
{
this.value = pValue;
}
public float getValue()
{
return this.value;
}
}
setSpeed(Speed.FAST);
It depends. For example
Are speeds limited to a few predefined values? In that case using an enum would be a good solution.
Is walking / running / stopping going have side effects other than just setting the speed? As a contrived example, starting to run might cause the character to drop an item it's holding, or stopping might cause the character to skid a little. In this case having separate methods might make sense.
Or maybe there are only a few predefined states, but depending on the environment running speed might be different.
What it comes down to is: Which way of conceptually modeling the properties of your character works best for your game logic / physics? Work this out and then base the interface of your classes on that. Don't get too hung up on the exact API early on, this sort of stuff is pretty easy to refactor.
getter and setters are useful when you want that your code is readble and for avoiding that public class fields can be used in the wrong way from another classes.
This example show how is important.
CLASS A:
public class ClassA{
// in the body class
private String fieldClass1;
//classic setter
public void setfieldClass1(String f1)
{
fieldClass1 = f1;
}
}
CLASS B:
public class ClassB{
// in the bodyclass
public String fieldClass2;
//classic setter
public void setfieldClass2(String f2)
{
setfieldClass2 = f2;
}
CLASS C:
public class ClassC{
//in the body of the class this method use class a and class b
public void calc()
{
ClassA aObject = new ClassA();
ClassB bObject = new ClassB();
ClassA.fieldClass1 = 5 + 5; // illegal expression for the compiler and costrain the developer to use setters
ClassB.fieldClass2 = 8 + 8; // legal expression
}
}
This mean that you must define a "modifiers logic" (protected, private, public) before make setters and getters. Define before the modifiers and after define the setters and getters.
If you want to get straight to the problem, skip this paragraph. As practice, I am trying to write a Java program that simulates an economy, and to that end wrote a company class. The idea was to have, say, a dozen of them, wrap their earnings into a normalvariate function, and that would be the economy.
I wrote a separate class to graph the companies' outputs using JFreeChart. However, I can't access the ArrayList that I write the amount of money for each year to from the graphing class. I understand the best way to do this is probably with getters, but it didn't seem to work, so if that is your advice, could you please provide an example? Thanks!
The company:
public class ServiceProvider implements Company {
//Variables
public ArrayList getRecords(){
return records;
}
public ServiceProvider(){
money = 10000;
yearID = 0;
goodYears = 0;badYears = 0;
records = new ArrayList();
id++;
}
public void year() {
yearID++;
if(!getBankrupt()){
spend();
}
writeRecords();
}
public void spend() {
...
}
public void printRecords() {
for(int i=0;i<records.size();i++){
String[] tmp = (String[]) records.get(i);
for(String a:tmp){
System.out.print(a+" ");
}
System.out.print("\n");
}
}
public void writeRecords(){
String[] toWrite = new String[2];
toWrite[0] = String.valueOf(yearID);
toWrite[1] = String.valueOf(money);
records.add(toWrite);
}
public void writeRecords(String toWrite){
String temp = "\n"+yearID+" "+toWrite;
records.add(temp);
}
public boolean getBankrupt(){
boolean result = (money < 0) ? true : false;
return result;
}
}
What I am trying to access it from:
public class grapher extends JFrame {
ArrayList records = s.getRecords();
public grapher(){
super("ServiceProvider");
final XYDataset dataset = getCompanyData();
}
private XYDataset getCompanyData(){
XYSeries series;
for(int i=0;i<s.getRecords().length;i++){ //S cannot be resolved, it's instantiated in the main class.
}
}
}
The main class:
public class start {
public static void main(String[] args) {
ServiceProvider s = new ServiceProvider();
for(int i=0;i<10;i++){
s.year();
}
s.printRecords();
}
}
P.S. Don't tell me what a mess Records are. I know.
Pass the instance of ServiceProvider as an argument to the grapher constructor and then it can pass it as an argument to getCompanyData().
Since the instance is created outside of the grapher class, there is no way for grapher to have the instance of ServiceProvider to work with unless you hand that instance to grapher.
BTW, make sure that whatever you do with that ArrayList in grapher that you don't change it. If you do, you'll be changing it in the ServiceProvider (since it's all just references to the same underlying ArrayList). That's probably not what you want to do. If you do need to change it, make a copy and work with the copy.
Your grapher class is trying to use a variable from the start class(you are making calls to variable s which exists in the start class), without having a reference to the variable. In order for grapher to access that instance, you'll have to pass it in to the grapher class as a paramater in the constructor:
public grapher(ServiceProvider serviceProvider) {
records = serviceProvider.getRecords();
}
In the getCompanyData method, use your class variable records instead of s.
Your grapher class should be as follows
public class grapher extends JFrame {
public grapher(ServiceProvider s){
super("ServiceProvider");
final XYDataset dataset = getCompanyData(s);
}
private XYDataset getCompanyData(ServiceProvider s){
XYSeries series;
for(int i=0;i<s.getRecords().length;i++){
// Do Process of business logic.
}
}
}
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.
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).