Cast parent to its child - java

I have:
class A
{
public String getID() { return "id of A";}
}
class B extends A
{
public String getID() { return "id of B"; }
}
and
class C {
public A returnA() {
return new A();
}
}
Now I somehow need to do:
C c = new C();
B b = (B)c.returnA();
String id = b.getId();
But I don't have access to implementation of C.returnA(), and I can't change return type of it to B.

You are casting a parent into a children.
You can never do that, because new A() is absolutely not a B.
Consider this: String extends Object. Now try to cast (String) new Object(). It wouldn't make any sense at all.
Because your object is not a B anyway, there is no way it could have the behavior of B.
What you want here is use a Decorator Pattern. See http://en.wikipedia.org/wiki/Decorator_pattern
Here is an example of what a implementation of a Decorator could be:
public class B extends A {
private A decorated;
public B(A decorated) {
this.decorated = decorated;
}
#Override
public String getID() {
return "id of B";
}
#Override
public void otherMethodOfA() {
return decorated.otherMethodOfA();
}
}
Note that it is mandatory to override all methods of A to make sure you call the method on the decorated element. (here otherMethodOfA is an example)
Use like this:
C c = new C();
B b = new B(c.returnA());
String id = b.getID();

That won't work. c.returnA() returns an A. An A is not a B. (A B is an A, but that's not relevant here).

The answer of njzk2 is perfect. Anyway, if you ended up reading this post and like me, you don't like overriding every method, you can just do this:
public class B extends A {
public B(A nonDecorated) {
this.anotherValueOfA = nonDecorated.getAnotherValueOfA();
}
#Override
public String getID() {
return "id of B";
}
}
There is no need to override every method and the object is constructed with the values from its parent.
This is, of course, assuming class A is:
class A {
private int anotherValueOfA;
public String getID() {return "id of A";}
public int getAnotherValueOfA() {return this.anotherValueOfA;}
}

Related

What is the idiomatic way to write common code for a group of classes with identical methods, but not implementing the same interface?

