Suppose I have a class Child extending Class Parent. The class Child has two nested classes nested1 and nested2. I want a abstract function to be defined in Parent with argument as nested1 and return type as nested 2. Right now , to achieve this , I have created a function with both argument and return type as Object.
So now , when I implement the child class , I am always required to cast the Object to nested1 and nested2. I feel there would be a better way to achieve this. Is there any better way to reduce the complexity?
Also attached the UML
The best way from a typing point of view is to make a interfaces within the parent class that specify the nested classes in the child. That way you won't need to cast the argument to func. This doesn't reduce the complexity per-se but it does make your intention a lot cleaner and reduces/eliminates the need for casting (always a good thing).
public abstract class Parent {
interface Interface1 {
//Specifications of methods that all child nested classes must have
}
interface Interface2 {
//Specifications of methods that all child nested classes must have
}
public abstract Interface2 func(Interface1 obj);
}
public class Child extends Parent {
private static class Impl1 implements Interface1 {
//Implementations of methods in Interface1 as they pertain to Child
}
private static class Impl2 implements Interface2 {
//Implementations of methods in Interface2 as they pertain to Child
}
#Override
public Interface2 func(Interface1 obj) {
//Should only have to use methods declared in Interface1
//Thus should have no need to cast obj.
//Will return an instance of Impl2
return null;
}
}
On a more broad scale, you should ask yourself why every child needs its own set of nested classes. This will get way simpler if you can move the nested class definitions to the parent (and make them static) and just have the child classes customize them as needed during construction.
Related
Say I have the following classes
public abstract class Parent {
public Parent() {
//stuff here
}
}
public class Child extends Parent {
public Child() {
//stuff here
}
public void doSomething() {
}
}
Then I get an object from an array of Parents
public Parent[] parents = new Parent[5];
Parent tempParent = parents[0]
If this object is of the child class, I want to cast the tempParent into the child class in order to use "doSomething" without having to create a new object
if(tempParent.getClass == Child.class) {
tempParent = (Child) tempParent;
tempParent.doSomething();
}
This, however, does not work. I still get an error telling me that doSomething is not a function in the Parent class. Is there a way to do what I'm trying to do?
You need to use the correct TYPE on the LEFT hand side:
Child someChild = (Child) tempParent;
Note: this does not create a new Object.
There is no way of having
Parent whatever = (Child) tempParent;
do what you want to do (invoke a Child class method)!
You see, the compiler only cares about the "defined" type of your reference, it does not take into account that you most likely, at runtime, just "put" something into that reference that in deed is a Child instance!
to do what you want to do.
And note: do not compare objects using ==. You should prefer to call equals() instead. For Class objects == should work (most of the time), but still: get used to check for equality using equals().
I think you're trying to solve the issue from the wrong side.
Technically speaking you should do it like this.
public abstract class Parent {
public Parent() {
//stuff here
}
public abstract void doSomething();
}
public class Child extends Parent {
public Child() {
//stuff here
}
#Override
public void doSomething() {
// Write the code of doSomething specific to child.
}
}
A bit off topic but you might want to consider the following:
I think that the class representation of your code is bad.
I think that you should have 2 concrete classes Parent and Child that are composed or either inherit from a common interface. Even better use composition over inheritance.
https://en.wikipedia.org/wiki/Composition_over_inheritance
if you are able to modify the parent class, I would recommend that you make doSomething an abstract method and have the child class override it. that way, there is no need to cast in order to invoke it.
https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html
I have children classes that use composition with classes that are also children. Instead of having a similar getter in each child class how can I move the getter of the composition class to the parent.
public class child1 extends Parent {
private CoolObjectTypeAAA coolObject;
//coolObject getter
}
public class child2 extends Parent {
private CoolObjectTypeBBB coolObject;
//coolObject getter
}
public class CoolObjectTypeAAA extends CoolObject {
}
public class CoolObjectTypeBBB extends CoolObject {
}
public abstract class Parent {
//would like to have a single CoolObject getter here in parent that returns the appropriate cool object of each child.
}
Is this possible or do I need to just have similar getter in each child class?
How about this:
abstract class Parent<T extends CoolObject> {
protected T mCoolObject;
public Parent(T coolObject) {
mCoolObject = coolObject;
}
public T getCoolObject() {
return mCoolObject;
}
}
class Child1 extends Parent<CoolObjectTypeAAA> {
public Child1(CoolObjectTypeAAA coolObject) {
super(coolObject);
}
public void demoType() {
// This type checks as the return type of getCoolObject() has been refined to CoolObjectTypeAAA
CoolObjectTypeAAA co = this.getCoolObject();
}
}
class Child2 extends Parent<CoolObjectTypeBBB> {
public Child2(CoolObjectTypeBBB coolObject) {
super(coolObject);
}
public void demoType() {
// This type checks as the return type of getCoolObject() has been refined to CoolObjectTypeBBB
CoolObjectTypeBBB co = this.getCoolObject();
}
}
abstract class CoolObject { }
class CoolObjectTypeAAA extends CoolObject { }
class CoolObjectTypeBBB extends CoolObject { }
Essentially you make the subclass specify whatever specific subtype of CoolObject it uses so that it can refine the return type of the getter, yet you get to implement the getter in the super class.
I would suggest taking a look at the abstract factory pattern as this seems to be what you are trying to accomplish. Properly implemented it involves multiple abstract classes and many subclasses but it is not as daunting as it seems.
What you are trying to do basically looks like a compact version of this but it is generally not a great approach as it leads to difficult to follow OO spaghetti code that jumps back and forth between the parent and subclass.
Remember, you've already defined Parent as abstract for a reason.
I suspect your goal is to maximise code reuse, normally when I see this kind of code it is because there is some common "CoolObject" init code that you don't want to duplicate in the child classes.
In that case, it is typically better to write a common "CoolObject" private or protected initializer in the parent but still construct the specific type of CoolObject in the child classes and then initialize it via the parent class method before returning it from the child.
In this case, since it is a getter, there may not be anything other than returning the private object. If that is the case then the best thing is to define a generic getter as abstract in Parent and then redefine in each child. The primary issue with this is that wherever you use this code you will need to continually typecast to the specific type of CoolObject you are expecting.
Because of this, it is likely that down the line, even if you provide either an abstract CoolObject getter or a concrete CoolObject getter in Parent, you will still end up wanting to have concrete implementations of getters for the specific CoolObject types.
The thing to keep in mind when designing something like this is how is it going to be used.
If the goal is to provide an abstraction over the various types of CoolObject then you are basically using a strategy pattern. In this case, being able to cast variables to the sub-type of CoolObject is not needed. In that case a non-specific type getter (abstract or concrete) is feasible.
Having the two specific child classes of Parent, however, it doesn't feel like this is what you are going for. Again I would suggest taking a look at the abstract factory pattern as this seems more like what you trying to do.
My abstract class has only three methods. My concrete class which extends the abstract class has price,name,packing. how can i access those properties using the reference variable of abstract class having instance of the concrete class. Directly i can't access any of the get set methods of the concrete class using this reference variable. Is there any special pattern for this problem????
According to my design, i have to assign the instance of the concrete class to the reference variable of the abstract class. I can't create the direct object of the concrete class.
With a reference to the abstract class alone, you can't do much.
However, you can type cast it to the corresponding concrete class.
eg: if you have class A and class B extends class A, you can do something like
if(obj instanceof B){
//type cast obj to class B here and call the respective method of B
((B)obj).concreteClassMethod();
}
Here obj is the reference variable of the abstract class A. This way, you can access any method (or public property) of class B, keeping the reference, however as class A.
Example:
First, you declare an abstract class, GraphicObject, to provide member variables and methods that are wholly shared by all subclasses, such as the current position and the moveTo method. GraphicObject also declares abstract methods for methods, such as draw or resize, that need to be implemented by all subclasses but must be implemented in different ways. The GraphicObject class can look something like this:
abstract class GraphicObject {
int x, y;
...
void moveTo(int newX, int newY) {
...
}
abstract void draw();
abstract void resize();
}
Each nonabstract subclass of GraphicObject, such as Circle and Rectangle, must provide implementations for the draw and resize methods:
class Circle extends GraphicObject {
void draw() {
...
}
void resize() {
...
}
}
class Rectangle extends GraphicObject {
void draw() {
...
}
void resize() {
...
}
}
than to acces to the father variable classes you can use: super.(variable)
only if the variable is public or protected.
If the variable is private, you will use get and set methods.
My abstract class has only three methods. My concrete class which extends the abstract class has price,name,packing.
I take it these abstract class methods are not the same as the three concrete class methods. Fine, I'll call these unnamed methods the mystery methods. If it turns out they are the same then just delete the mystery methods you'll see below.
how can i access those properties using the reference variable of abstract class having instance of the concrete class.
By injecting the dependency.
Directly i can't access any of the get set methods of the concrete class using this reference variable.
If they only exist on the concrete class this is no surprise. The only reason not to add them to the abstract class as #JBNizet suggests is if you don't want them exposed to client code. This is a reasonable concern but there is a better way to handle it.
Is there any special pattern for this problem????
Patterns are solutions not problems. What you say you're doing is structurally close to the http://en.wikipedia.org/wiki/Composite_pattern but you have the composition going in the wrong direction. I don't think the composite pattern is going to be what you want here.
According to my design, i have to assign the instance of the concrete class to the reference variable of the abstract class. I can't create the direct object of the concrete class.
There is a way to achieve this without using instanceof and more importantly without the Abstract class even knowing that the Concrete class exists.
public class Driver {
public static void main(String[] args) {
Composition compositionInstance = new Composition( new Concrete() );
System.out.println(compositionInstance);
}
}
public class Composition {
Abstract abstractInstance;
Composition(Abstract abstractInstance) {
if (abstractInstance == null) { throw new IllegalArgumentException("may not be null"); }
this.abstractInstance = abstractInstance;//concrete assigned to abstract ref var
}
public String toString() {
return String.format( "Price: %s, Name: %s, Packaging: %s",
abstractInstance.getPrice(),
abstractInstance.getName(),
abstractInstance.getPackaging() );
}
}
public abstract class Abstract {
void mysteryMethod1() {}
void mysteryMethod2() {}
void mysteryMethod3() {}
abstract String getPrice();
abstract String getName();
abstract String getPackaging();
}
public class Concrete extends Abstract {
String getPrice() {return "42";}
String getName() {return "My Concret Product";}
String getPackaging() {return "cardboard box";}
}
A lot of classes but they are very simple. These class names are terrible so don't imitate them.
Driver doesn't have to touch the getters since it can let Composition do that for it. It only knows how to build Composition and Concrete. It doesn't get chatty with them.
Composition only has to know how to talk to Abstract. It has no idea how to build one or exactly what concrete instance it might get.
Abstract only knows about it self. Doesn't know anyone else. It doesn't want to know.
Concrete only knows about abstract.
By writing the code this way it is kept flexible. It should be easy to make changes as requirements change.
This wasn't written following any set pattern. What it follows are the S.O.L.I.D. principles.
I have a superclass, let's say BaseClass and two subclasses, let's say SubclassA and SubclassB, they don't have any other relationship between them but their parent class.
At a lot of places in my code I need to call to methods that both the subclasses have but not the parentclass... And I find myself repeating a lot of code which looks like:
if (obj instanceof SubclassA) {
// stuff
} else if (obj instanceof SubclassB) {
// same stuff
}
The first idea should be to put that "stuff" into a method in superclass, but I can't as that superclass is parent to other subclasses that don't have that behavior...
So... is there a way to avoid repeating aaaalll of that code?
Maybe a common superclass for both subclasses that is a subclass itself of superclass?
I would suggest extracting the method as an abstract method in the parent(if the parent is abstract), or just a method that will be overridden in child classes. If this is not possible, or desirable I would suggest adding a common abstract class that extends the parent that has just the method that is common to both subclasses, that will be then extended by the two subclasses.
If adding and changing the parent class might be an issue, you can do the same thing by using an interface that is then implemented by both subclasses and where you need to call your code you will just cast to the given interface and call the needed method.
Something like this:
interface CommonInterface {
void commonMethod();
}
class SubClassB implements CommonInterface {
void commonMethod() {
// implementation
}
}
class SubClassA implements CommonInterface {
void commonMethod() {
// implementation
}
}
//...
if (obj instanceof CommonInterface) {
((CommonInterface)object).stuffCall();
}
Add the method to the super class.
Make it with an empty body.
In SubClassA override it, implement the logic you need.
In SubClassB override it, implement the logic you need.
Then in your calling code, instead of doing
if (obj instanceof SubclassA) {
obj.method();
} else if (obj instanceof SubclassB) {
obj.method();
}
just do this
obj.method();
provided obj is declared as an instance of the parent class.
The empty method body in the super class guarantees you have
no issues with this "but I can't as that super class is parent
to other subclasses that don't have that behavior".
So the idea is that you will have empty behavior
in the super class and in all the sub classes which
do not explicitly override this method.
Firstly, the concept of polymorphism is to do away with the need to check the type of an object before calling methods on it. So, this should not be necessary in an OO-language.
Secondly, the reason why you might use an abstract parent class over an interface would but because there is some shared functionality between sub-types (subclasses). So, if there is shared, common functionality between SubclassA and SubclassB then leave your superclass intact, otherwise switch it to an interface.
Likewise, and as you suggest yourself, if SubclassA and SubclassB have a common behaviour (but their own implementation) then utilise a separate API (if other sub-types of BaseClass do not also share that behaviour (your #doStuff call).
In this case, I'd introduce interface Stuff containing method #doStuff and have both my SubclassA and SubclassB implement it, each providing it's own implementation. Your clients can then treat your obj instance as a Stuff, irrespective of it's real type and polymorphism will do the rest.
interface Stuff {
void doStuff();
}
public class SubclassA extends BaseClass implements Stuff {
// Does it need BaseClass still?
public doStuff() {
...
}
}
public class SubclassB extends BaseClass implements Stuff {
// Does it need BaseClass still?
public doStuff() {
...
}
}
// Example client code...
public class MyStuffClient {
Stuff s = new SubclassA();
...
public void onStuff() {
s.doStuff();
}
}
Decide if you really need the suer class BaseClass.
What about the following two ways:
Declare the target method in super class and provide a default implementation(e.g. empty method, do nothing) as well. Subclass will override that behavior if needed.
Declare the target method in a Interface, and make SubclassA and SubclassB implementation of the interface. The super class and other subclasses don't need to implement the interface.
If SubClassA and SubClassB have some behaviour that isnt present in Subclass C, D, E etc then just introduce an intermediate class between the parent and A and B. C, D etc derive from the parent, And B derive from the new class, which contains functionality that A and B share.
You can make the method on the superclass protected. For example, you can do this on SuperClass:
package test;
public SuperClass {
protected void myMethod() {
...stuff...
}
}
exposing on SubclassA
package test;
public SubclassA extends SuperClass {
public void myMethod() {
super.myMethod();
}
}
and hiding on SubclassB (just not override it)
package test;
public SubclassB extends SuperClass {
}
From a different package, protected methods are not visible unless the class override it changing its visibility modifier.
Source: http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html
here's the code (simplified):
public abstract class PageBase implements Serializable {
private static final long serialVersionUID = -31905358958878336L;
}
public abstract class ListPage extends PageBase {
public Controller getController() {
// Controller is a class
// that implements Serializable and does have an def. constr.
return new Controller() {
#Override
public void someMethod() {
// DoSomething
}
};
}
}
public class ProjectList extends ListPage {
}
and through deserialization it throws:
java.io.InvalidClassException: my.pkg.page.ListPage$1; no valid constructor
The deserialization is taking place somewhere in the IBM JSF-Code.
Any ideas? Thanks!
my.pkg.page.ListPage$1 will be an anonymous inner classes. Serialisaing nested classes isn't a good idea at the best of times (poor mapping to full JVM name and handling of "outer this" references).
The exception looks as if it is trying to find the no-arg constructor of the most derived non-Serializable base class, which must be accessible to the least derived Serializable class.
I'd suggest defining the anonymous Controller as a separate class.
I think that the problem is that subclass of Controller is a non-static inner class, and as such its constructor has an implicit argument that refers to the instance of the enclosing class. This makes the constructor unusable for object deserialization.
It is a bad idea to try to serialize these objects, but if you change the inner class so that it is static deserialization may work.
You are trying to serialize an abstract class which, by definition, cannot be instantiated.
That is, with your definition of ListPage, you cannot do:
ListPage l = new ListPage();
Remove the abstract qualifier from ListPage and ProjectList, and everything will be ok.
One serializes objects, not classes, no? All of the classes you've shown are abstract, so can't be instantiatiated, so what is it that you're (de)serializing?
The error references the class as "ListPage$1" -- an anonymous inner class. I think we'd need to see more of the code to understand what's going on.