Suppose I have a base class with a function foo
public class Base
{
protected static void foo()
{
// ToDo - what is the name of the child class calling me?
}
}
and at least one child class containing a static initialiser that calls foo
public class Child extends Base
{
static
{
foo();
}
}
Is there a way of foo() knowing which child class has called it? I'm presuming there's a reflection technique I can use.
The simplest way is to pass an argument. For example
public class Base {
protected static void foo(Class<?> type) {
if (type == Child.class) {
}
}
}
public class Child extends Base {
static {
foo(Child.class);
}
}
However, if you need to do something that depends on the child class then I recommend looking for a solution that leverages abstract methods and polymorphism.
public Base {
protected static void foo(Base child) {
child.doFoo();
}
protected abstract void doFoo();
}
public Child extends Base {
static {
foo(new Child());
}
#Override
protected void doFoo() {
//do the child specific thing here
}
}
You can get the class by using the getClass method, like:
o.getClass()
also, if you have a class c and you need to check whether o is an instance of c, you can use instanceof, like this:
o instanceof c
Cheers.
Related
Objective: Define an abstract method which accepts a reference of type (or sub-type) of the implementing class.
What I came up with is:
public abstract class Parent<T extends Parent> {
public abstract void foo(T t);
}
An implementation could be:
public class Child extends Parent<Child> {
public void foo(Child child) { /* ... */ }
}
At first sight this looks like a satisfying solution, but it allows as well following implementation:
public class Child1 extends Parent<Child> {
public void foo (Child child) { /* ... */ }
}
Is there a way to define the abstract method to prevent the second implementation?
It is not totally possible to force that constraint in compilation time. However you can make it a bit more cumbersome to violate that constraint like so:
abstract class Parent<T extends Parent> {
protected Parent(Class<T> clazz) {
if (!this.getClass().equals(clazz)) {
throw new IllegalArgumentException("you must pass this; invalid attempt to extend Parent where subclass does not assign T to itself.
}
}
// ...
}
class GoodChild extends Parent<GoodChild> {
public GoodChild() { super(GoodChild.class) };
}
class BadChild extends Parent<GoodChild> {
public BadChild() { super(BadChild.class) }; // cannot compile.
}
class WorstChild extends Parent<GoodChild> {
public WorstChild() { super(GoodChild.class); } // compiles but will fail in run-time.
}
class CircularChild extends Parent<Parent> {
public CircularChild() { super(Parent.class); } // compiles but will fail
}
The trick is that the parent constructor code is binding in run-time the this's class to be the same class as T that is what you want.
I have a class in jar of which I want to invoke a method. But that method has parameter of abstract class and that abstract class is inner method of class in jar. AbstractClassA is a HIDDEN class. Here is code:
public class A{
private invokeThisMethod(AbstractClassA object){
}
public abstract class AbstractClassA {
public void update(int remaining){}
}
}
public class myClass{
//using Reflection get object of class A
objectOfClassAusingReflection.inovke("invokeThisMethod", params)
}
Problem here is how do I create concrete implementation of AbstractClassA to pass in invoke method and get update method callbacks ?
Something like this should work:
AbstractClassA a = new AbstractClassA() {
public void update(int remaining) {... do something...}
};
objectOfClassAusingReflection.inovke("invokeThisMethod", a);
You cannot create an instance of abstract class or any interface at runtime.
Instead create an anonymous class for this.
public abstract class A {
public void fun(){....}
public abstract void absFun();
}
public class MyClass {
objectOfClassA = new A(){
public void absFun(){...}
}
}
Or you can first create implementation for that abstract classes for which you will have to create another class extending A
class AWrapper extends A {
public class ImplementationClassA extends AbstractClassA {
// override abstract functions...
}
}
Now you can use this Awrapper class
AWrapper wrapperObj = new AWrapper();
A obj = wrapperObj; // just to make it clear that A can hold wrapperObj as it is implementation of it.
A.AbstractClassA absObj = wrapperObj.new ImplementationClassA();
...
objectOfClassAusingReflection.inovke("invokeThisMethod", params)
Below code should work--
Here, i used anonymus classes for both outer and inner class and then with the help of getdeclatedMethod called your update method.
"TestAbs" is your jar class--
public abstract class TestAbs {
private void invokeThisMethod(AbstractClassA object) {
}
public abstract class AbstractClassA {
public void update(int remaining) {
}
}
}
Then calling your jar class from "TestAbs1" like below--
public class TestAbs1 {
public static void main(String[] args) {
TestAbs.AbstractClassA abs = new TestAbs() {
AbstractClassA a = new AbstractClassA() {
public void update(int remaining) {
System.out.println("Inside update method : " + remaining);
}
};
}.a;
try {
int i = 1;
Class<?> class1 = Class.forName("app.test.mytest.TestAbs$AbstractClassA"); -- (*Getting instance of inner class*)
System.out.println(class1.getDeclaredMethod("update", int.class));
class1.getDeclaredMethod("update", int.class).invoke(abs, i);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
The output i got is --
public void app.test.mytest.TestAbs$AbstractClassA.update(int)
Inside update method : 1
Answer to your Comment:-
What I understood from your comment is that, you wanted to call method from abstractClass which is hidden in outerclass.
As per my understanding, there is one way like below--
public abstract class TestAbs {
private void invokeThisMethod(AbstractClassA object) {
}
private abstract class AbstractClassA { --- your hidden class
public void update(int remaining) {
}
}
public class ImplementedClass extends AbstractClassA{ -- use implemented class here
....
...
}
}
And after that, use your ImplementedClass the same way mentioned above.
You can find reference example for private inner class here from java docs.
Note: In your question context, since your inner class and outer class is in jar, so I think it is difficult for you add implementation class in your jar.
In case, you find any alternatives, please let all knows about this;
thanks.
I have these 2 classes
class A {
public void foo1() {
...;
foo2();
...;
}
protected abstract foo2();
}
class B extends A {
public foo2() {
......
}
I need foo2 to be static so I can do B.foo2() but I also want the functionality in class A to remain.n
Any suggestions?
}
You can't override static methods or implement abstract methods as static.
Static methods are defined on a class definition, not on a class instance. Abstract methods are defined on a class instance.
What you said doesn't make sense in fact.
Although I don't quite get why you need to do it, there is a workaround:
class B {
#Override
public void foo() {
fooUtil();
}
public static void fooUtil() {
// your impl here
}
}
Then you can do B.fooUtil() instead, and using its behavior to override A.foo().
I wanted to implement a method in a abstract class that is called by the inherited classes and uses their values.
For instance:
abstract class MyClass{
String value = "myClass";
void foo(){System.out.println(this.value);}
}
public class childClass{
String value="childClass";
void foo(){super.foo();}
}
public static void main(String[] args){
new childClass.foo();
}
This will output "myClass" but what I really want is to output "childClass". This is so I can implement a "general" method in a class that when extended by other classes it will use the values from those classes.
I could pass the values as function arguments but I wanted to know if it would be possible to implement the "architecture" I've described.
A super method called by the inherited class which uses the values from the caller not itself, this without passing the values by arguments.
You could do something like this:
abstract class MyClass {
protected String myValue() {
return "MyClass";
}
final void foo() {
System.out.println(myValue());
}
}
public class ChildClass extends MyClass {
#Override
protected String myValue() {
return "ChildClass";
}
}
and so on
This is a place where composition is better than inheritance
public class Doer{
private Doee doee;
public Doer(Doee doee){
this.doee = doee;
}
public void foo(){
System.out.println(doee.value);
}
}
public abstract class Doee{
public String value="myClass"
}
public ChildDoee extends Doee{
public String= "childClass"
}
...
//Excerpt from factory
new Doer(new ChildDoee);
I believe you are asking whether this is possible:
public class MyClass {
void foo() {
if (this instanceof childClass) // do stuff for childClass
else if (this intanceof anotherChildClass) // do stuff for that one
}
}
So the answer is "yes, it's doable", but very much advised against as it a) tries to reimplement polymorphism instead of using it and b) violates the separation between abstract and concrete classes.
You simply want value in MyClass to be different for an instance of childClass.
To do this, change the value in the childClass constructor:
public class childClass {
public childClass() {
value = "childClass";
}
}
Edited:
If you can't override/replace the constructor(s), add an instance block (which gets executed after the constructor, even an undeclared "default" constructor):
public class childClass {
{
value = "childClass";
}
}
Say you have a super-class. In that super class you want to pass runtime object of itself (this) as a parameter to an overloaded method. Trick is, this overloaded method is overloaded by sub-class type. When you try to do it, you'll get a
method ... is not applicable(actual argument
... cannot be converted to ... by method invocation
conversion)
Instead you would need to implement the method separately in each subtype (just to get the correct runtime class), which is a lot of duplicate effort when the contents of the method are identical.
e.g:
public class InferTypeTest {
public static void main(String[] args) {
SubClass1 s1 = new SubClass1();
s1.sayHi();
}
public static void sayHi(SubClass1 clz) {
System.out.println("clz 1");
}
private abstract static class SuperClass{
public void sayHi() {
InferTypeTest.sayHi(this);
}
}
private static class SubClass1 extends SuperClass{
}
}
Yes, this is how double dispatch works, you have to override the accept method in each subclass like this:
private static abstract class NodeWithChildren implements DomNode {
/* snip */
public void accept(DomNodeVisitor visitor) {
for (DomNode child : children) {
child.accept(visitor);
}
}
}
private static class BodyNode extends NodeWithChildren {
public void accept(DomNodeVisitor visitor) {
visitor.visit(this);
super.accept(visitor);
visitor.visited(this);
}
}
private static class DivNode extends NodeWithChildren {
public void accept(DomNodeVisitor visitor) {
visitor.visit(this);
super.accept(visitor);
visitor.visited(this);
}
}
}
BodyNode is a NodeWithChildren
DivNode is a NodeWithChidren
NodeWithChildren is a DomNode
DomPrinterVisitor is a DomNodeVisitor
DomNodeVisitor's visitor can visit "BodyNode" or "DivNode, But you are passing "NodeWithChildren" to visit.
Here BodyNode is a NodeWithChildren but NodeWithChildren is not BodyNode/
Theary is if B extends A, you can say B is a A/ not A is a B.