public class A
{
public void display(int i)
{
System.out.println("Inside A");
}
}
public class B extends A
{
public void display(Integer i)
{
System.out.println("Inside B");
}
}
public class starter
{
public static void main (String args[])
{
A a = new B();
a.display(5);
System.out.println("So now you know or not");
}
}
Output : Inside A
Can somebody explain this output? Normally child method should be called. How does Java behave here when we have a wrapper class and a primitive class using inheritance?
B#display does not override A#display, as the signature is different.
The fact ints can be boxed into Integers is not relevant here.
You could easily verify this by using the #Override annotation.
Since the reference type of a is A, the method is resolved with the exact match for a literal integer (your given 5 argument), which is int, therefore A#display is invoked.
You can still force the invocation of B#display by using this idiom (not for production code):
((B)a).display(new Integer(5));
This casts your a variable as a B type, hence allowing visibility of B's display method within context.
It also passes an Integer rather than an int, thus employing the signature of B's display method and allowing resolution to that method.
Related
I have 1 interface and 3 class. I would like the class to be able to both implement the interface which need a transform method. This method must exist but there can't be more than one per class. I don't know the number of parameters taken by this class.
Example :
public interface A{
public void transform(Object ... args);
}
public class B implements A{
public void transform(String a){
System.out.println(a);
}
}
public class C implements A{
public void transform(Integer a, Character b){
System.out.println(a+b);
}
}
// super generic case if possible with Objects + primitive
public class D implements A{
public void transform(int a, String b){
System.out.println(a+b);
}
}
This doesn't work. But I hope you got the idea. Is something like this possible in java ? How should I call them in a generic way ? Let's say if I have an other method like :
void callTransf(A a, Object ... objs){
Method m = a.getClass().getMethods()[0];
m.invoke(a, objs)
}
A practicable solution would be to declare the interface as a generic one:
public interface Transformation<S, R> {
R transform(S source);
}
The type parameter S plays the source role; the type parameter R plays the result role.
You now can create source and result classes for each different transformation. An example:
public final class TransformationSourceForA {
// Here you declare whatever fields and methods you need for an A source.
// For example:
int a;
String b;
}
public final class TransformationResultForA {
// Here you declare whatever fields and methods you need for an A result.
}
With that you declare the transformation as following:
public final class TransformationA implements Transformation<TransformationSourceForA, TransformationResultForA> {
#Override
public TransformationResultForA transform(TransformationSourceForA source) { ... }
}
The principle is to delegate the needs for different fields to a class and not to the method's parameter.
You can achieve what you want, with some changes and some help of functional programming...
TL;DR
The main idea is that the transform method doesn't receive any arguments. Instead, it will return an instance of some functional interface.
The implementation of this functional interface will consist of the code that would have been executed by the transform method if it had arguments.
To represent arguments of different types and/or a different number of arguments for each subclass of the A interface, we'll use covariance in the return type of the method transform.
This means that the functional interface will be generic (so that the type of the arguments can be different for each subclass of A), and that there will be subinterfaces that will extend this functional interface, each one accepting a different number of arguments in its single abstract method. This will allow the transform() method's return value to have either 1, 2, 3, ... etc arguments.
To execute the code returned by the transform() method, we'll do:
instanceOfB.transform().execute("hello");
instanceOfC.transform().execute(1, 'a');
instanceOfD.transform().execute(1, "hello");
Finally, in order to be able to execute the code in a generic way, the base functional interface defines a varargs method executeVariadic(Object... args), which will be implemented as a default method by every child functional interface, delegating to its execute method and casting the arguments as needed.
Now the long version...
Let's start by renaming your A interface to something more descriptive. As it defines a method called transform, let's name it Transformer.
Then, let's create a functional interface that will represent the transform method of the Transformer interface. Here it is:
#FunctionalInterface
public interface Transformation {
void executeVariadic(Object... args);
}
This interface just defines one single abstract method (SAM) that receives an Object... varargs argument. It is there so that subinterfaces can override it.
Now, let's create a Transformation1 functional interface that extends the Transformation interface:
#FunctionalInterface
public interface Transformation1<A> extends Transformation {
void execute(A a);
#Override
#SuppressWarnings("unchecked")
default void executeVariadic(Object... args) {
this.execute((A) args[0]);
}
}
This Transformation1<A> functional interface is generic and defines the single abstract method execute, which takes one argument of type A. The executeVariadic method is overriden as a default method that delegates its execution to the execute method, casting the first argument accordingly. This cast generates a warning, but oh, well... we'd better learn to live with it.
Now, let's create an analogous interface with two generic type parameters and an execute method that receives two arguments whose types match the generic type parameters:
#FunctionalInterface
public interface Transformation2<A, B> extends Transformation {
void execute(A a, B b);
#Override
#SuppressWarnings("unchecked")
default void executeVariadic(Object... args) {
this.execute((A) args[0], (B) args[1]);
}
}
The idea is the same: the Transformation2 interface extends the Transformation interface and we override the executeVariadic method so that it is delegated to the execute method, casting the arguments accordingly (and suppressing the annoying warning).
For completeness, let's introduce the Transformation3 interface, which is analogous to the previous TransformationX ones:
#FunctionalInterface
public interface Transformation3<A, B, C> extends Transformation {
void execute(A a, B b, C c);
#Override
#SuppressWarnings("unchecked")
default void executeVariadic(Object... args) {
this.execute((A) args[0], (B) args[1], (C) args[2]);
}
}
Hope the pattern is clear by now. You should create as many TransformationX interfaces as arguments you want to support for the transform method of your Transformer interface (A interface in your question, remember I've renamed it).
So far so good, I know this answer is long, but I needed to define the interfaces above so that they can now be used to put all the pieces together.
Remember your A interface? Let's not only keep its name changed to Transformer, but also the signature of its transform method:
#FunctionalInterface
public interface Transformer {
Transformation transform();
}
So this is your base interface now. The transform method no longer has arguments, but returns a Transformation instead.
Let's see how to implement your B, C and D classes now. But first, allow me to rename them to TransformerB, TransformerC and TransformerD, respectively.
Here's TransformerB:
public class TransformerB implements Transformer {
#Override
public Transformation1<String> transform() {
return a -> System.out.println(a); // or System.out::println
}
}
The important thing here is the use of covariance in the return type of the transform method. And I'm using the Transformation1<String> type, which is a subtype of Transformation and indicates that, for the TransformerB class, the transform method returns a transformation that accepts one argument of type String. As the Transformation1 interface is a SAM type, I'm using a lambda expression to implement it.
Here's how to invoke the code inside the TransformerB.transform method:
TransformerB b = new TransformerB();
b.transform().execute("hello");
b.transform() returns an instance of Transformation1, whose execute method is immediately invoked with the String argument it expects.
Now let's see the implementation of TransformerC:
public class TransformerC implements Transformer {
#Override
public Transformation2<Integer, Character> transform() {
return (a, b) -> System.out.println(a + b);
}
}
Again, covariance in the return type of the transform method allows us to return a concrete Transformation, in this case Transformation2<Integer, Character>.
Usage:
TransformerC c = new TransformerC();
c.transform().execute(1, 'A');
For the TransformerD example, I've used a three-argument transformation:
public class TransformerD implements Transformer {
public Transformation3<Integer, Double, String> transform() {
return (a, b, c) -> System.out.println(a + b + c);
}
}
Usage:
TransformerD d = new TransformerD();
d.transform().execute(12, 2.22, "goodbye");
This is all type-safe, because the generic types can be specified in the TransformationX return type of each concrete transform method implementation. It's not possible to use primitive types, though, because primitive types cannot be used as generic type parameters.
Regarding how to call the transform method in a generic way, it's straightforward:
void callTransf(Transformer a, Object... args) {
a.transform().executeVariadic(args);
}
This is why the executeVariadic method exists. And it's overriden in each TransformationX interface, so that it can be used polymorphically, as in the code above.
Calling the callTransf method is straightforward too:
callTransf(b, "hello");
callTransf(c, 1, 'A');
callTransf(d, 12, 2.22, "goodbye");
What you are asking isn't possible.
If interface method uses Varargs then others must too. So one solution would be to have both classes use this interface. Here is general idea:
public interface A{
public void transform(char ... args);
}
public class B implements A{
public void transform(char ... args){
String s = "";
for(char c : args){
s += c;
}
System.out.println(s);
}
}
public class C implements A{
public void transform(char ... args){
System.out.println(args[0] + args[1]);
}
}
Now when you are calling method in B then you must convert string to char array:
String str = "example";
char[] charArray = str.toCharArray();
When calling method in A you make sure to convert integer to char:
int i = 5;
transform((char)Character.forDigit(i, 10), 'a'); // 10 stands for number radix which is probably 10
This isn't perfect solution but it is working one.
But a bit simpler solution without varargs is using just char array, but again you need to convert inputs to char array.
public interface A{
public void transform(char[]);
}
public class B implements A{
public void transform(char[] args){
String s = "";
for(char c : args){
s += c;
}
System.out.println(s);
}
}
public class C implements A{
public void transform(char[] args){
System.out.println(args[0] + args[1]);
}
}
Anyway you do it, you will end up with a bit complicated code, even if using generics you must remember that 1 method takes 1 parameter and other one 2. I actually think that it would be best to simply make this methods separate.
It's a very old question but I don't see a correct implementation in any of the solution. OP was going the right way and is the correct implementation but needs to be written like this -
public interface A<T>{
public T transform(Object ... args);
}
public class B implements A{
public void transform(Object ... args){
System.out.println((String)args[0]);
}
}
public class C implements A{
public void transform(Object ... args){
Integer a = (Integer)args[0];
Integer b = (Integer)args[1];
System.out.println(a+b);
}
}
public static void main(String [] vals){
//Interface A
A b = new B();
A c = new C();
b.transform("Hello");
c.transform(new Integer(1), 'c');
}
You will see it's importance if you use Spring or other DI framework then all you need to do is
#Inject
#Qualifier("B") // For Implementation class B
A b;
#Inject
#Qualifier("C") // For Implementation class C
A C
I see accepted answer is very convuluted and in the end, it is just directly calling the implementation class -
Ex:TransformerB b = new TransformerB;
b.transform();
What's the point of creating all the interfaces???
this is a very interesting Question.you can use method overloading concept if you know the maximum number of arguments coming.
lets say you know that at max user can give 2 parameters then you can do something like this.
public void implementation(){
System.out.println("method with zero args")
}
public void implementation(String arg1){
System.out.println("method with one args and is:-"+arg1)
}
public void implementation(String arg1,String arg2){
System.out.println("method with two args and are :-"+arg1+" "+arg2)
}
if you dont know the maximum number of args you can implement in multiple ways.
1.create a collection and store them in collection object and pass the object as argument.
List args= new List();
l.add(arg1)
----------
----------
----------
l.add(argn)
now pass this as argument to the function call as
objecReference.implementation(l)
2.using var arg methods.
this is the very easy way to solve this kind of problems from java 1.8.
in implementation
public String implementation(int(change to required datattype)...x){
//here x will act like an array
for(int a:x){//iam assuming int values are coming
System.out.println(a)
}
}
now you can call this function with atleast 0 args like
objecReference.implementation()
objecReference.implementation(10)
objecReference.implementation(10,20)
objecReference.implementation(12,23,34,5,6)
As per your requirement you want to override method from your interface in class B and C , but you cannot do the way you have done that.
One way to do is as :
public interface A<T> {
public void transform(T ... args);
}
public class B implements A<String> {
#Override
public void transform(String... args) {
}
}
public class C implements A<Integer> {
#Override
public void transform(Integer... args) {
}
}
One possible solution could be to use Marker Interfaces. A marker (or tagging) interface is an interface that has no methods or constants inside it. It provides run-time type information about objects.
Here is an example that uses Input interface as transform method parameter. An instance of a class that implements this marker interface can be used as transform method argument.
public interface Input {
}
public interface Transformable {
void transform(Input input);
}
public class InputForA implements Input {
int a;
String b;
public int getA() {
return a;
}
public InputForA setA(int a) {
this.a = a;
return this;
}
public String getB() {
return b;
}
public InputForA setB(String b) {
this.b = b;
return this;
}
}
public class TransformerA implements Transformable {
#Override
public void transform(Input input) {
InputForA inputForA = (InputForA) input;
System.out.println(inputForA.getA() + inputForA.getB());
}
}
This question already has answers here:
Polymorphism in Overloaded and Overridden Methods
(4 answers)
Closed 6 years ago.
class PolymorphisomTest {
class Base {
public void doTest(double d) {
System.out.println("From Base");
}
}
class DerivedBase extends Base {
public void doTest(int d) {
System.out.println("From Derived Base");
}
}
public void use(Base base) {
base.doTest(3);
}
public void run() {
use(new Base());
use(new DerivedBase ());
}
public static void main(String []cmd) {
new PolymorphisomTest ().run();
}
}
Here doTest(double d) from parent class and doTest(int d) from subclass but when i call base.doTest(3) it always invokes parent class method even my object reference is different. what's the reason behind it?
doTest(double d) is a completely different method from void doTest(int d), because they have different parameter lists. There actually isn't any polymorphism there at all; DerivedBase is declaring a new method, not overloading Base.doTest. It's as if you had done this:
class Base {
public void doTest(double d) {
System.out.println("From Base");
}
}
class DerivedBase extends Base {
public void doSomethingElse(int d) {
System.out.println("From Derived Base");
}
}
Changing a parameter's type changes the method signature, and makes it a new method instead of overriding the parent class' method.
When you call base.doTest(3), the compiler is going to call doTest(double), because that's the only method of the Base class that matches the parameter. Because that method isn't overriden by anything, Base.doTest gets called.
To override a method you must match the method signature in the derived class. When you change from double to int you create a new method. From Defining Methods - The Java Tutorials,
Definition: Two of the components of a method declaration comprise the method signature—the method's name and the parameter types.
The #Override annotation can protect you from this specific class of error. You can do something like,
class DerivedBase extends Base {
#Override
public void doTest(double d) {
System.out.println("From Derived Base");
}
}
DerivedBase class inherited your doTest from base class. Now, it has 2 methods-
doTest (double d)
doTest (int d)
You have not overridden method but overloaded it by giving different parameter. If you need to override doTest add method with double as parameter.
Reason why it is not calling doTest (int d) is when we call from parent reference , it searches for method their during compile time and bind with same. And at runtime , its same method with same signature from object in hand.
I'm trying to better understand the concept of anonymous classes in Java. From other answers on this website, I learned that an anonymous class can access non-final fields of the enclosing class using OuterClass.this.myField.
I made the following simple test case with an interface, AnonInt, and a class AnonTest with a method foo which returns an instance of an anonymous class implementing AnonInt. Dspite the fact that I'm using System.out.println(a) rather than System.out.println(AnonTest.this.a) the code works and prints the correct result. How can this be?
public interface AnonInt {
void print();
}
public class AnonTest {
private int a;
public AnonTest(int a) {
this.a = a;
}
public AnonInt foo() {
return new AnonInt() {
public void print() {
System.out.println(a);
}
};
}
public static void main(String[] args) {
AnonTest at = new AnonTest(37);
AnonInt ai = at.foo();
ai.print();
}
}
Despite the fact that I'm using System.out.println(a) rather than System.out.println(AnonTest.this.a) the code works and prints the correct result. How can this be?
Since the reference to a is unambiguous in your context, the two expressions reference the same field.
Generally, AnonTest.this is required in a very specific context - when your method needs to access AnonTest object itself, rather than accessing one of its members. In case of your program, this is unnecessary: the compiler resolves the expression a to the object AnonTest.this.a, and passes it to System.out.println.
Why does the following Java code produces:
10
superclass
The code in question is:
class SuperClass {
int a;
public SuperClass() {
this.a = 10;
}
private void another_print() {
System.out.println("superclass");
}
public void print() {
System.out.println(this.a);
this.another_print();
}
}
class SubClass extends SuperClass {
int a;
public SubClass() {
this.a = 20;
}
private void another_print() {
System.out.println("subclass");
}
public void print() {
super.print();
}
}
public class Main {
public static void main (String[] args) {
SubClass c = new SubClass();
c.print();
}
}
There is no instance of SuperClass ever created, isn't there?
Not only that Java starts looking for the method to invoke from the SuperClass, it even somehow knows that a = 10!
Let's consider a similar Python code:
class SuperClass:
def __init__(self):
self.a = 10
def another_prn(self):
print('superclass')
def prn(self):
print(self.a)
self.another_prn()
class SubClass(SuperClass):
def __init__(self):
self.a = 20
def another_prn(self):
print('subclass')
def prn(self):
super().prn()
c = SubClass()
c.prn()
It works as I expect:
20
subclass
The only explanation that my colleagues (Python disliking Java folks) came up with is: "Python is not a true OOP language". Not very convincing at all.
Update: private void another_print() is my blunder, I should have used protected.
It is the order of constructor calling in Java.
In the SubClass, when you instantiate c, the constructor implicitly calls the default constructor of the SuperClass (public SuperClass()) (it must do so). Then a is set to be 10 in the SuperClass.
Now that we're done with the SuperClass constructor, we get back to the constructor of SubClass, which assigns a = 20. But fields are not subject to overriding in java, so a in SuperClass is still 10.
After that it's pretty obvious, we call c.print() which calls the print of SubClass, which calls the print of SuperClass (by super.print()), which prints a which is as you remember 10. Then another_print (which is not overridden since it is private) just prints superclass and we're done.
In the sub-class's print you just call super-class's print method.
So it prints the a from the super class of course.
You have two separate a fields here. Fields are not subject to overriding, only methods are. The super-class has an a field and you have another a field in the sub-class.
If another language produces another result, that's not a big surprise. Also, I am not sure your Python code is logically equivalent/analogous to your Java code.
My comment explained the reason your code probably doesn't work as expected.
Below is code written how you most likely expected it to work. Note the comments in the code.
static class SuperClass {
int a; // only declare field in superclass to avoid hiding
public SuperClass() {
this.a = 10;
}
// make method protected, public, or package private to allow children to override it
protected void another_print() {
System.out.println("superclass");
}
public void print() {
System.out.println(this.a);
this.another_print();
}
}
static class SubClass extends SuperClass {
public SubClass() {
this.a = 20;
}
#Override
protected void another_print() {
System.out.println("subclass");
}
public void print() {
super.print();
}
}
public static void main (String[] args) {
SubClass c = new SubClass();
c.print();
}
This will print
20
subclass
I've debugged my slightly corrected code and found out that:
this is an instance of SubClass
Unlike Python, Java is ok with more than one variable of the same name (as peter.petrov mentioned in his answer, but I didn't got it right away)
One of the as is from the SubClass and the second is from the SuperClass (as implicit superclass constructor call, again unlike Python)
this.a has a different value in test_super() and test_sub() and that is the magic, given that this is a SubClass and Java documentation reads:
this is a reference to the current object — the object whose method or constructor is being called
I think I can live with the fact that this will have all the variables from the whole dependency tree and Java will select which one to use depending on the context.
What is the difference between override and overload?
Overloading: picking a method signature at compile time based on the number and type of the arguments specified
Overriding: picking a method implementation at execution time based on the actual type of the target object (as opposed to the compile-time type of the expression)
For example:
class Base
{
void foo(int x)
{
System.out.println("Base.foo(int)");
}
void foo(double d)
{
System.out.println("Base.foo(double)");
}
}
class Child extends Base
{
#Override void foo (int x)
{
System.out.println("Child.foo(int)");
}
}
...
Base b = new Child();
b.foo(10); // Prints Child.foo(int)
b.foo(5.0); // Prints Base.foo(double)
Both calls are examples of overloading. There are two methods called foo, and the compiler determines which signature to call.
The first call is an example of overriding. The compiler picks the signature "foo(int)" but then at execution time, the type of the target object determines that the implementation to use should be the one in Child.
Overloading of methods is a compiler trick to allow you to use the same name to perform different actions depending on parameters.
Overriding a method means that its entire functionality is being replaced. Overriding is something done in a child class to a method defined in a parent class.
src: http://www.jchq.net/tutorial/06_02Tut.htm
Overloading :
public Bar foo(int some);
public Bar foo(int some, boolean x); // Same method name, different signature.
Overriding :
public Bar foo(int some); // Defined in some class A
public Bar foo(int some); // Same method name and signature. Defined in subclass of A.
If the second method was not defined it would have inherited the first method. Now it will be replaced by the second method in the subclass of A.
Overload - similar signature - same name, different parameters
void foo() {
/** overload */
}
void foo( int a ) {
/** overload */
}
int foo() {
/** this is NOT overloading, signature is for compiler SAME like void foo() */
}
Override - you can redefine method body when you inherit it.
class A {
void foo() {
/** definition A */
}
}
class B extends A {
void foo() {
/** definition B, this definition will be used when you have instance of B */
}
}
On interesting thing to mention:
public static doSomething(Collection<?> c) {
// do something
}
public static doSomething(ArrayList<?> l) {
// do something
}
public static void main(String[] args) {
Collection<String> c = new ArrayList<String> ();
doSomething(c); // which method get's called?
}
One would suppose the method with the ArrayList argument would be called but it doesn't. The first method is called since the proper method is selected at compile time.
Override
Is when a method which is inherited by a subclass from a superclass is replaced (overridden) in the subclass.
class A {
void foo() {
/** definition A of foo */
}
}
class B extends A {
void foo() {
/** definition B of foo */
}
}
Now if you call foo using:
A a = new B();
a.foo();
The B definition of foo will be run. This is not so intuitive since you will get a compile error if the class A didn't have a method called foo. So the type of the object a which is A has to have the method foo, then you can call it, and the method foo of the instance will be executed, which is that of class B, hence 'execution time'.
Overload
When you create a method with the same name as an existing method. To avoid a compile time error, you have to define the new method with different parameters than the existing one. This way the methods will be distinguishable. Have a method with the same name and parameters, but a different return type is still vague and will therefore cause a compile error. Example of overloading:
class A {
void bar(int i) {}
// The following method is overloading the method bar
void bar(Object a) {}
// The following will cause a compile error.
// Parameters should differ for valid overload
boolean bar(int i) {
return true;
}
}