I have an A interface with a method getT(), abstract B class with method getS() and class C that extends B class which implements A interface. I'm overriding methods from A interface and B superclass inside the C subclass. Then in the main method I instantiate the C class to be typeo if A like this: A obj = new C(); I'am able to call the getT() from obj, but can't call getS() method. How can I call getS() method from obj, but I can't change the type of obj, it has to be A. Here is the code:
Interface A :
public interface A {
public String getT();
}
Abstract class B :
public abstract class B implements A {
public abstract String getS();
}
subclass C :
public class C extends B {
#Override
public String getT() {
System.out.println("method getT() from C class");
return null;
}
#Override
public String getS() {
return null;
}
}
And the main method inside of the T class :
public class T {
public static void main(String[] args) {
A obj = new C();
obj.getT();
}
}
With a reference variable of type A, you cannot call getS(), because it could be any type that implements A, say, AImplementer, that doesn't extend from B. Any A object doesn't necessarily have a getS() method. It's only guaranteed to have a getT() method.
If obj has to be a type A and you need to call getS(), then include the getS() method in the definition of the A interface:
public interface A {
public String getT();
public String getS(); // Add this line.
}
Then B is still an A, and you can call getS() on an A reference variable.
By the way, I don't see any static methods in your code. Static methods cannot be overridden.
To gain access to the method you will need to downcast obj to B.
So you could have:
((B)obj).getS();
Downcasting: http://www.programmerinterview.com/index.php/java-questions/downcasting-in-java/
the type class of obj is A, but A hasn't method getS() so you can't call in the main method.
obj must be class B or class C.
Related
Trying to add a base interface with method so all derived classes have to implement the method or use default method. What's the best way to going about getting this method callable? See comment in code block below.
public interface IA{}
public interface IB{
public Integer doWork();
}
public interface IC extends IB{
}
class B implements IB{
Integer doWork(){
return 2;
}
}
class C extends B implements IC{
#Override
Integer doWork(){
return 7;
}
}
//What do I need to do to cast clazz to an object so I can call the derived class' doWork method?
private Integer newClient(Class<T> clazz){
((B) clazz).doWork();
}
Ended up finding a solution:
B.class.cast(clazz);
As for how to ensure you call the derived class' method that overrides the base, that is a native behavior of Java.
Example Program:
public class Foo {
static class A {
int get() { return 0; }
}
static class B extends A {
#Override
int get() { return 1; }
}
public static void main(final String[] args)
{
A a = new A();
B b1 = new B();
A b2 = new B();
printA(a);
printA(b1);
printA(b2);
}
public static <T extends A> void printA(T bObj) {
System.out.println(bObj.get());
}
}
Output:
0
1
1
Note that the output returned from b2::get()::int is the same as b1::get()::int, even though b2 is type A and b1 is type B. This is because even though we only have a reference to the A class in b2, the object implementation is still B.
It seems that you only want to know how to instantiate the Class. Assuming it has a default constructor you can do it this way:
private Integer newClient(Class<B> clazz){
try {
((B) (clazz.getConstructor().newInstance())).doWork();
} catch ...
}
I wrote down this mini-program:
A class:
public class A
{
public A()
{
System.out.println(getS());
}
public String getS() { return s;}
}
B class:
public class B extends A
{
private String s = "hello2";
public String getS() { return s;}
}
main:
public static void main(String[] args)
{
B b = new B();
}
and it printed:
null
Why is that?
I know that the String that printed is B's string, but why it didn't initialized before?
According to this answer - the variable initialized before the constructor..
EDIT -
I edited the code so the unrelated code won't confuse
Here is what's going on: when you construct B, the first thing its constructor needs to do is constructing A. This is done before B's own field s is initialized.
A constructs its own s, and then calls getS. However, it does not get its own getS, because B provides an override for it. Recall that B.s has not been initialized yet. That is why you see null printed.
Follow-up reading: What's wrong with overridable method calls in constructors?
What is happening:
You create a B instance, this will call the super() so the constructor of A.
Here it will do the print using the getter getS(). This will use the getter of B since this is the type of this but in this getter, the String is not yet instanciate since it is still doing the super class construction, so it return null.
Note that the String s in A is hidden by the one in B
The order during an instance is :
the static (from the super then the class)
the super class declaration (statement then constructor)
the block statement
the constructor
As Seen with :
public class A{
static{System.out.println("sA");}
{System.out.println("A1");}
public Main() {
System.out.println("new A");
}
{System.out.println("A2");}
public static void main(String[] args) {
new A();
}
}
class B extends Main {
static{System.out.println("sB");}
{ System.out.println("B1"); }
public B() {
System.out.println("new B");
}
{ System.out.println("B2"); }
}
Output :
sA
sB
A1
A2
new A
B1
B2
new B
it prints null because you have polymorphism in java. You Overrided method getS(). So when you call it from A, you try to call getS() from class B. But you didn't create instance of class B yet, because you need to finish class A first. So String in class B haven't been initialized yet, because of it you get null.
i want to access method of calling class when method in called class is triggered. Following is the example i want to do. The class that is making the instance of classes C is called randomly. so when the listerners method is triggered the calling class' interface method should be able to listen that tigger.Thats what i want to do
Interface myinterface
{
public void interfacemethod();
}
class A implements myinterface
{
C instance = new C ();
public void interfacemethod()
}
class B implements myinterface
{
C instance = new C ();
public void interfacemethod()
}
Class C extends someListerner
{
public void listenercalled()
{
//here i want to call the callers interfacemethod()
}
}
You need to pass a pointer to the caller object.
If you are trying to call C's creator's Myinterface object, pass a Myinterface pointer in the C constructor.
C instance = new C(this);
Store that pointer in your C class and use it for the callback. Java functions are "virtual" by default. That means, regardless of casting, the lowest subclass function will be called (which is what you want, I think).
Interface Myinterface{
public void interfacemethod();
}
class A implements Myinterface
{
C instance = new C ((Myinterface)this);
public void interfacemethod()
}
class B implements Myinterface
{
C instance = new C ((Myinterface)this);
public void interfacemethod()
}
Class C extends someListerner
{
Myinterface ml;
public C(Myinterface arg_ml){
ml = arg_ml;
}
public void listenercalled()
{
ml.interfacemethod();
//here i want to call the callers interfacemethod()
}
}
I have an object object and I'm going to call it's method toString. How do I know in what exact class this method is implemented last?
For example if we have hierarchy:
class A /*extends Object */{
}
class B extends A{
public String toString() {
return "representation";
}
}
class C extends B{
}
class D extends C{
}
and the object
Object object = new SomeClass(); //(A/B/C/D/Object)
then for toString() I should get Object for Object and A but B for B, C and D
You can use the Method.getDeclaringClass() method:
...
private Class<?> definingClass(Class<?> clz, String method) throws NoSuchMethodException, SecurityException {
Method m = clz.getMethod(method);
return m.getDeclaringClass();
}
...
System.err.println(definingClass(A.class, "toString"));
System.err.println(definingClass(B.class, "toString"));
System.err.println(definingClass(C.class, "toString"));
System.err.println(definingClass(D.class, "toString"));
...
Result:
class java.lang.Object
class com.example.B
class com.example.B
class com.example.B
You need to extend the definingClass() method appropriately if you need to look up methods which have parameters.
public class A {
protected ClassX a;
public void foo() {
operations on a;
}
}
public class B extends A {
private ClassY b; // ClassY extends ClassX
#Override
public void foo() {
//wanna the exact same operation as A.foo(), but on b;
}
}
Sorry for such a not clear title.
My question is: in class B, when I call foo(), and I want the exact same operation as class A have on a. How do I achive that and without duplicate the same code from A?
If i leave out foo() in class B, would it work?
Or whats happening when I call super.foo() in foo();
Since ClassY extends ClassX, then you can remove private ClassY b from class B. Then you can just set your instance of ClassX to the a instance variable. This allows foo() to be inherited in class B, but still use the same logic and instance variable.
public class A {
protected ClassX a
public void foo() {
// operations on a;
}
}
public class B extends A {
// do something to set an instance of ClassY to a; for example...
public void setClassY(ClassY b){
this.a = b;
}
}
It sounds like ClassX and ClassY would have a common interface (if they have the same methods you want to call on earch, at least). Have you considered making foo() take in an object of the type of the common interface?
public class A {
private ClassX a;
protected void foo(ClassXAndClassYInheritMe anObject) {
operations on anObject;
}
public void foo() {
foo(a);
}
}
public class B {
private ClassY b;
#Override
public void foo() {
foo(b);
}
}
Don't define the foo() method in B if you want the same operation as that in A. If you want a different operation as A, override the foo() method in B. If you want to extend the foo() method in B so that it first does the operation in A and then in B, then call super.foo() at the top of the method; if you want the operation in A to come after the one in B, then call super.foo() at the end of the method foo().
You can do super.foo() inside your overrided method.