Here's the code
class TwoD {
int x, y;
public TwoD(int x, int y) {
super();
this.x = x;
this.y = y;
}
}
class ThreeD extends TwoD {
int z;
public ThreeD(int x, int y, int z) {
super(x, y);
this.z = z;
}
}
class FourD extends ThreeD {
int t;
public FourD(int x, int y, int z, int t) {
super(x, y, z);
this.t = t;
}
}
class coords<T extends TwoD> {
T cordinates;
public coords(T cordinates) {
super();
this.cordinates = cordinates;
}
static void show(coords<? super ThreeD> c) {}
}
public class mainX {
public static void main(String a[]) {
FourD fourD = new FourD(1, 2,3,4);
coords check = new coords(fourD);
coords.show(check);
TwoD twoD = new TwoD(1, 2);
coords check1 = new coords(twoD);
coords.show(check1);
// How this program runs fine with the child and parent subclass objects in show method?
}
}
The method
static void show(coords c)
should only allow Parent class objects ? Why is it allowing child class objects also?
How this program runs fine with the child and parent subhclass objects in show method?
I am confused!
As mentioned by #Thomas in the comments, you're using raw types for your coords. (I could go into detail, but the linked answer explains everything very clearly. Your use case is mainly mentioned in the sections How's a raw type different from using <?> as a type parameter? and A raw type is the erasure of that type.)
If you'd change:
coords check = new coords(fourD);
...
coords check1 = new coords(twoD);
To:
coords<FourD> check = new coords<>(fourD);
...
coords<TwoD> check1 = new coords<>(twoD);
You would get the error you'd expect:
error: incompatible types: coords<TwoD> cannot be converted to coords<? extends ThreeD>
coords.show(check1);
^
PS/off-topic: Class coords should be with a capital C (thus Coords) when following Java's code standards.
Related
This is using Processing 3.5, not every java thing works the same here.
The Bird class is giving me the error saying it needs to implement call(). Isn't it already under the main? I'm not experienced with interfaces so I don't know what exactly is going on here.
public interface FuncCall<A> {
A call();
}
class Bird implements FuncCall{
//Error here ^
//The type FuncCallTest.Bird must implement the inherited abstract method FuncCallTest.FuncCall.call()
//Is this not implemented already under main?
float x, y, size;
ArrayList<FuncCall<Float>> inputs = new ArrayList<FuncCall<Float>>();
public Bird(float x, float y, float size){
this.x = x;
this.y = y;
this.size = size;
}
public void main(String[] args){
FuncCall<Float> getX = new FuncCall<Float>(){
#Override
public Float call(){
return x;
}
};
FuncCall<Float> getY = new FuncCall<Float>(){
#Override
public Float call(){
return y;
}
};
FuncCall<Float> getSize = new FuncCall<Float>(){
#Override
public Float call(){
return size;
}
};
inputs.add(getX);
inputs.add(getY);
inputs.add(getSize);
}
}
class Pol {
ArrayList<FuncCall<Float>> inputs = new ArrayList<FuncCall<Float>>();
public Pol(ArrayList<FuncCall<Float>> inputs){
this.inputs = inputs;
}
//public float call(ArrayList<FuncCall<Float>> arr, int index){
//return arr.get(index).call();
//}
//How do I do this? Do I need to implement the interface here as well? Because if so same error as on Bird
}
I'll also stick this extra bit on the end here.
System.out.println(pol.call(pol.inputs, 1));
Does will that work? It doesn't error before compiling.
I appreciate any help. Please ask if something doesn't make sense as I'm still new to stack and not the best with java. :)
main file :
void setup(){
Bird bird = new Bird(1.2, 3.2, 7.5);
Pol pol = new Pol(bird.inputs);
System.out.println(pol.call(pol.inputs, 1););
}
First of all you could skip your FuncCall interface and use Java's Supplier functional interface and just add these Suppliers respectively method references of your class objects getters to the list.
Another approach is to provide an interface or abstract class that has getters and/or member variables for x, y and size and use this interface or abstract class as type parameter for the list.
With Suppliers:
This is closer to your example and requires less changes in
your code.
The second option with an interface changes your Pol class
completely and I am not sure if this is acceptable for you.
´
public class Bird {
private float x;
private float y;
private float size;
public Bird(float x, float y, float size) {
//set your members here
}
public Float getX() {
return this.x;
}
public Float getY() {
return this.y;
}
public Float getSize() {
return this.size;
}
}
´
Then the Pol class
´
public class Pol {
private final List<Supplier<Float>> inputs;
public Pol(List<Supplier<Float>> inputs) {
this.inputs = inputs;
}
public Float call(int index) {
return this.inputs.get(index).get();
}
}
´
And your main should look like
´
public static int main(String[] args) {
Bird bird = new Bird(1.0f, 1.0f, 2.5f);
Pol pol = new Pol(Arrays.asList(bird::getX,
bird::getY, bird::getSize));
Float birdsSize = pol.call(2);
return 0;
}
´
as a homework assigment, I am asked to build some sort of calculator with java.
In order to make it easier to create expressions, I wanna add constructors that provide "shortcuts" for creating the Num and Var classes. For example, instead of writing new Plus(new Var("x"), new Num(5)) I would like to be able to write new Plus("x", 5) and get the same resulting expression.
in order to not repeat code lines I've created an abstract class called BinaryExpression, inside it are all the possible combination I need for my constructors.
I'm trying to figure out an elegant way to construct a plus class without the need to re-write the same code again.
public abstract class BinaryExpression implements Expression {
protected Expression x;
protected Expression y;
public BinaryExpression(Expression x, Expression y) {
this.x = x;
this.y = y;
}
public BinaryExpression(String x, Expression y) {
this(new Var(x),y);
}
public BinaryExpression(Double x, Expression y) {
this(new Num(x), y);
}
public BinaryExpression(Expression x, String y) {
this(x ,new Var(y));
}
public BinaryExpression(Expression x, Double y) {
this(x ,new Num(y));
}
public BinaryExpression(String x, String y) {
this(new Var(x) ,new Var(y));
}
public BinaryExpression(Double x, Double y) {
this(new Num(x) ,new Num(y));
}
public BinaryExpression(Double x ,String y){
this(new Num(x) ,new Var(y));
}
public BinaryExpression(String x ,Double y){
this(new String(x) ,new Num(y));
}
I searching for a solution like this:
public class Plus extends BinaryExpression {
public Plus(<String,Double, Expression> x, <String,Double, Expression> y) {
super(x, y);
}
so I only accept this class types that way they will fit themselves to their designated constructor inside BinaryExpression class.
thanks :)
The problem is that you need some general container for objects which can be treated as if they were instances of Expression without them actually being instances of Expression. (example: String, Double)
This answer assumes the following:
class Num implements Expression
class Var implements Expression
and that the following constructor exists, or that no constructor is defined for the class Expression
public Expression() {}
I think a good solution would be as #markspace suggested. You can make sure it compiles by using instanceof to determine what to cast the arguments to.
public Plus(Object a, Object b) {
Expression exprA = convertToExpression(a);
Expression exprB = convertToExpression(b);
if(exprA == null || exprB == null) {
// could error handle here or in the place below
}
// do initialization here
}
//
public Expression convertToExpression(Object obj) {
Expression exprObj = null;
if(obj instanceof String) {
exprObj = new Var(obj);
} else if(obj instanceof Double) {
exprObj = new Num(obj);
} else {
// error handle here or in the place above
}
return exprObj;
}
Also, is the last constructor incorrect in your code above?
It seems like it should read like this:
public BinaryExpression(String x, Double y) {
this(new Var(x), new Num(y));
}
is it possible to get the final parameter values from an anonymous class? Using reflection or anything else?
This example is of course all made up:
final String x = "Param1";
final String y = "Param2";
ITest<String> iTest = new ITest<String>() {
#Override
public String execute() {
return t.testMethod(x, y);
}
};
// Get values or x and y from iTest here?
So this is your code:
ITest<String> iTest = new ITest<String>() {
#Override
public String execute() {
return testMethod(x, y);
}
};
Try defining ITest like so:
public class ITest {
int x;
int y;
public testMethod(int x, int y) {
this.x = x; this.y = y;
}
// execute somewhere
}
I haven't tried this myself, but I believe that the values of x and y are copied into autogenerated fields in the anonymous class instance. Try this:
for (Field field : iTest.getClass().getDeclaredFields()) {
field.setAccessible(true);
System.out.println(field.getName() + ": " + field.get(iTest));
}
Consider a wrapper class W, wrapping C, this meaning that for most attributes of C, there is a correspondent attribute A on W, its logic consisting in nothing more than delegation to C's A. This situation can be most precisely depicted with the sketch shown below:
class W {
private C c;
getX() { return c.getX(); }
getY() { return c.getY(); }
}
The trouble is that I've decided that I wan't to get rid of getX(), and I'd prefer to either as a transitory step to put C c as public, having all the calling code of W do a w.c.getX() or w.c.getY() or alternatively to put create a W.getC(), and have all calls to getX() and getY() go through it.
What this all boils down is to an "un-encapsulate" refactoring. Is there anything performing this much needed task either in Eclipse or Intellij?
With IntelliJ you can use the Remove Middleman refactoring.
Consider:
Before:
public class W {
private C c;
Object getX() { return c.getX(); }
Object getY() { return c.getY(); }
}
public class C {
private Object x;
private Object y;
public Object getX() {
return x;
}
public Object getY() {
return y;
}
}
public class UsesW {
W w;
public void useW() {
Object x = w.getX();
Object y = w.getY();
}
}
Place your cursor on the declaration of W.c. Then choose Refactor | Remove Middleman.
The result gets you halfway to where you want to be:
After:
public class W {
private C c;
public C getC() {
return c;
}
}
/* class C is unchanged */
public class UsesW {
W w;
public void useW() {
Object x = w.getC().getX();
Object y = w.getC().getY();
}
}
Then you can introduce a variable of type C in UsesW. Place your cursor over one of the calls to w.getC() and inline it: Refactor | Inline... (Ctrl-Alt-N is the default shortcut), choosing to inline all instances. It'll leave you with this:
public class UsesW {
W w;
public void useW() {
final C c = w.getC();
Object x = c.getX();
Object y = c.getY();
}
}
Finally getting rid of W altogether is something you probably can answer better than me, but now that job became significantly easier.
Write your new getC() method.
Rewrite getX() to be return getC().getX().
Inline getX().
The same goes for y.
There is an example of "Implementing an Interface" in Java tutorial. I have repeated this example but it doesn't work. NetBeans shows the mistake on te left of RectanglePlus class declaration. And mistake is:
rectangleplus.RectanglePlus is not abstract and does not override
abstract method isLargerThan(rectangleplus.Relatable) in
rectangleplus.Relatable
I did the same as written in tutorial. Why it shows the mistake? Here is my implementation of the project.
The name of the project is RectanglePlus.
The name of the package is rectangleplus.
1st file in the project is Interface Relatable:
package rectangleplus;
public interface Relatable {
int isLarger(Relatable other);
}
2nd file in the project is Main Class RectanglePlus with helper class Point:
package rectangleplus;
public class RectanglePlus implements Relatable {
public int width = 0;
public int height = 0;
public Point origin;
// four constructors
public RectanglePlus() {
origin = new Point(0, 0);
}
public RectanglePlus(Point p) {
origin = p;
}
public RectanglePlus(int w, int h) {
origin = new Point(0, 0);
width = w;
height = h;
}
public RectanglePlus(Point p, int w, int h) {
origin = p;
width = w;
height = h;
}
// a method for moving the rectangle
public void move(int x, int y) {
origin.x = x;
origin.y = y;
}
// a method for computing
// the area of the rectangle
public int getArea() {
return width * height;
}
// a method required to implement
// the Relatable interface
public int isLargerThan(Relatable other) {
RectanglePlus otherRect
= (RectanglePlus)other;
if (this.getArea() < otherRect.getArea())
return -1;
else if (this.getArea() > otherRect.getArea())
return 1;
else
return 0;
}
public static void main(String[] args) {
// TODO code application logic here
}
}
class Point {
int top;
int left;
int x;
int y;
public Point(int t, int l) {
top = t;
left = l;
}
}
Why there is nothing said about abstraction in the tutorial example? Should the tutorial example work without mitakes?
Thank you.
In the interface, you declare the method isLarger but in the class you declare isLargerThan Change one to the other name and it will go fine.
You're not correctly implementing the isLarger() method in the Relatable interface. Rename the isLargerThan(Relatable other) method so it looks like this:
#Override
int isLarger(Relatable other) {
}
It's a good idea to use the #Override annotation, it allows you to catch errors like the one in the question.