I'm currently writing a class, that should serve as an add-on to already existing classes. For example, let my add-on class be the following:
public class NewClass {}
Also, assume there already exist classes like:
public final class ExistingClassA {}
public final class ExistingClassB {}
...
These I am not allowed to change.
For some algorithms, I'd like to define the existing classes to be children of my NewClass, though. So instead of inherit from some class with extends, I kind of want to achieve the opposite: I want to "adopt" a class, as if the existing classes were originally defined this way:
public final class ExistingClassA extends NewClass {}
public final class ExistingClassB extends NewClass {}
...
Is this even possible in Java? And if so, is it also possible to add a class as a parent of a class, which already extends another class?
Edit:
To make my situation a bit clearer, I'll try describing what I want to achieve in more detail. E.g. assume a variable myVar, which should only be instance of specific classes. If those classes belonged to a common parent class, this wouldn't be a problem:
public final class ExistingClassA extends CommonParentClass {}
public final class ExisitingClassB extends CommonParentClass {}
public final class ExistingClassC extends CommonParentClass {}
...
/* We're inside some class now... */
CommonParentClass myVar; // May be of ExistingClassA, ExistingClassB, or ExistingClassC.
Now say, I want myVar to be only of the class ExistingClassA or ExistingClassB. Assuming I could "adopt" those two classes with my NewClass, I could also just write:
NewClass myVar; // May be of ExistingClassA, or ExistingClassB, but not ExistingClassC.
Since this seems not to be possible (from reading the comments), what approach would be the smartest to achieve the goal of just allowing myVar so be of a subset of CommonParentClass?
There's no compile-time mechanism to check whether a class extends either class A or B. If the authors of A and B did not define that they are related, they are not.
You have several options:
You could use instanceof and then cast to the specified type.
Object myObj = ...;
if (myObj instanceof Alpha) {
((Alpha) myObj).doSomething();
}
else if (myObj instanceof Bravo) {
((Bravo) myObj).doSomethingElse();
}
else {
throw new IllegalArgumentException("myObj" must be of either Alpha or Bravo");
}
Or you could make a wrapper object accepting either in the constructor:
class Either<A, B> {
A a;
B b;
boolean isA;
Either(A a) {
this.a = a;
this.isA = true;
}
Either(B b) {
this.b = b;
}
boolean isA() {
return isA;
}
A getA() {
return a;
}
B getB() {
return b;
}
}
and then call it:
Either<Alpha, Bravo> either = new Either(...);
if (either.isA()) {
either.getA().doSomething();
}
else {
either.getB().doSomethingElse();
}
But I fail to see how you want to use those two classes. Do they have a method with the same name? And why don't you just simply use two variables?
Related
I have a couple of classes 'X' and 'Y' that extend a common abstract class 'Base'. Almost all of the configuration is in Base. As the configuration can be complex and needs to be flexible I would like to write Builder classes for X and Y that have flowing interfaces.
It occurs to me that most of the setter methods in the builders will be identical - after all the common code is in the common base class. I should therefore probably write an abstract Builder for 'base'. This would look like:
abstract class Base {
abstract static class Builder {
private int a;
Builder setA(int a) {
this.a = a;
return this;
}
}
}
public class X extends Base {
static class Builder extends Base.Builder {
X build() {
// Do some stuff with the configuration
return new X();
}
}
}
Class 'Y' would look a lot like 'X'
the client could should read
X x = new X.Builder().setA(1234).build();
But this won't work because setA() returns a Base.Builder, which doesn't implement build
I don't particularly want to overload each method in the derived builders to return the correct type. That's a lot of boilerplate code and a maintenance headache.
Is there some trick I can use with Generics to tell the abstract builder what it's derived class is?
EDIT: Improved Version
The original answer (see below) did not support for the derived builder to add additional setters.
Yes, you can use Generics for this, but it needs a little twist. With the Type Parameter T extends Builder on the Base.Builder you allow derived Builders to specify that their type should be returned. The problem is, that this in the Base.Builder does not necessarily fulfill that requirement. So instead of using this to return in the setters, one has to pass/set the correct builder-instance to be returned using the method setBuilder. The derived Builder has to make sure to call super.setBuilder(this) at some point to make sure the Base.Builder is correctly initialized:
abstract class Base {
abstract static class Builder<T extends Builder> {
private int a;
private T builder;
protected void setBuilder(T builder) {
this.builder = builder;
}
T setA(int a) {
this.a = a;
return this.builder;
}
}
}
public class X extends Base {
static class Builder extends Base.Builder<Builder> {
public Builder() {
super.setBuilder(this);
}
X build() {
// Do some stuff with the configuration
return new X();
}
}
Builder builder() {
return new Builder();
}
}
Original Answer:
Yes, you can use Generics for this. Make the builder class take a Type parameter T extends Base, and add an abstract method T build() to it:
abstract class Base {
abstract static class Builder<T extends Base> {
private int a;
Builder<T> setA(int a) {
this.a = a;
return this;
}
abstract T build();
}
}
Now, extending classes can specify their type to the Builder and only have to overwrite the build method, and optionally provide additional setters:
public class X extends Base {
static class Builder extends Base.Builder<X> {
X build() {
// Do some stuff with the configuration
return new X();
}
}
}
I have a class A with a number of setter/getter methods, and want to implement a class B which "extends A" and provides other functionality.
I cannot modify class A, and it doesn't have a clone or constructor method that that takes a class A obj as a parameter. So basically I implement class B such that
it has a constructor that takes a class A obj as a parameter and keeps a copy of this obj
when we call setter/getter methods on B, it delegates to the class A obj
other functionality...
Class A has many setter/getter methods and I feel this implementation is not clean but not sure how to fix this. Usually I can make B extend A, but in this case I have to be able to take a class A obj as a parameter for the constructor.
I'm sorry if the question is not clear enough, please let me know if you need more clarifications. Thanks.
Example:
public class A {
private int x;
public void setX(int x) { this.x = x; }
public int getX() { return this.x; }
}
public class B {
private A a;
public B(A a) { this.a = a; }
public void setX(int x) { a.setX(x); }
public int getX() { return a.getX(); }
public void foo() { ... };
public void bar() { ... };
}
Basically A has a lots of properties X/Y/Z... and has many setters/getters. If I do this then B have many dummy setters/getters which simply delegate to the same call on a. Is there a cleaner way to implement this?
I think you're trying to extend an object of class A to add functionality to it and this is creating this dilemma. You can't copy A easily with a copy constructor and so you're trying to use composition rather than inheritance, and then that's not working.
Three options:
Do what you're doing - wrap the object of type A as something owned by B and delegate - it works and it's not too bad
Subclass A with B and then use some sort of reflection based copy routine to copy all properties from the object of type A into the new object of type B - e.g. http://commons.apache.org/proper/commons-beanutils/ copyProperties function
Create a copy constructor in class B that does what you want
Example
public class A {
private int x;
public void setX(int x) { this.x = x; }
public int getX() { return this.x; }
}
public class B {
public B(A a) {
// copy all A properties from the object that we're going to extend
this.setX(a.getX());
}
.. other stuff
}
The problem you're describing is one of extending an object. Extending a class is straightforward - just subclass it, and you have the base implementation plus your new stuff. To extend an object with the above code:
A someA = new A();
// a is initialised as an A
B aWithExtraProperties = new B(someA);
// now you have a B which has the same values as the original A plus
// b's properties
// and as B subclasses A, you can use it in place of the original A
I've tried changing an object's type at runtime like this before and it doesn't feel nice. It may be better to consider why you're doing this at all and whether there are alternatives.
If class B extends class A, it will automatically inherit all its non-private non-static methods. In your code, the getter/setters in class A are declared public, so class B will inherit them.
However, for this to work, you will need to rewrite class B's signature as follows, abd remove pretty much all code you wrote in B's body :
public class B extends A {
// here, put any functionalities that B provides in addition to those inherited from A
}
This way, you can access all the getter/setters through any reference of type A or B, like this :
public static void main(String... args) {
A a = new A();
a.setName("Bob");
System.out.println(a.getName());
B b = new B();
b.setName("Joe");
System.out.println(b.getName());
// And even this, thanks to polymorphism :
A ab = new B();
ab.setName("Mike");
System.out.println(ab.getName());
}
Suppose I've got two classes A and B such that B extends A, respectively implementing method getA and getB that has the same input parameter types and same return type (but different names). In a method public static <T extends A> void print(T t) getting as input an object of type A or B, I want to call getA if the object is of type A or getB if the object is of type B.
If I could edit the code of A and B I would make them implement an interface I providing getValue() (in the implementation for A and B, getValue() would call getA() and getB() resp.), and then call this method from print(). Problem is: classes A and B are not modifiable!. No methods can be added or changed, their class hierarchy is fixed, I didn't write their code, and I don't have access to the source.
Note that this also applies to the cases when - for any reason - I don't want to change the code of A and B.
Is there any way of doing so without the use of instanceof?
Here follows a solution that uses instanceof (bad!).
public class Test {
public static <T extends A> void print(T t){
if (t instanceof B)
System.out.println(((B)t).getB());
else if (t instanceof A)
System.out.println(t.getA());
}
public static class A {
public String getA(){
return "A";
}
}
public static class B extends A {
public String getB(){
return "B";
}
}
}
When you don't have access to the original code for whatever reason, you end up having to fall back on things like instanceof. In these cases, it's not bad per se - your hands are tied.
What I would do is to create a wrapper class that is genericized on your T, give it a getValue that tests with instanceof as you proposed, and make it clear that the only reason this class exists is to provide a consistent interface for using either an A or a B. It's still gross, but you've contained the grossness in one place.
To extend Matt's answer, I would consider adopting the Facade Pattern for these classes. This means you create a separate class (or two) to wrap all the functionality you require from these two classes. This includes adding a method, as Matt suggests.
The benefit is you decouple your application from an API you have no control over. You also have an opportunity to simplify the API, if you don't require all the methods from the original libraries.
Thank you and #Matt. Guess this one is definitely the cleanest way. Will provide the full code that does not make use of instanceof:
public static void main(String[] args){
A a = new A();
B b = new B();
AWrapper aw = new AWrapper(a);
BWrapper bw = new BWrapper(b);
print(aw);
print(bw);
}
public static void print(Wrapper t){
System.out.println(t.getValue());
}
public static class A {
public String getA(){
return "A";
}
}
public static class B extends A {
public String getB(){
return "B";
}
}
public static interface Wrapper{
public String getValue();
}
public static class AWrapper implements Wrapper{
A a;
public AWrapper (A a){
this.a = a;
}
public String getValue(){
return a.getA();
}
}
public static class BWrapper implements Wrapper{
B b;
public BWrapper (B b){
this.b = b;
}
public String getValue(){
return b.getB();
}
}
SITUATION: Say there is a class A and an interface B.
REQUIREMENT: If any class, say C, wants to create objects of A and use them, then that class will also have to implement interface B.Is there any way to enforce this condition?
WHY: Now a question may arise as to why I want to do such a thing. The reason is that when a class C creates objects of A and uses them, then those objects call certain methods of C. I want to declare those methods in interface B, so that C will invariably implement those methods.
Try this snippet:
public interface B {
// methods
}
public class A {
private final B b;
public A(B b) {
this.b = b;
}
...
}
public class C implements B{
// implement B's methods
public static void main(String[] arg) {
C c = new C();
A a = new A(c);
}
}
Since you say that objects of class A will call methods on C, they will have to keep reference to C somehow. Make this reference of type B and you are done.
That is
public class A {
public A(B arg) {
....
}
}
Then in C:
A a = new A(this);
That will force class C to implement interface B.
I can understand what inner class is and how to write program. My question is in what situation do programmers really need inner class?
Sometimes there is some functionality which is best represented as an object, but which is only meaningful within the context of another object, which does not necessarily need to be exposed to the outside world, and which can benefit from having access to the parent classes data (so as to not violate encapsulation).
The best example that I can think of is putting a Node class inside of a LinkedList. Nodes are only meaningful to the LinkedList, so they only exist within one. No one outside of the LinkedList cares about nodes or should have access to them.
An inner class allows us to remove that logic and place it into its own class. So from an object-oriented point of view, we've taken functionality out of where it doesn't belong and have put it into its own class.
Please go through this link....
http://www.javaworld.com/javaworld/javaqa/2000-03/02-qa-innerclass.html
Also as you know in Java exists nested classes, which is static inner clasess.
From previous posts becomes clear when we need to use an inner class but I think you also interested in the question "Why we need nested classes (static inner class)".
The answer is simply, there is the same purpose as for the inner class except few things.
1) The nested class (static inner) is required when we whant to exclude some logic that concerns another object but this logic might be used in outworld.
The simpliest examples is a builders or editors of some object. For example we have class Foo
which may have a lot of optional fields, to construct such object we may decide to introduce a builder class which will do this work.
public class Foo {
private int param1;
private int param2;
private int param3;
private Foo(FooBuilder builder) {
this.param1 = builder.param1;
this.param2 = builder.param2;
this.param3 = builder.param3;
}
public int getParam1() {
return param1;
}
public void setParam1(int param1) {
this.param1 = param1;
}
public int getParam2() {
return param2;
}
public void setParam2(int param2) {
this.param2 = param2;
}
public int getParam3() {
return param3;
}
public void setParam3(int param3) {
this.param3 = param3;
}
public static class FooBuilder {
private int param1;
private int param2;
private int param3;
public FooBuilder() {
}
public FooBuilder withParameter1(int param1) {
this.param1 = param1;
return this;
}
public FooBuilder withParameter2(int param2) {
this.param2 = param2;
return this;
}
public FooBuilder withParameter3(int param3) {
this.param3 = param3;
return this;
}
public Foo build() {
return new Foo(this);
}
}
}
This example illustrates at leas one reason why we need such classes
2) The second difference between inner and static inner classes is that the first one always has pointer to the parent class. Actully compiler creates synthetic field member for the non static inner class of the type of it's parent, exectly of this reason we can access private members of the parent class. The static inner clasess doesn't has such generated field member. For instance we has just simple parent class with declared non static inner class:
public class Foo {
public class FooBuilder {
}
}
but in fact if take into account the byte code it looks like:
public class Foo {
public class FooBuilder {
private Foo generatedNameHere;
}
}
if you want you can figure out this throught generated byte code.
One of the use of inner class is :
Inner class helps in multiple-inheritance. Inner class allows you to inherit from more than one non-interface.
//first case; can implement if two classes are interface
interface A { }
interface B { }
class X implements A, B { }
//second case; you can extend only one class. This case inner class can help to inherit other class as well
class D { }
abstract class E { }
class Z extends D {
void method() {
return new E() { }; //Anonymous inner class
}
}
When you want to specify a class that has sence only in context with the bounded one.
For example you write a MathOperations class that can execute four operations. So the operations can be represented as inner enum MathOps.
When the inner class is not used anywhere except the inbounded one.
You use anonymous inner classes to specify only the operation, for exmple if you want to sort a collection, you specify a Comparable class just for one method compare.
Collections.sort(employments, new Comparator<Employment>() {
#Override
public int compare(Employment o1, Employment o2) {
return o1.getStartDate().before(o2.getStartDate()) ? 1 : -1 ;
}
});
With inner classes you can access private members of the enclosing class.
They are useful for interface implementations that are only used by the enclosing class (event handlers in a application).
They are useful for providing fine grained access and creation control over an interface implementation that is retrieved externally (maybe something like an Iterator implementation).