Is there any way by which I can cast a reference of type Object, assuming that the reference could point to any class I defined, to said defined class at runtime?
I've been trying to work it out and the code I came out with is:
public class SomeTestBench {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
myEntity a = new myEntity("Hello Code!");
Receptacle cage = new Receptacle();
cage.injectYourEntity(a);
((cage.itsClass) cage.theEntity).exertExistence();
}
}
That unfortunately does not work, as the class argument to that cast must be static.
Rest of the code:
public class myEntity extends Object{
String warcry;
myEntity(String warcry){
this.warcry = warcry;
}
public void exertExistence(){
System.out.println(this.warcry);
}
}
public class Receptacle {
Object theEntity;
Class itsClass;
public void injectYourEntity(Object it){
this.theEntity = it;
this.itsClass = it.getClass();
}
public void prodIt(){
System.out.println(theEntity.getClass());
}
}
Why don't you just do this using Generics.
public static void main(String[] args) {
myEntity a = new myEntity("Hello Code!");
Receptacle<myEntity> cage = new Receptacle<>();
cage.injectYourEntity(a);
cage.theEntity.exertExistence();
}
//
//That unfortunately does not work, as the class argument to that cast must be static.
//
//Rest of the code:
class myEntity {
String warcry;
myEntity(String warcry){
this.warcry = warcry;
}
public void exertExistence(){
System.out.println(this.warcry);
}
}
class Receptacle<T> {
T theEntity;
public void injectYourEntity(T it){
this.theEntity = it;
}
public void prodIt(){
System.out.println(theEntity.getClass());
}
}
To call a no-arg method named exertExistence() on an object of unknown type, you have three choices:
Use generics. See answer by WJS.
Use reflection:
Receptacle cage = new Receptacle();
cage.injectYourEntity(new myEntity("Hello Code!"));
Method method = cage.itsClass.getMethod("exertExistence", null);
method.invoke(cage.theEntity, null);
Use an interface (recommended):
Receptacle cage = new Receptacle();
cage.injectYourEntity(new myEntity("Hello Code!"));
cage.theEntity.exertExistence();
interface MyInterface {
void exertExistence();
}
class myEntity implements MyInterface {
String warcry;
myEntity(String warcry){
this.warcry = warcry;
}
#Override
public void exertExistence(){
System.out.println(this.warcry);
}
}
class Receptacle {
MyInterface theEntity;
public void injectYourEntity(MyInterface it){
this.theEntity = it;
}
}
Related
As in the example below, I need to do an operation on an object of type A passing a reference to an object of type B to the function, but the expression is invalid:
a.setId(a.getId());
public class Example {
public static void main() {
A<?> a = new B();
useA(a);
B b = new B();
useA(b);
useB(b);
}
static void useA(A<? extends A.AId> a) {
a.setId(a.getId());
}
static void useB(B b) {
b.setId(b.getId());
}
}
interface A<ID extends A.AId> {
ID getId();
void setId(ID id);
interface AId {
}
}
class B implements A<B.BId> {
#Override
public BId getId() {
return null;
}
#Override
public void setId(BId id) {
}
static class BId implements A.AId {
}
}
What type should the a parameter of the useA function be for correct assignment?
Hello you can try it.
static <T extends A.AId> void useA(A<T> a) {
a.setId(a.getId());
}
interface Y {
void search(String name);
}
class A implements Y {
void search(String name) {
//Is it possible to say: "If I was called from class B then do a search("B");
}
}
class B extends A {
}
public class Main {
public static void main(String[] args) {
B b = new B();
b.search();
}
}
Given the above code is it possible to reason in superclass which subclass was used for calling a method?
The reason I want to do this is because the code in Search is very similar for all Subclasses, the only thing that changes is the Classname, so I thought there is no need to Override in each subclass. I have updated the code to reflect this. Please let me know if there is a better way of doing it/
Calling this.getClass() inside your search method will give you the concrete class of the current instance.
For example:
class Example
{
static class A {
public void search() {
System.out.println(getClass());
}
}
static class B extends A {}
public static void main (String[] args) throws java.lang.Exception
{
new A().search();
new B().search();
}
}
outputs
class Example$A
class Example$B
The cleanest way to do it is to override the method in each subclass.
interface Y {
void search();
}
class A implements Y {
public void search(){
search("A");
}
protected void search(String name) {
// implement your searching algoithm here
}
}
class B extends A {
public void search(){
search("B");
}
}
public class Main {
public static void main(String[] args) {
B b = new B();
b.search();
}
}
That's the way inheritance is suppose to works. A super class should not know its subclasses.
And, in case you extends your class B, you can easily either:
-Keep the same behaviour as B:
class C extends B {
// do nothing, when calling search, it calls the method implemented in B
}
-Change the behaviour to search for "C"
class C extends B {
public void search(){
search("C"); // or search("whateveryouwant")
}
}
You can simply override the method in class B.
The other way could be to write the search() method as
void search() {
if (this.getClass().equals(B.class)) {
//The logic for B
} else if (this.getClass().equals(A.class)) {
//The logic for A
}
}
You have to provide the fully qualified name for the class.
Better follow template pattern.
interface Y {
void search(String name);
}
abstract class AbstractionTemplate implements Y{
#Override
public void search(String name) {
//a lot of code.
System.out.println("common stuff start");
doImplspecificStuffOnly();
System.out.println("common stuff end");
//a lot of code.
}
abstract void doImplspecificStuffOnly();
}
class A extends AbstractionTemplate{
#Override
void doImplspecificStuffOnly() {
System.out.println("a's stuff");
}
}
class B extends A {
#Override
void doImplspecificStuffOnly() {
System.out.println("B's stuff");
}
}
public class Main {
public static void main(String[] args) {
B b = new B();
b.search("hey");
}
}
interface Sporty {
public void beSporty();
}
class Ferrari implements Sporty {
public void beSporty() {
System.out.println("inside Ferrari impelemnting Sporty");
}
}
class RacingFlats implements Sporty {
public void beSporty() {
System.out.println("inside RacingFlats impelemnting Sporty");
}
}
public class TestSportythings {
public static void main(String[] args) {
Sporty[] sportyThings = new Sporty[3];
sportyThings[0] = new Ferrari();
sportyThings[1] = new RacingFlats();
}
}
You can call methods from Array instance of the interface by an object of a class which is implemented that method of the interface.
Like the following:
sportyThings[0].beSporty();
And you will get output:
inside Ferrari impelemnting Sporty
But if you call beSporty() by
sportyThings[2].beSporty();
You will get NullPointerException as sportyThings[2] is not initialized (by new).
I have few classes that implements some interface. Now I want to create new class, which can extend one of them, based on runtime calculation while using interfaces methods. Let's talk in code:
public interface Interface {
public void doSomething();
}
public class A implements Interface {
#Override
public void doSomething() {
System.out.println("hello");
}
}
public class B implements Interface {
#Override
public void doSomething() {
System.out.println("hi");
}
}
These are existing classes, so now I need to do something like this (which is not working of course):
public class C<T extends Interface> extends T {
public void doSomethingElse() {
this.doSomething();
}
public static void main(String[] args) {
C c;
if(isSomethingLoaded) {
c = new C<A>();
} else {
c = new C<B>();
}
c.doSomethingElse();
}
}
Is it possible somehow, except the way that I pass argument Interface other to C's constructor and store to class property..?
A class cannot extend from its type parameter.
Use composition instead of inheritance:
public class C<T extends Interface> {
private final T foo;
public C(T foo){
this.foo = foo;
}
public void doSomethingElse() {
foo.doSomething();
}
public static void main(String[] args) {
C<?> c;
if(isSomethingLoaded) {
c = new C<>(new A());
} else {
c = new C<>(new B());
}
c.doSomethingElse();
}
}
You might even not need the type parameter here, but just use the interface type as argument/ member type.
I think it's situations like this which show why we have the rule of favouring composition over inheritance. Consider this solution using composition:
public class Test {
public interface Interface {
void doSomething();
}
public static class A implements Interface {
#Override
public void doSomething() {
System.out.println("Doing A");
}
}
public static class B implements Interface {
#Override
public void doSomething() {
System.out.println("Doing B");
}
}
public static class C implements Interface {
private Interface composedWith;
public C(Interface i) {
this.composedWith = i;
}
#Override
public void doSomething() {
this.composedWith.doSomething();
}
}
public static void main(String[] args) {
C c;
if(isSomethingLoaded) {
c = new C(new A());
} else {
c = new C(new B());
}
c.doSomething();
}
}
Personally, I feel this is a clearer and move flexible way of achieving what you are trying to do.
I have generic class :
public class Test<T> {
private Test<? extends T> myInstance;
public Test<? extends T> getInstance () {
return myInstance;
}
public void setInstance (Test<? extends T> argType) {
this.myInstance = argType;
}
}
And I have two classes in my class hierarchy relations:
public abstract class Alphabet {
//code here
}
and
public class A extends Alphabet{
public A() {
super();
System.out.print("This is A call");
}
}
Finally I have a class where I want to store make generic class Test with particular type and set new Instance of Object -> A through setInstance() method:
public static void main(String[] args) {
List<Alphabet> list = new ArrayList<Alphabet>();
Test<Alphabet> tAlphabet = new Test<Alphabet>();
tAlphabet.setInstance(new A()); //Here is compilation ERROR
}
But I have got the compilation error in line tAlphabet.setInstance(new A());
What is the issue with my generic class?
Your instance is a Test object as it's currently written, and you are supplying it with an Alphabet object instead. You probably want your instance to be of type Alphabet:
public class Test<T> {
private T myInstance;
public T getInstance() {
return myInstance;
}
public void setInstance(T argType) {
myInstance = argType;
}
}
This way, your Test stores an Alphabet instead of another Test.
It seems you have made things more complicated than needed. You probably want this in your Test class instead of what you actually have:
private T myInstance;
public T getInstance () {
return myInstance;
}
public void setInstance (T argType) {
this.myInstance = argType;
}
With this arrangement you would be free to setInstance(new A()) on a Test<Alphabet> instance.