I'm using an external library that provides tightly related classes (generated from some template), but unfortunately without a shared interface, e.g.
public class A {
public UUID id();
public Long version();
public String foo();
public String bar();
}
public class B {
public UUID id();
public Long version();
public String foo();
public String bar();
}
public class C {
public UUID id();
public Long version();
public String foo();
public String bar();
}
// ... and more: D, E, F, etc.
Given I have no influence over the external library, what's the idiomatic way to write logic common to a group of classes that share the same method signatures (at least, for the methods being used by the common logic)?
Currently I do one of three things, on a case-by-case basis:
I write helper methods that take the primitive results from each object, e.g.
private static void myHelper(UUID id, Long version, String foo, String bar) {
...
}
This way I can "unpack" an object regardless of its type:
myHelper(whatever.id(), whatever.version(), whatever.foo(), whatever.bar());
But that can get very wordy, especially when I need to work with many members.
In the scenario where I'm only working with getters (i.e. only need to access current values of the objects), I've found a way to use mapping libraries like Dozer or ModelMapper to map A or B or C to my own common class, e.g.
public class CommonABC {
UUID id;
Long version;
String foo;
String bar;
}
By playing with configuration, you can get these libraries to map all members, whether method or field, public or private, to your class, e.g.
modelMapper.getConfiguration()
.setFieldMatchingEnabled(true)
.setFieldAccessLevel(Configuration.AccessLevel.PRIVATE);
But this was kind of a "broadsword" approach, a hack that IMO isn't clearly justified merely to factor out duplicate code.
Finally, in certain other scenarios it was most succinct to simply do
private static void myHelper(Object extLibEntity) {
if (extLibEntity instanceof A) {
...
} else if (extLibEntity instanceof B) {
...
} else if (extLibEntity instanceof C) {
...
} else {
throw new RuntimeException(...);
}
}
It's obvious why this is bad.
In enterprise situations where you have to live with a library that is this way, what would you do?
I'm leaning toward writing a very explicit, if verbose, mapper (not using a generic mapper library) that translates these entities from the start. But, I wonder if there's a better way. (Like, is there a way to "cast" an object as implementing a new interface, in runtime?)
An option that is (under the hood) likely similar to the second approach, but comparatively lean and flexible, is to use Dynamic Proxy Classes. With only a few lines of code, you can let any object "appear" to implement a certain interface, as long as it has the required methods. The following is an MCVE that shows the basic approach:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.UUID;
public class DelegatingProxyExample {
public static void main(String[] args) {
A a = new A();
B b = new B();
C c = new C();
CommonInterface commonA = wrap(a);
CommonInterface commonB = wrap(b);
CommonInterface commonC = wrap(c);
use(commonA);
use(commonB);
use(commonC);
}
private static void use(CommonInterface commonInterface) {
System.out.println(commonInterface.id());
System.out.println(commonInterface.version());
System.out.println(commonInterface.foo());
System.out.println(commonInterface.bar());
}
private static CommonInterface wrap(Object object) {
CommonInterface commonInterface = (CommonInterface) Proxy.newProxyInstance(
CommonInterface.class.getClassLoader(),
new Class[] { CommonInterface.class }, new Delegator(object));
return commonInterface;
}
}
// Partially based on the example from
// https://docs.oracle.com/javase/8/docs/technotes/guides/reflection/proxy.html
class Delegator implements InvocationHandler {
private static Method hashCodeMethod;
private static Method equalsMethod;
private static Method toStringMethod;
static {
try {
hashCodeMethod = Object.class.getMethod("hashCode", (Class<?>[]) null);
equalsMethod = Object.class.getMethod("equals", new Class[] { Object.class });
toStringMethod = Object.class.getMethod("toString", (Class<?>[]) null);
} catch (NoSuchMethodException e) {
throw new NoSuchMethodError(e.getMessage());
}
}
private Object delegate;
public Delegator(Object delegate) {
this.delegate = delegate;
}
public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
Class<?> declaringClass = m.getDeclaringClass();
if (declaringClass == Object.class) {
if (m.equals(hashCodeMethod)) {
return proxyHashCode(proxy);
} else if (m.equals(equalsMethod)) {
return proxyEquals(proxy, args[0]);
} else if (m.equals(toStringMethod)) {
return proxyToString(proxy);
} else {
throw new InternalError("unexpected Object method dispatched: " + m);
}
} else {
// TODO Here, the magic happens. Add some sensible error checks here!
Method delegateMethod = delegate.getClass().getDeclaredMethod(
m.getName(), m.getParameterTypes());
return delegateMethod.invoke(delegate, args);
}
}
protected Integer proxyHashCode(Object proxy) {
return new Integer(System.identityHashCode(proxy));
}
protected Boolean proxyEquals(Object proxy, Object other) {
return (proxy == other ? Boolean.TRUE : Boolean.FALSE);
}
protected String proxyToString(Object proxy) {
return proxy.getClass().getName() + '#' + Integer.toHexString(proxy.hashCode());
}
}
interface CommonInterface {
UUID id();
Long version();
String foo();
String bar();
}
class A {
public UUID id() {
return UUID.randomUUID();
}
public Long version() {
return 1L;
}
public String foo() {
return "fooA";
}
public String bar() {
return "barA";
}
}
class B {
public UUID id() {
return UUID.randomUUID();
}
public Long version() {
return 2L;
}
public String foo() {
return "fooB";
}
public String bar() {
return "barB";
}
}
class C {
public UUID id() {
return UUID.randomUUID();
}
public Long version() {
return 3L;
}
public String foo() {
return "fooC";
}
public String bar() {
return "barC";
}
}
Of course, this uses reflection internally, and should only be used when you know what you're doing. Particularly, you should add some sensible error checking, at the place that is marked with TODO: There, the method of the interface is looked up in the given delegate object.
The only technique not tried:
package aplus;
public interface Common {
...
}
public class A extends original.A implements Common {
}
public class B extends original.B implements Common {
}

How to access a parent class variable via a child class

