I'm working through an exercise sheet regarding interfaces, generics and abstract classes in Java. No matter what way I seem to code it, the class Exercise1 won't work. The question asked are commented in the code. Any help would be appreciated, I'm not sure if the error is in the Exercise one code or the implementation of the interface in the classes Time and Point.
/*Exercise 2
(a) Write an interface Printable which has a single method put whose intention is to display a string representation of any object whose class implements Printable. Check it by compiling it. */
interface Printable {
public void put(Object o);
}
/*(b) Enhance classes Point and Time from Chapter 2 of the notes to implement Printable. Check them by compiling them. */
class Point implements Printable {
static Scanner sc = new Scanner(System.in);
private double x, y; // coordinates
Point(double x, double y){ // all-args constructor
this.x = x; this.y = y;
}
Point(){}; // no-args constructor (defaults apply)
void get() {
x = sc.nextDouble();
y = sc.nextDouble();
}
public String toString() {
return "(" + x + "," + y + ")";
}
double distance(Point r) { // distance from r
double xdist = x-r.x; double ydist = y-r.y;
return(Math.sqrt(xdist*xdist+ydist*ydist));
}
public void put(Object o) {
if(o==null) return;
Point p = (Point)o;
System.out.println(x + ":" + y);
}
}
class Time implements Order, Printable {
private int hours; // 0..23
private int mins; // 0..59
Time() { }
Time (int hours, int mins) {
this.hours = hours;
this.mins = mins;
}
public boolean lte(Object other) { // Note public
if (other==null) return false;
Time t = (Time) other;
return hours*60+mins<=t.hours*60+t.mins;
}
public void put(Object o) {
if(o==null) return;
Time t = (Time)o;
System.out.printf("%02d:%02d\n", t.hours, t.mins);
}
}
/*(c) Write a static method print which takes an array of objects whose class implements Printable, and prints each element in the array, one element per line. Check it by placing it in an otherwise empty class and compiling it. */
//this is the bit that is giving me grief, I've tried :
public class Exercise1 {
static void print(Printable[] a) {
for(int i = 0; i < a.length ; i++) {
a[i].put(); // put(java.lang.Object) in Printable cannot be applied to () //a[i].put();
}
}
public static void main(String[] args) {
Time[] t = new Time[10];
for(int i = 0; i < t.length; i++) {
t[i] = new Time();
}
print(t);
}
}
public interface Order {
boolean lte (Object obj); // Object for max generality
// is this object less than or equal to obj?
}
You want to print this, not some arbitrary object o.
I think the problem is the interface Printable. It doesn't match the question correctly.
to display a string representation of any object whose class implements Printable
This doesn't mean, that the put() method should have a parameter of type Object.
The object here refers to this, the object which class implements Printable. And the method put() should print out a string representation of this. So in the simplest case you can implement it with the help of toString().
interface Printable {
/**
* Display a string representation of this
*/
void put();
}
class Point implements Printable {
// ...
/**
* returns a string representation of this
*/
public String toString() {
return "(" + x + "," + y + ")";
}
public void put() {
// this is the same as System.out.println(this.toString());
System.out.println(this);
}
}
Then you can call put() for every Printable in your array.
What you want to do is make the interface Printable look something like this:
interface Printable {
public void print(); //The name of the method should be similar to the name of the interface
}
Then your classes will work like this:
public class Time implements Printable {
private int hours, minutes;
public void print() {
System.out.println( hours + ":" + minutes );
}
}
For Exercise 1, you would then call print() for each element of the array.
By the way: There's already an interface similar to Order. It's called Comparable, and it looks like this:
public interface Comparable<T> {
public void compareTo(T other); //Returns -1 if less than, 0 if equal, and 1 if greater than other object.
}
If no parameter T is given, it becomes Object.
you might want your Printable method to be print(Object object), not put.
Related
I am trying to pass two variables along to a method and have the method give me back two independent results.
int numX = 5;
int numY = 3;
System.out.println(displayTwiceTheNumber(numX, numY));
}
public static int displayTwiceTheNumber(int numX, int numY) {
int numW, numZ;
numW, numZ = 2 * (numX, numY);
return numW numZ;
}
Java takes it that at numW, numZ = 2 * (numX, numY); that I am trying to redefine numX and numY. How do I phrase the last block to take two variables and give two results?
A single int function can only return 1 int at a time.
If you want to return 2 values, consider calling the function twice or creating a custom object to be used.
You need to change the return type of the function. Currently, the return type is int, so you have to return one integer.
To return two integer, you should consider returning an array or a list or something similar.
public static int[] displayTwiceTheNumber(int numX, int numY){
//your code that do something
int[] ret = {numW, numZ};
return ret;
}
Or knowing that this function would change the value of numW and numZ, you could declare those as global variable. Now, when you call this function, those variable will be changed. Then, you can use numW and numZ subsequently.
public int numW;
public int numZ;
public static void displayTwiceTheNumber(int numX, int numY){
//your code that do something and modifies numW and numZ
}
public static void anotherfunction(){
//after calling displayTwiceTheNumber, numW and numZ would have the appropriate value
//you can now just use numW and numZ directly
}
Overview: Use a tuple. In this example I use an tuple to return more than one result. Tuple means to return more than one result type. In this example I return a tuple of two integer types. My class TupleCustom contains one method function1 which receives two parameters of type integer: x and y. I create a tuple of type integer and return the tuple as a variable. Internally, the precomiler converts the tuple json than back to a tuple with variable Item1, Item2...ItemN in the unit test method.
public class TupleCustom
{
public async Task<Tuple<int, int>> Function1(int x, int y)
{
Tuple<int, int> retTuple = new Tuple<int, int>(x, y);
await Task.Yield();
return retTuple;
}
}
public class TestSuite
{
private readonly ITestOutputHelper output;
public TestSuite(ITestOutputHelper output)
{
this.output = output;
}
[Fact]
public async Task TestTuple()
{
TupleCustom custom = new TupleCustom();
Tuple<int, int> mytuple = await custom.Function1(1,2);
output.WriteLine($" Item1={mytuple.Item1} Item2={mytuple.Item2} ");
}
When I have this problem I create a private utility class for handling the return values. By doing it this way, you can pass various types in the argument list. Aspects of the class can be tailored to your requirements.
public static void main(String [] args) {
int numX = 5;
double numY = 3.0;
Nums n = displayTwiceTheNumber(numX, numY);
System.out.println(n.numX);
System.out.println(n.numY);
}
public static Nums displayTwiceTheNumber(int numX, double numY) {
int numW;
double numZ;
// do something with arguments.
// in this case just double them and return.
return new Nums(2*numX, 2*numY);
}
private static class Nums {
int numX;
double numY;
public Nums(int nx, double ny) {
this.numX = nx;
this.numY = ny;
}
public String toString() {
return "(" + numX + ", " + numY +")";
}
}
Prints
10
6.0
I am new to Java and I am trying to write a class with constructors and methods that adds and divides two numbers, and also compares if one object is larger or equal than the other. But I am getting an error: The method plus(int) in the type Compare is not applicable for the arguments (Compare). what's wrong?
Here's the code:
public class Compare {
// fields
private int number;
private int plus;
private double div;
// constructor
public Compare (int n) {
number = n;
}
public int plus (int x) {
return this.number + x;
}
public int div (int x) {
return this.number / x;
}
public boolean isLargerThan (int x) {
return this.number > x;
}
public boolean isEqualTo (int x) {
return this.number == x;
}
public static void main(String[] args) {
Compare n1 = new Compare(9);
Compare n2 = new Compare(4);
Compare sum = n1.plus(n2);
Compare div = n1.div(n2);
boolean check1 = sum.isLargerThan(n1);
boolean check2 = div.isLargerThan(n2);
boolean check3 = div.isEqualto(sum);
}
}
The requirement is to create sum and div objects using Compare constructor that will be equal to n1 plus n2, with plus method or division as applicable.
It may be that here you want a new Compare, containing the sum.
public Compare plus (int x) {
return new Compare(number + x);
}
public Compare plus (Compare x) {
return new Compare(number + x.number);
}
This also is implied by expecting a Compare object, not an int as shown.
With that Compare would become immutable, which is very good, as you then can share objects in different variables without problems (changing one variable's value changing other variables' values).
#Override
public String toString() {
return Integer.toString(number);
}
public int intValue() {
return number;
}
The issue here is for the "plus", "div", "isLargerThan" and "isEqualTo" methods in "Compare" class the argument/return type is of type "int". But in "main" function you are passing the object and expecting object of type "Compare".
To fix it either change the argument/return type to "Compare" for those methods in "Compare" class or pass the "int" value as parameter and get "int" value in "main" function.
The plus and div methods take an int and return an int and you are trying to receive their output in a Compare object. Also, isLargerThan takes an int and not a Compare.
Problem is here :
Compare sum = n1.plus(n2);
Compare div = n1.div(n2);
methods : plus and div return int value not an objet of Class Compare.
public int plus (int x) {
return this.number + x;
}
public int div (int x) {
return this.number / x;
}
Add getter method in Compare Class.
public int getNumber(){
return number;
}
Use below code and try to run:
public static void main(String[] args) {
Compare sum = new Compare(9);
Compare divObj = new Compare(4);
sum.plus(n2);
divObj.div(n2);
boolean check1 = sum.isLargerThan(sum.getNumber());
boolean check2 = divObj.isLargerThan(divObj.getNumber());
boolean check3 = divObj.isEqualto(sum.getNiumber());
}
I have the following Progression class:
/** Generates a simple progression. By default: 0,1,2,3...*/
public class Progression {
// instance variable
protected long current;
/** Constructs a progression starting at zero. */
public Progression() { this(0); }
/** Constructs a progression with a given start value. */
public Progression(long start) { current = start; }
/** Returns the next value of the progression.*/
public long nextValue() {
long answer = current;
advance();
return answer;
}
/** Advances the current value to the next value of the progression */
protected void advance() {
current++;
}
/** Prints the next value of the progression, separated by spaces .*/
public void printProgression(int n) {
System.out.print(nextValue());
for(int j = 1; j < n;j++)
System.out.print(" " + nextValue());
System.out.println();
}
}
How do I redesign the above java Progression class to be abstract and generic, producing a sequence of values of generic Type T, and supporting a single constructor that accepts an initial value?
I understand how to make the above class abstract but I don't see or understand how to translate the class to generics. In particular I don't know how to redesign the advance() method so that it uses java generics to produce a sequence of values of generic Type T.
You can only code what you know to hold for all generic instantiations. Everything else remains abstract. This can be seen by looking at the (added) method getInitial: it would return 0 for a Long, but (perhaps) "A" for a String. Also, nextValue is illuminating: it calls advance (no matter how) but advance is left to the implementation of the instantiation.
public abstract class Progression<T> {
protected T current;
public Progression() { this( getInitial()); }
protected abstract T getInitial();
public Progression(T start) { current = start; }
public T nextValue() {
T answer = current;
advance();
return answer;
}
protected abstract void advance();
public void printProgression(int n) {
System.out.print(nextValue());
for(int j = 1; j < n;j++)
System.out.print(" " + nextValue());
System.out.println();
}
}
Please Note:
I created a post earlier that had this question along with several others, but was told that since I was asking so many questions in the same post, it'd be better to break it up into individual questions. So please do not mark this as a duplicate, yes the instructions are the same and yes the same code is being used, but the question itself is different. Thanks.
I'm working on a program with the following instructions:
Write a class named Octagon that extends GeometricObject and implements the Comparable and Cloneable interfaces. Assume that all 8 sides of the octagon are of equal size. The area can be computed using the following formula
area = (2 + 4/square root of 2) * side * side
Write a program (driver) to read in a series of values from a file, display the area and perimeter, create a clone and compare the object and its clone (based on the area). In addition, your program should compare the current object (just read in) with the first object read in. The program ends when a negative number is read from the file.
Here is the code I have so far, This is my GeometricObject class:
public abstract class GeometricObject {
public abstract double getArea();
public abstract double getPerimeter();
}
My Octagon class:
public class Octagon extends GeometricObject implements Comparable<Octagon> {
private double side = 1.0;
protected native Object clone() throws CloneNotSupportedException;
private static int numberOfObjects = 0;
public Octagon() {
}
public Octagon(double side) {
this.side = side;
numberOfObjects++;
}
public double getSide() {
return side;
}
public void setSide(double side) {
this.side = side;
}
public double getArea() {
return (2 + (4 / (Math.sqrt(2))) * side * side);
}
public double getPerimeter() {
return side * 8;
}
public String toString() {
return "Octagon " + numCreated + ": Area: " + getArea() + "\nPerimeter: "
+ getPerimeter() + "\nClone Compare: " + Cloneable + "\nFirst Compare: "
+ comparisson;
}
public int compareTo(Octagon octagon) {
if(getArea() > octagon.getArea())
return 1;
else if(getArea() < octagon.getArea())
return -1;
else
return 0;
}
public interface Cloneable {
}
}
And my Driver or tester class: (this is where I need the most help)
import java.util.*;
import java.io.*;
public class Driver {
public static void main(String[] args) {
int comparisson = compareTo(octagon);
java.io.File file = new java.io.File("prog7.dat");
Scanner fin = new Scanner(file);
while(fin.hasNext()) {
double side = fin.nextDouble();
if(side < 0.0) break;
Octagon first = new Octagon(side);
System.out.println("Octagon 1: " + first);
}
}
}
And here is the file being used to get the input. Each line is one octagon:
5.0
7.5
3.26
0.0
-1.0
I'm having trouble setting up the compareTo() method. I've never used this before and while I've read the documentation and have a general idea of how it works, I'm having trouble figuring out how to implement it to my specific program.
Along these same lines, I know that the compareTo() method returns an integer value of either -1, 0, or 1 based on whether the current object is smaller, larger, or equal to the object it's being compared with. However, as you can see from the example output, rather than displaying this integer value, I"m supposed to display something like "The first is smaller". I'm pretty sure to do this I would need to assign the return value to a variable and then use if statements to determine what should be printed, but I'm having trouble figuring out how and at what point in my code this should be done?
Based on this line of your requirement: In addition, your program should compare the current object (just read in) with the first object read in. Here's some code to do that. Basically this reads Octagons until a negative number is read, and compares each one with the first Octagon read in.
Octagon first = null;
int i = 0;
while(fin.hasNext())
{
double side = fin.nextDouble();
if(side < 0.0)
break;
Octagon oct = new Octagon(side);
System.out.print("Octagon " + i + ": \"" + oct.toString() + "\"");
if (first == null)
first = oct;
else
{
// Here is where we compare the current Octagon to the first one
int comparison = oct.compareTo(first);
if (comparison < 0)
System.out.print(", less than first");
else if (comparison > 0)
System.out.print(", greater than first");
else System.out.print(", equal to first");
}
Octagon first = new Octagon(side);
System.out.println();
}
int compareTo(Object o)
or
int compareTo(String anotherString)
public class Test {
public static void main(String args[]) {
String str1 = "Strings are immutable";
String str2 = "Strings are immutable";
String str3 = "Integers are not immutable";
int result = str1.compareTo( str2 );
System.out.println(result);
result = str2.compareTo( str3 );
System.out.println(result);
result = str3.compareTo( str1 );
System.out.println(result);
}
}
This produces the following result:
0
10
-10
Also you can check -> http://www.javapractices.com/topic/TopicAction.do?Id=10
I need to modify DataSet to accept Comparable Objects. The tester will not compile and I do not know how to print out the compareTo method. Should I be using an ArrayList for the tester? Thanks ahead of time!
public interface Comparable
{
/**
Compares this object with another.
#param other the object to be compared
#return a negative integer, zero, or a positive integer if this object
is less than, equal to, or greater than, other
*/
int compareTo(Object other);
}
public class DataSetComparable
{
private double sum;
private Object maximum;
private Object minimum;
private int count;
private Comparable comparer;
/**
Constructs an empty data set with a given measurer.
#param aMeasurer the measurer that is used to measure data values
*/
public DataSetComparable(Comparable acomparer)
{
sum = 0;
count = 0;
maximum = null;
minimum = null;
comparer= acomparer;
}
/**
Adds a data value to the data set.
#param x a data value
*/
public void add(Object x)
{
sum = sum + comparer.compareTo(x);
if (count == 0 || comparer.compareTo(maximum) < comparer.compareTo(x))
maximum = x;
if (count == 0 || comparer.compareTo(minimum) > comparer.compareTo(x))
minimum=x;
count++;
}
/**
Gets the largest of the added data.
#return the maximum or 0 if no data has been added
*/
public Object getMaximum()
{
return maximum;
}
/**Gets the smallest of the added data.
*#return the minimum or 0 if no data has been added
**/
public Object getMinimum()
{
return minimum;
}
}
public class String implements Comparable {
private String input;
private int holder;
public String(String aninput){
input= aninput;
holder=0;
}
public String getComparer(){
return input;
}
public String getString(){
return input;
}
public int compareTo(Object other){
String temp= (String) other;
if(input.compareTo(temp)<0){
holder=-1;
}
else if (input.compareTo(temp)== 0) {
holder= 0;
}
else{
holder= 1;
}
return holder;
}
}
public class StringTester{
public static void main (String [] args){
Comparable c = new String();
DataSetComparable data = new DataSetComparable(c);
data.add(new String("Jimmy"));
data.add(new String("Amy"));
data.add(new String("Melissa"));
data.add(new String("Melissa"));
String max = (String) data.getMaximum();
String min = (String) data.getMinimum();
System.out.println("Maximum String = " + max);
System.out.println("Minimum String = " + min);
}
}
More specifically, the error says:
constructor String in class String cannot be applied to given types.
Your code includes this:
public class String implements Comparable {
...
}
Do you realize that there is a standard Java library class called String that gets imported by default into every class? If implement your own class called String you are going to get some very confusing compilation error messages.
I strongly recommend that you change the name of your class to something else; e.g. StringHolder.
Note, technically you could define a class called String. However the rules that Java uses to disambiguate the names of classes are not designed for this use-case ... and you will end up having to refer to java.lang.String by its fully qualified name wherever you use it. And other people reading / modifying your code would find that really awkward / annoying.
It is best to treat the names of classes in the java.lang package as "reserved", and don't define classes with the same (unqualified) name.