When i call s1.dub(7) or s2.dub(7) it doesn't work
,but calling it with a string like s2.dub("9") works and prints the doubled string
Could any one tell me why?
Here's the code
interface Inter {
int number();
}
abstract class Abs {
static int foo = 12;
int number() { return 5; }
abstract int ace();
}
final class Sub extends Super {
Sub(int bar) { foo = bar; }
public int number() { return 10; }
int ace() { return 13; }
int dub(int i) { return 2 * i; }
}
public class Super extends Abs implements Inter {
public int number() { return 11; }
public static void main(String args[]) {
Super s1 = new Super();
Super s2 = new Sub(16);
//System.out.println(s1.dub(7)); //doesn't work
//System.out.println(s2.dub(7)); //doesn't work
//System.out.println(s1.dub("7")); //works giving 77
//System.out.println(s2.dub("7")); //works giving 77
}
int twice(int x) { return 2 * x; }
public int thrice(int x) { return 3 * x; }
int ace() { return 1; }
String dub(String s) { return s + s; }
}
Very easy.. you class Super defines a method:
String dub(String s) { return s + s; }
in your main method you instantiate Super:
Super s1 = new Super(); // this has a dub( String ) method
then you try to call this method (dub) passing a integer, instead of a string:
System.out.println(s1.dub(7)); // s1.dub(...) takes a String, not a number
EDIT: This code should not compile, or run, because you are assigning both instances to the super class Super (which does not define a dub(int) method).
Not sure how you are getting exceptions?
Thank you #Jean-FrançoisSavard - I totally missed that!
EDIT2: The original question was modified and no longer indicates that an exception is thrown, which makes sense as the code should not compile at all.
EDIT3: (last one, due to original question changing)
System.out.println(s1.dub(7)); //- this will never work unless you change your class' definition
System.out.println(s2.dub(7)); //- will work if you also change the following line:
from:
Super s2 = new Sub(16);
to:
Sub s2 = new Sub(16);
Related
I am having hard time to understand the solution of the given question. I can't understand at each step which of the class' methods are invoked.
I tried to make a list for what are a,b,c declared types and actual types then try to chose overridden or overloaded methods but it is complex.
class Upper {
private int i;
private String name;
public Upper(int i) {
name = "Upper";
this.i = i;
}
public void set(Upper n) {
i = n.show();
}
public int show() {
return i;
}
}
class Middle extends Upper {
private int j;
private String name;
public Middle(int i) {
super(i + 1);
name = "Middle";
this.j = i;
}
public void set(Upper n) {
j = n.show();
}
public int show() {
return j;
}
}
class Lower extends Middle {
private int i;
private String name;
public Lower(int i) {
super(i + 1);
name = "Lower";
this.i = i;
}
public void set(Lower n) {
i = n.show();
}
public int show() {
return i;
}
}
class Tester {
public static void main(String[] args) {
Lower a = new Lower(1);
Middle b = a;
Upper c = new Middle(5);
a.set(c);
b.set(a);
c.set(b);
System.out.println(a.show());
System.out.println(b.show());
System.out.println(c.show());
}
}
What is printed as a result of System.out.println(a.show()); after the set commands? Answer is 1
What is printed as a result of System.out.println(b.show()); after the set commands? Answer is 1
What is printed as a result of System.out.println(c.show()); after the set commands? Answer is 1
I don't get why the answers of all these are 1. Also I can't tell which class' overridden or overloaded methods that "a.set(c); b.set(a); c.set(b);" uses. A detailed explanation would be really helpful.
a.set(c) uses the set-method from Middle, as that overrides the one from Upper and the (overloaded) set from Lower is not applicable because c is not an instance of Lower.
Therfore j is set to c.show() which returns c's attribute j, so it will be set to 5. Consequently the (Lower-)attribute i of a is never touched and remains at 1 when it is shown and printed.
Try to resolve the others yourself.
I'm working with Java. I have a class with 2 constructors. The first constructor takes an int value as a parameter and sets an int variable as that value. The second constructor takes a string and prints it out. The idea is that when I call the first constructor from my main class, it sets an integer value. And when I call the second constructor in the main class, it takes the string representation of int variable of the first constructor and prints it out.
Here's how I made the constructors:
public class Test
{
int val;
public Test(int x)
{
val = x;
return val; //I know this won't work. So I'm looking for an alternative
}
public Test(String y)
{
System.out.println("The value is " + y);
}
}
And the main method (in a different class) looks like this:
public static void main(String [] args)
{
Test t1 = new Test(6);
Test t2 = new Test(String.valueOf(t1)); //This won't work because the first constructor can't return a value
}
So how exactly can I change the contents of the constructors so that I can pass val into the 2nd constructor?
Override toString() to return value so when you so String.valueOf(t1) it will do the toString() method;
public class Test
{
int val;
public Test(int x)
{
val = x;
}
public Test(String y)
{
System.out.println("The value is " + y);
}
#Override
public String toString()
{
return String.valueOf(val);
}
}
I think what you are probably actually trying to do is to override the toString() method of Test.
public class Test
{
int val;
public Test(int x)
{
val = x;
}
#Override
public String toString() {
return "Test:"+val;
}
}
Then you can do this:
public static void main(String [] args)
{
Test t1 = new Test(6);
String s = t1.toString();
// or this
System.out.println( t1 ); // prints "Test: 6"
}
What you're describing is actually impossible without some changes.
First and foremost, t1 and t2 are two separate instances and the values inside of them have no bearing on one another. So t1 has x=6 and t2 has x=0 (because of default values).
If you want your second constructor to have a value of x that isn't 0, then you'll need to pass that in too.
public Test(int x, String s) {
super(x);
System.out.println(x);
}
I think you don't really want two constructors. It seems like you're wanting to do something like the following:
public class Test
{
int val;
public Test(int x)
{
val = x;
}
public void printVal()
{
System.out.println("The value is " + val);
}
public static void main(String [] args)
{
Test t1 = new Test(6);
t1.printVal();
}
}
Your requirement is kinda weird. But this will work even it is kinda weird
public class Test {
private static int val;
public Test(int x) {
val = x;
}
public Test() {
System.out.println("The value is " + String.valueOf(val));
}
public static void main(String[] args) {
Test t1 = new Test(6);
Test t2 = new Test();
}
}
So I've seen, in many places, calling methods of a class like:
SomeClass obj = new SomeClass();
obj.addX(3).addY(4).setSomething("something").execute();
I don't think I completely understand how that works. Is each method independent of each other, so the above is equal to:
obj.addX(3);
obj.addY(4);
obj.addSomething("something");
obj.execute();
Or are they designing their class structure in some other fashion that allows for this. If they are how are they designing their classes to support this?
Also, does that have a specific name? Or is this just calling methods on a class?
That would be method chaining. It can do one of two things.
Each call to a method returns this which allows you to continue to call methods on the original instance.
public class SomeClass
{
private int _x = 0;
private int _y = 0;
private String _something = "";
public SomeClass addX(int n)
{
_x += n;
return this;
}
public SomeClass addY(int n)
{
_y += n;
return this;
}
public SomeClass setSomething(String something)
{
_something = something;
return this;
}
// And so on, and so on, and so on...
}
Each method call returns a new instance of the class with everything copied/updated appropriately. This makes the class immutable (so you don't accidentally modify something that you didn't mean to).
public class SomeClass
{
private int _x = 0;
private int _y = 0;
private String _something = "";
public SomeClass(int x, int y, String something)
{
_x = x;
_y = y;
_something = something;
}
public SomeClass addX(int n)
{
return new SomeClass(_x + n, _y, _something);
}
public SomeClass addY(int n)
{
return new SomeClass(_x, _y + n, _something);
}
public SomeClass setSomething(String something)
{
return new SomeClass(_x, _y, something);
}
// And so on, and so on, and so on...
}
Some people have also mentioned Fluent Interfaces. Fluent Interfaces utilize method chaining to create an API that provides something along the lines of a Domain Specific Language which can make code read much more clearly. In this case, your example doesn't quite qualify.
they modify object's state and return the same object back mostly
class Number{
int num;
public Number add(int number){
num+=number;
return this;
}
}
you can call it like
new Number().add(1).add(2);
most of the time the use case is to return new Object to support immutability
Each of those methods return an instance. For example, the call to
obj.addX(3)
will return the same instance obj, so the call
obj.addX(3).addY(4)
will be equivalent to
obj.addY(4)
This is called method chaining.
The methods are implemented like this:
public SomeClass addX(int i) {
// ...
return this; // returns the same instance
}
public class Test1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Test1 abc = new Test1();
abc.add1(10, 20).sub1(40, 30).mul1(23, 12).div1(12, 4);
}
public Test1 add1(int a, int b)
{
int c = a + b;
System.out.println("Freaking Addition output : "+c);
return this;
}
public Test1 sub1(int a, int b)
{
int c = a - b;
System.out.println("Freaking subtraction output : "+c);
return this;
}
public Test1 mul1(int a, int b)
{
int c = a * b;
System.out.println("Freaking multiplication output : "+c);
return this;
}
public Test1 div1(int a, int b)
{
int c = a / b;
System.out.println("Freaking divison output : "+c);
return this;
}
}
Imagine I have a class
class A {
int a;
int b;
A(int a, int b) {
this.a=a; this.b=b;
}
int theFunction() {
return 0;
}
void setTheFunction([...]) {
[...]
}
}
And for every new object I instantiate, I want to be able to define theFunction() in a new way by calling setTheFunction( [...] ). For example, I want to do something like this:
A test = new A(3,2);
test.setTheFunction ( int x = a*b; return x*x+2; );
System.out.println(test.theFunction()); // Should return (3*2)*(3*2)+2 = 38
Or something like this:
A test2 = new A(1,5);
test.setTheFunction ( for(int i=0; i<b; i++) a=a*b*i; return a; );
Now, what I could of course do is write all of those functions inside class A and use a switch statement to determine which one is to pick. But if I don't want the algorithm of theFunction() hardcoded inside my class A, is there any way to do something similar to the above? And what would setTheFunction() look like? What type of argument would you have to pass?
You can use Callable.
public class A<V> {
public int a;
public int b;
private Callable<V> callable;
public A(int a, int b) {
this.a = a;
this.b = b;
}
public V theFunction() {
try {
return callable.call();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public void setTheFunction(Callable<V> callable) {
this.callable = callable;
}
}
Then, to use it:
final A<Integer> test = new A<Integer>(3, 2);
test.setTheFunction(new Callable<Integer>() {
int x = test.a * test.b;
return x * x + 2;
});
System.out.println(test.theFunction());
Of course, the generic typing of A isn't necessary, but I've added it to make this answer to be less restricted.
If you always need to operate on the same arguments, you could solve this by defining an interface such as:
public interface MethodPerformer {
int performOperation(int a, int b);
}
Then pass in implementations of this to your setTheFunction method. Finally, invoke the operation when you call the other method:
class A {
int a;
int b;
MethodPerformer performer;
A(int a, int b) {
this.a=a; this.b=b;
}
int theFunction() {
performer.performOperation(a, b);
}
void setTheFunction(MethodPerformer performer) {
this.performer = performer;
}
}
Clearly additional code would be required to check the performer is not null. Perhaps take a performer in the constructor?
Instead of using a setter, the more natural way is to use an anonymous sub-class. This way the compiler will check it behaves correctly and has access to the right variables.
public class Main {
static abstract class A {
protected int a, b;
A(int a, int b) {
this.a = a;
this.b = b;
}
public abstract int theFunction();
}
public static void main(String... ignored) {
A test = new A(3, 2) {
#Override
public int theFunction() {
int x = a * b;
return x * x + 2;
}
};
System.out.println(test.theFunction()); // Should return (3*2)*(3*2)+2 = 38
A test2 = new A(1, 5) {
#Override
public int theFunction() {
for (int i = 1; i < b; i++) a = a * b * i;
return a;
}
};
System.out.println(test2.theFunction());
}
}
prints
38
15000
With this you can solve any kind of problem, that involves any kind of public variable of A (but can work with package private variables as well, if the AFunction implementation resides in the same package), that a function may use to perform it's operation. It's just not as compact as it can be in other languages than java.
interface AFunction
{
int call(A a);
}
class A
{
int a;
int b;
//giving it a default implementation
private AFunction f = new AFunction()
{
#Override
public int call(A a)
{
return a.a * a.b;
}
};
A(int a, int b)
{
this.a = a;
this.b = b;
}
int theFunction()
{
return f.call(this);
}
void setTheFunction(AFunction f)
{
this.f = f;
}
}
By the way as AlexTheo points out, all answers so far (except for Peter Lawrey's) are a form of the strategy design pattern.
The easiest way to do this is defining "A" as an interface instead of a class. You declare theFunction() without actually implementing it.
In client code, everytime you need "A", you instantiate a so-called anonymous inner class.
For example:
new A() { #Override public int theFunction() { ...your implementation... } };
I'm attempting implement the add method mentioned in the Generic sparse matrix addition question
class Matrix<T extends Number>
{
private T add(T left, T right)
{
if (left instanceof Integer)
{
return new Integer(((Integer)left).intValue() + ((Integer)right).intValue());
}
}
The compiler errors with found java.lang.Integer Required T at the line where I return a new Integer. I'm not sure what I'm missing since T extends Number and Integer is a subclass of Number.
The compiler doesn't let you do this because T might be some other class, such as Double.
You know that T is Integer from the instanceof check, but the compiler doesn't.
Java's type system is simply not capable of expressing this. Here is a work around.
Create an interface Numeric that provides the numeric operations you are interested in, and write its implementations for the data types you are interested in.
interface Numeric<N> {
public N add(N n1, N n2);
public N subtract(N n1, N n2);
// etc.
}
class IntNumeric extends Numeric<Integer> {
public static final Numeric<Integer> INSTANCE = new IntNumeric();
private IntNumeric() {
}
public Integer add(Integer a, Integer b) {
return a + b;
}
public Integer subtract(Integer a, Integer b) {
return a - b;
}
// etc.
}
And rewrite your Matrix class constructor to accept this implementation.
class Matrix<N> {
private final Numeric<N> num;
private final List<List<N>> contents;
public Matrix(Numeric<N> num) {
this.num = num;
this.contents = /* Initialization code */;
}
public Matrix<N> add(Matrix<N> that) {
Matrix<N> out = new Matrix<N>(num);
for( ... ) {
for( ... ) {
out.contents.get(i).set(j,
num.add(
this.contents.get(i).get(j),
that.contents.get(i).get(j),
)
);
}
}
return out;
}
}
// Use site
Matrix<Integer> m = new Matrix<Integer>(IntNumeric.INSTANCE);
Hope that helps.
"I'm not sure what I'm missing since T extends Number and Integer is a subclass of Number."
This statement is false. In general if you have:
public class B extends A {
}
public class C extends A {
}
it does not mean that B can be cast to C. So writing something like:
public <T extends A> T method(T arg) {
return (B)arg;
}
and you calling it with B b = (B)method(C); is obviously wrong.
package generics;
public class Box<T> {
public T j,k;
int l;
float f;
#SuppressWarnings("unchecked")
public void add(T j,T k) {
this.j = j;
this.k=k;
if(j.toString().contains("."))
{
this.f=Float.parseFloat(j.toString())+Float.parseFloat(k.toString());
} else{
this.l=Integer.parseInt(j.toString())+Integer.parseInt(k.toString());
}
}
public int getInt() {
return l;
}
public float getFloat() {
return f;
}
public static void main(String[] args) {
Box<Integer> integerBox = new Box<Integer>();
Box<Float> floatBox = new Box<Float>();
integerBox.add(new Integer(10),new Integer(20));
floatBox.add(new Float(2.2),new Float(3.3));
System.out.printf("Integer Value :%d\n\n", integerBox.getInt());
System.out.printf("float Value :%f\n", floatBox.getFloat());
}
}