I am trying to re-build an OOP approach to mobile verification at the developers discretion. The concept I come up with is to allow for interfaces to manipulate the class. If the class implements the interface, then the verify method will be executed.
The problem I am facing, because I am only used to programming in less strongly-typed languages (PHP) is how to get a protected variable from a class extending the current class.
_areaCodes.stream().forEach(o -> {
try {
int prefix = Integer.parseInt(this._mobileNumber.charAt(0), this._mobileNumber.charAt(1));
} catch (Exception e) {}
});
This line of code is now giving me an error
_mobileNumber cannot be resolved or is not a field
Here is my full code and here is an example I wrote of the same concept in PHP which I am trying to implement in Java.
import java.util.ArrayList;
interface Verification
{
public void initVerification();
}
class AreaCode
{
private int _code;
private String _country;
public AreaCode(int code, String country)
{
this._code = code;
this._country = country;
}
public int getAreaCode() { return this._code; }
public String getAreaCountry() { return this._country; }
}
class VerificationHandler
{
private ArrayList<AreaCode> _areaCodes = new ArrayList<AreaCode>() {{
this.add(new AreaCode(44, "UNITED KINGDOM"));
this.add(new AreaCode(91, "INDIA"));
}};
public void initVerification()
{
if(this instanceof Verification) {
this.verify();
}
}
protected void verify()
{
_areaCodes.stream().forEach(o -> {
try {
int prefix = Integer.parseInt(this._mobileNumber.charAt(0), this._mobileNumber.charAt(1));
} catch (Exception e) {}
});
}
}
class Main extends VerificationHandler implements Verification {
protected String _mobileNumber = "+447435217761";
}
public class Hack1337 { public static void main(String[] args) { new Main(); } }
How can I retrieve a variable in a class extending another, ie:
class A { public String getB() { return this.b; } }
class B extends A { protected String b = 'A should get this'; }
B b = new B().getB();
Only instances of class B, or sub-classes of B can access the b instance variable directly (unless you cast A to B within the body of the A class, which is bad practice).
You can give class A read-only access to that value by overriding getB():
class B extends A
{
protected String b = 'A should get this';
#Override
public String getB() {
return this.b;
}
}
and you may also want to make the getB() method abstract in class A (which means making class A abstract):
abstract class A
{
public abstract String getB();
}
This would only make sense if different sub-classes of A are expected to return different things in getB(). Otherwise, you may as well move the b variable to the base class A.

Common method to set values of the fields for the parent class

I have a Response class which contains n number of fields and there are multiple classes which extend my Response class. In every method I need to set fields of the response class along with my sub class fields, instead i want to create a common method which sets all the fields of my parent class and returns me the sub class.
Parent Class
class Response{
private String a;
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
}
Sub Class 1
class Custom extends Response{
private String b;
public String getB() {
return b;
}
public void setB(String b) {
this.b = b;
}
}
Sub Class2
class Custom1 extends Response{
private String c;
public String getC() {
return c;
}
public void setC(String c) {
this.c = c;
}
}
method 1
public Custom setFields(String aValue,String bValue){
Custom c = new Custom();
c.setA(aValue);
c.setB(bValue);
return c;
}
method 2
public Custom1 setFields(String aValue,String cValue){
Custom1 c1 = new Custom1();
c1.setA(aValue);
c1.setC(cValue);
return c1;
}
I want to create a method which sets the value of the fields belonging to the Response class and return me the same class object Custom or Custom1 respectively
Ex:
Custom c = setResponseValue(aValue); OR
Custom1 c1 = setResponseValue(aValue);
Methods something like
public Custom/Custom1 setResponseValue(String value){
/**
Sets the value
**/
return Custom/Custom1;
}
Please help as i need to do the same thing over and over again.Problem increase as the no of fields increase in the response class.
Since you want to return a child class with the value of the parent set, you could have your child class constructor with an input value and use it to set the value on the parent.
public class Response {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
public class Child extends Response {
public Child(String value) {
setValue(value);
}
}
And then use it like this:
Child childResponse = new Child("hey");
Update:
I am not sure I understand exactly what you mean, but if you do not want to set the value in the constructor, and you don't want to set the value for an existing child object, maybe you need a cloned object returned with this new value. Make sure your class supports the Cloneable interface and:
public Child cloneAndSetValue(String value) throws CloneNotSupportedException {
Child c = (Child) this.clone();
c.setValue(value);
return c;
}
If you want setResponseValue to be outside of your pojo classes then you need to tell it how to create a specific subclass. Here is how you can accomplish it with Java lambdas and generics:
Custom c1 = setResponseValue( Custom::new, "a1" );
Custom1 c2 = setResponseValue( Custom1::new, "a1" );
public static <T extends Response> T setResponseValue(Supplier<T> s, String value){
T result = s.get();
result.setA(value);
return result;
}

Java: how does a component know its owner

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();
}
}

