I am trying to cast a child to a sibling in Java (though I'm not sure if this is allowed). Basically what is written below:
public interface BaseInterface {
public int a = 5;
}
public class ClassA implements BaseInterface {
public int a = 3;
}
public class ClassB implements BaseInterface {}
public static void main(String[] args) {
BaseInterface a = new ClassA();
ClassB b = (ClassB) a;
}
I keep getting a ClassCastException. I am trying to copy all member variables from the BaseInterface object a to b. Can someone provide a solution on how to do this? Thanks!
This is not possible. Instead, you should give ClassA and ClassB copy constructors taking a BaseInterface:
public class ClassB implements BaseInterface {
public ClassB(BaseInterface other) {
//copy state from other instance
}
}
public static void main(String[] args) {
BaseInterface a = new ClassA();
ClassB b = new ClassB(a);
}
Of course this means you're copying to a new object instead of converting, but it's the only option if you want to go from a ClassA to a ClassB.
A ClassA is not a ClassB, so of course this is not allowed. Even if you suppress all warnings/errors and get the code to compile, at runtime the cast will cause a ClassCastException.
http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
public interface BaseInterface {
public int getA();
}
public class ClassA implements BaseInterface {
private final int a;
public ClassA(int a) {
this.a = a;
}
public int getA() {
return a;
}
}
public class ClassB implements BaseInterface {
private final int a;
public ClassB(BaseInterface baseInterface) {
this.a = baseInterface.getA();
}
public int getA() {
return a;
}
}
public static void main(String[] args) {
BaseInterface a = new ClassA(5);
ClassB b = new ClassB(a);
}
Will do what you want. As others noted, casting will always give a ClassCastException.
Related
I'm new in java, I want to call method class from implemented Class with interface without know class name "ClassA", which only know Object c and I have 2 file.
File (1) CobaInterface.java
package cobainterface;
public class CobaInterface {
public static void main(String[] args) {
ImplementedClass implementedClass = new ImplementedClass();
ClassA clsA = new ClassA();
implementedClass.myMethodFromClassA(clsA);
}
}
class ClassA{
public Integer getTwo(){
return 2;
}
}
interface MyInterface {
public void myMethod();
//here interface
public void myMethodFromClassA(Object c);
}
File (2) : ImpementedClass.java
package cobainterface;
public class ImplementedClass extends CobaInterface {
public void myMethodFromClassA(Object c) {
//System.out.println(c.getTwo()); <- wrong when call method c.getTwo()
}
}
How about if I want to call method getTwo() from ClassA without know Class Name, which only know Object c from file (2) as describe in code above. Thanks for advance.
You should use generic types so the implementation knows what the object will be,
interface MyInterface<T> {
public void myMethod();
//here interface
public void myMethodFromClassA(T c);
}
The impl becomes,
package cobainterface;
public class ImplementedClass Implements MyInterface<ClassA> {
public void myMethodFromClassA(ClassA c) {
//System.out.println(c.getTwo()); <- wrong when call method c.getTwo()
}
}
All together,
class Scratch {
public static void main(String[] args) {
ImplementedClass implementedClass = new ImplementedClass();
ClassA clsA = new ClassA();
implementedClass.myMethodFromClassA(clsA);
}
}
class ImplementedClass implements MyInterface<ClassA> {
#Override
public void myMethod() {
}
#Override
public void myMethodFromClassA(ClassA c) {
System.out.println(c.getTwo());
}
}
class ClassA {
public Integer getTwo() {
return 2;
}
}
interface MyInterface<T> {
void myMethod();
void myMethodFromClassA(T c);
}
You could also do a cast
System.out.println((MyClass)c.getTwo());
but you will lose all benefit of type saftey.
I have two classes A and B and they both have a common field in them, and I want to create a function in which if I pass Class A object then I want to set that common field value to the passed value and if I pass Class B object then I want to set that common field value to the passed value. Can anyone please tell me how can I do this, I am new to Java Generic Classes.
Otherwise I would have to make two different functions OR I would have to make an if and else which would decide that passed object belongs to which class ??
Class A
public class A{
int footer;
public void setFooter(int fo) {
footer = fo;
}
}
Class B
public class B{
int footer;
public void setFooter(int fo) {
footer = fo;
}
}
Class D
public class D{
public void change_footer(T generic_param, int value) {
generic_param.setFooter(value);
}
}
Class HelloWorld
public class HelloWorld{
public static void main(String []args){
Here I want to call
A a = new A();
new D().change_footer(a, 5);
B b = new B();
new D().change_footer(b, 5)
}
}
Thank You
And if I got all of the question wrong, and nor A nor B are generic, AND the type of field is fixed.
then you mean something like:
class D {
/*public <T extends Super> would be muuuch nicer here as well!*/
public /*static*/ <T> void change_footer(T obj, int data) {
//otherwise, you could just cast to Super...and set dat field.
if (obj instanceof A) {
((A) obj).setField(data);
} else if (obj instanceof B) {
((B) obj).setField(data);
} // else ... ?
}
}
Original answer:
Easy peasy (the "straight forward" implementation produces the desired results.):
class A<T> {
T daField;
public void setField(T pField) {
daField = pField;
}
public T getField() {
return daField;
}
}
class B<T> extends A {//empty
}
class Test {
public static void main(String... args) {
B<Object> testB1 = new B<>(); //
testB1.setField(new Object());
System.out.println(testB1.getField());
B<String> testB2 = new B<>();
testB2.setField("blah blah");
System.out.println(testB2.getField());
B<Integer> testB3 = new B<>();
testB3.setField(42);
System.out.println(testB3.getField());
}
}
System.out:
java.lang.Object#6d06d69c
blah blah
42
It get's (little) more complicated, when you want to instantiate Ts ...but still possible/other question. :)
Edit to your comment:
If there's only one common field, then why not:
/*abstract */class Super<T> {
T daField;
public void setField(T pField) {
daField = pField;
}
public T getField() {
return daField;
}
}
? ...and:
class A<T> extends Super { ... }
class B<T> extends Super { ... }
public class MyTest {
public static void main(final String[] args) {
B b = new B();
b.print();
}
}
class A {
private final int x = 5;
protected int getX() {
return x;
}
public void print() {
System.out.println(getX());
}
}
class B extends A {
private final int x = 10;
#Override
protected int getX() {
return x;
}
}
In this example, I need to print subclass value in the parent class.
It is working fine. No issue.
Now it is printing 10.
But I do not want to define that property in the parent class A.
Because in this example this x datatype is very simple. So no issue.
But in real-time I want to use other datatype which may be another Class variable or List<something> which have huge data.
So ultimately I do not wish to store that value in Class A.
Because it is redundant data. It will slow down in my Hibernate thing.
Please let me know, how to achieve this without declaring variable in parent class. But I still need to use subclass variable in parent class.
make abstract your class A and the getX(); method.
public class Test {
public static void main(final String[] args) {
B b = new B();
b.print();
}
}
abstract class A {
protected abstract int getX();
public void print() {
System.out.println(getX());
}
}
class B extends A {
private final int x = 10;
#Override
protected int getX() {
return x;
}
}
and override the toString method in place of your print method
#Override
public String toString() {
return String.valueOf(getX());
}
the final code
public class Test {
public static void main(final String[] args) {
B b = new B();
System.out.println(b);
}
}
abstract class A {
protected abstract int getX();
#Override
public String toString() {
return String.valueOf(getX());
}
}
class B extends A {
private static final int X = 10;
#Override
protected int getX() {
return X;
}
}
you could also define as static your x variable
But as say Andrew Tobilko you can consider also to use an interface if A doesn't represent a stateful entity.
It's certainly the best solution for your case, mix the use of an interface and an abstract class
public class Test {
public static void main(final String[] args) {
B b = new B();
System.out.println(b);
}
}
interface MyInterface {
int getX();
}
abstract class A implements MyInterface{
#Override
public String toString() {
return String.valueOf(getX());
}
}
class B extends A {
private static final int X = 10;
#Override
public int getX() {
return X;
}
}
You need the getX within the parent class, but you don't have information enough to implement this method there.
You can declare this class as abstract and mark the method with abstract as well. Doing that, you are handing the responsibility of method implementation over its subclasses and preventing from parent field declaration.
If the A doesn't describe any state (only actions/methods), you should consider replacing it with an interface. At the current state, it is the case.
You could make the parent class abstract, eliminate the property in the parent class, make getX() abstract, and then leave print() as concrete. Then just use the concrete implementation of getX() in the child class.
Structure
-ClassA
|---|
|---ClassAImplA
|---ClassAImplB
-Main
Class A:
public interface ClassA {
public void execute();
}
Implementaion A:
public class ClassAImplA implements ClassA
{
private int a = 5;
public ClassAImplA (int a){setA(a);}
#Override
public void execute() {
System.out.println(a);
}
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
Implementaion B:
public class ClassAImplB implements ClassA
{
private boolean b = false;
public ClassAImplB (int a){setB(b);}
#Override
public void execute() {
System.out.println(b);
}
public booelan getB() {
return b;
}
public void setA(boolean b) {
this.b = b;
}
main:
public class main {
/**
* #param args
*/
public static void main(String[] args) {
ClassAImplA param1 = new ClassAImplA(10);
ClassA = param1;
}
}
By doing this I make ClassA interchangeable,
but I lose the capability to access the parameter int a.
Is there a way to still make it interchangeable, and still have access to int a,
or in case of ClassAImplB, the field boolean b ?
There is a way, but it's not a good idea to do, as it defeats the purpose:
ClassAImplA param1 = new ClassAImplA(10);
ClassA = param1;
if (param1 instanceof ClassAImplA) {
param1x = (ClassAImplA) param1;
System.out.println(param1x.getA());
}
But don't do this. It defeats the purpose of the pattern.
The purpose of the pattern is to use objects of type ClassA,
without having to know how they work.
The getA method is only defined in ClassAImplA,
it's an implementation detail that should not be relevant to users of the ClassA type.
They shouldn't have to know. It's hidden.
This is called good encapsulation and information hiding.
you need one more class using composition to decide which implementation is needed.
public ClassHelper{
private A a;
public ClassHelper(A a){
this.a = a;
}
public void execute() {
this.a.execute();
}
}
public class main {
/**
* #param args
*/
public static void main(String[] args) {
ClassHelper param1 = new ClassHelper(new ClassAImplA(10));
param1.execute();
//or when you need classBIMpl
param1 = new ClassHelper(new ClassAImplB(true));
param1.execute();
}
}
And about the ability to access member of implA or implB , no you cannot have that flexibilty with this patter, whole point of this pattern is that caller need not be aware of implementation details.
Define an interface for the strategy and a Factory with different overloaded methods to create the concrete instances of the classes. Of course the methods are typed to the interface instead of the concrete classes.
The interface.
public interface Strategy {
void execute();
}
The first implementation.
public class ConcreteStrategy implements Strategy {
private boolean a;
public ConcreteStrategy(final boolean a) { this.a = a; }
public void execute() {}
}
The second implementation.
public class AnotherConcreteStrategy implements Strategy {
private int a;
public AnotherConcreteStrategy(final int a) { this.a = a; }
public void execute() {}
}
The factory.
public class Factory {
public static Strategy create(final boolean a) {
return new ConcreteStrategy(a);
}
public static Strategy create(final int a) {
return new AnotherConcreteStrategy(a);
}
}
Suppose I have a class A and a class B.
public class A {
private B b;
public A() {
this.b = new B();
}
public B getB() {
return this.b;
}
}
public class B {
public String getSome() {
return "Get some!";
}
}
I know I can get B through A, because A has (or owns) B: new A().getB().
But if I have B, can I get A?
Sure, just add routine getA() in you class B, and change the line in your constructor to
public A() {
this.b = new B(this);
}
This of course assumes your class B has a constructor which accepts an A, e.g.,
public B(A a) {
this.a = a;
}
B needs an explicit reference to its owner:
public class B {
private final A owner;
public B(A owner) {
this.owner = owner;
}
public A getOwner() {
return owner;
}
}
And in A:
public A() {
b = new B(this);
}
Nope. There is no such thing as an 'owner' in Java. Any object can be referenced by any number of other objects.
If you need B to always be bound to an instance of A, make B an inner class of A:
class A {
B b = new B();
class B {
String getSome() {
// this will refer to the enclosing A
return A.this.toString();
}
}
}
An inner (non-static) class always has an implicit reference to the enclosing instance and cannot exist without it. In order to instantiate B from outside, you need a nasty syntax: B b = new A().new B();
No you cannot. B has no reference to A.
No.
Class a has reference to class B, but class B has no reference to class A. References are one way only.
No, that's not possible. You're looking for backreferences, but we have to create them in the code if needed.
If you want to collect all referencers to B, you could do this with a constructor or with a factory (pattern) that creates B's. I'll show the factory:
public class B {
private static Set<? extends Object> referencers = new HashSet<? extends Object>();
private B(){} // no public constructor
public static create(Object parent) {
// cooperative approach, the caller should pass "this"
referencers.add(parent);
}
public static remove(Object parent) {
referencers.remove(parent);
}
}
you can also use inner classes
package test;
public class A {
B b = null;
public B getB()
{
return b;
}
public class B {
public A getA()
{
return A.this;
}
}
public static void main(String[] args) {
B b = new A().new B();
}
}