Inheritance in Java

Consider the following code in Python:
class A(object):
CLASS_ATTRIBUTE = 42
def f(self):
return "CLASS_ATTRIBUTE: %d" % self.CLASS_ATTRIBUTE
class B(A):
CLASS_ATTRIBUTE = 44
Now A().f() and B().f() return "CLASS_ATTRIBUTE: 42" and "CLASS_ATTRIBUTE: 44" respectively.
How can I achieve a similar effect in Java? I want a CLASS_ATTRIBUTE field to be initialized statically and redefined in the inherited class but the f method should be only defined in the base class.
Is there a particular reason you want the attribute to be static? In Java the typical way you'd do this is to have A contain a protected variable that you then set in the constructors of the 2 classes:
public class A
{
protected int CLASS_ATTRIBUTE;
public A()
{
CLASS_ATTRIBUTE = 42;
}
public String f()
{
return "CLASS_ATTRIBUTE: " + CLASS_ATTRIBUTE;
}
}
public class B extends A
{
public B()
{
CLASS_ATTRIBUTE = 44;
}
}
Alternatively (and probably more consistent with Java design patterns) you'd declare a function that you can override to return the value instead of using a member variable.
Short answer: you cant solve it like this in Java. You'll have to solve it in another way.
In Java you can't override or "redeclare" fields in subclasses, and you can't override static methods.
It can be solved using an ugly reflection-hack (should be avoided though):
public class Main {
public static void main(String... args) {
A a = new A();
B b = new B();
System.out.println(a.f()); // Prints 42.
System.out.println(a.fReflection()); // Prints 42.
System.out.println(b.f()); // Prints 42.
System.out.println(b.fReflection()); // Prints 44.
}
}
class A {
static int CLASS_ATTRIBUTE = 42;
public int f() {
return CLASS_ATTRIBUTE;
}
public int fReflection() {
try {
return getClass().getDeclaredField("CLASS_ATTRIBUTE").getInt(null);
} catch (Exception wontHappen) {
return -1;
}
}
}
class B extends A {
// Compiles, but will not "override" A.CLASS_ATTRIBUTE.
static int CLASS_ATTRIBUTE = 44;
}
You can't do this directly with only a variable, because in Java variables cannot override (they only shadow the super classes variables).
You need to use a protected "getter" method, which can then be overridden by the subclass:
class A
{
private int attribute=42;
...
protected int getAttribute() {
return attribute;
}
}
class B
extends A
{
private int attribute=44;
...
protected int getAttribute() {
return attribute;
}
}
But note there's a special consideration to calling methods from an object's constructor, in that it allows object code to run before object construction is complete.
I'm not sure if you meant "statically" literally or not, but here's a brief example of how inheritance at it's most basic form looks in Java. Note that using a getter method to access the variable is a better idea for several reasons -- this is just an example.
public class Dog {
protected String whatISay = "Woof!";
public void speak(){
System.out.println(whatISay);
}
}
public class Poodle extends Dog {
public Poodle(){
whatISay = "Yap!";
}
}
public class Main {
public static void main(String[] args){
Poodle fluffy = new Poodle();
fluffy.speak();
Dog dog = new Dog();
dog.speak();
}
}
Yap!
Woof!
This way of doing it introduces as little intrusion as I could think of. setAttribute() could be named something like setDefaultValue() if that's clearer.
public class A
{
protected int attribute;
public A()
{
setAttribute();
}
public String f()
{
return "CLASS_ATTRIBUTE: " + attribute;
}
protected void setAttribute()
{
attribute = 42;
}
}
public class B extends A
{
#Override
protected void setAttribute()
{
attribute = 44;
}
}
public class Main
{
public static void main(String[] args)
{
A a = new A();
B b = new B();
System.out.println("A: " + a.f());
System.out.println("B: " + b.f());
}
}

Categories

Resources