This is really a general Java question but I figured it would be easier to explain with the specific Webdriver perspective from which it arose.
I have a complicated page object that I now want to make abstract, because I found another page that is very similar but different in key ways. Now many of my methods, which had returned instances of the page object, are broken. I want to keep the bulk of the code for these methods in the abstract class and still have them return instances of the new subclasses; these methods should return new instances of whatever subclass called them.
Here is an example with a navNextPage method which is common to both of the subclasses. This seems to work, but it feels wrong:
public abstract class PresContentPage {
protected PresContentPage navNextPage() {
// code to navigate to the next page goes here
return null;
}
}
public class MainContent extends PresContentPage {
public MainContent navNextPage() {
super.navNextPage();
return new MainContent(...);
}
}
// And so on with another subclass...
So, this does what I want: the code for the navNextPage method is siloed in the abstract class, but the version that gets called will return the page object of the type that invoked the method.
I just feel wrong having my protected method, which is not and cannot be void, return null. But since it's protected, and it's an abstract class, no one will ever be able to call it anyway, right? Does that make it okay? Is there a way better way to do this that I just never learned?
Another option I thought of is to just make a void method with a different name like navNextPageVoid and have the subclasses call that instead of super.navNextPage, but... that seems sort of gross in a different way.
Thanks in advance!
Typically if you want to force a method to be implemented in a specialisation you make it abstract in the generalisation. Therefore
public abstract class PresContentPage {
abstract PresContentPage navNextPage(); }
Related
I need to add one optional method in existing abstract class that is extended by more than 50 classes:
public abstract class Animal{...}
This method is not used by all those classes, but in the future it probably will.
The structure of one of my classes is:
public class Dog extends Animal {...}
The cleanest way is using abstract method but it obliges me to change all existing classes.
The workaround is to create "empty" method in abstract class:
public String getString(Map<String, Object> params){
return "";
}
and then override it when I need in classes that extend abstract class.
Is there any better solution?
Having an "empty" method is fine. But in order to be sure, that it will be implemented where it is really needed, consider throwing an exception by default from this method:
throw new UnsupportedOperationException();
A similar approach is used in java.util.AbstractList class:
public E set(int index, E element) {
throw new UnsupportedOperationException();
}
I can't help feeling like you have some architectural/design issues here, but without knowing more, I can't say for sure. If 50 classes are going to inherit from Animal, but not all of them are going to use this method, then I'm wondering if they should really inherit from one common class. Perhaps you need further levels of sub-classing... think Kingdom->Phylum->Sub-Phylum. But my gut says that's still not the right answer for you.
Step back - what are you trying to accomplish? If you're going to implement this function on these classes in the future, then you must also be changing your code to know to use/expect this. The point of inheritance is to allow code to refer to an object's expected common behavior without knowing what type of object it's referencing. In your getString() example, you might have a function as such:
public string SendMessage(Animal someAnimal) {
string message = someAnimal.getString();
// Send the message
}
You can pass it a dog, a cat, a platypus - whatever. The function doesn't care, because it can query the message from its base class.
So when you say you'll have animals that don't implement this message... that implies you'll have logic that ensures only cats and dogs will call this function, and that a platypus is handled differently (or not at all). That kind of defeats the point of inheritance.
A more modern approach would be to use interfaces to establish a "has a" relationship instead of an "is a" relationship. A plane might have an IEngine member, but the specific type of engine can be set at run-time, either by the plane class itself, or by the app if the member is writeable.
public interface IEngine {
string getStatus();
string getMileage();
}
public class Cessna {
public IEngine _engine;
public Cessna() {
_engine = new PropellerEngine();
}
}
You could also inherit directly from that interface... Animals that don't implement IAnimalMessage wouldn't implement that function. Animals that do would be required to. The downside is that each animal will have to have its own implementation, but since your base class currently has an abstract function with no body, I'm assuming that's a non-issue. With this approach, you can determine if the object implements the interface as such:
IAnimalMessage animalMessage = myPlatypus as IAnimalMessage;
// If your playtpus doesn't implement IAnimalMessage,
// animalMessage will be null.
if (null != animalMessage) {
string message = animalMessage.getString();
}
public interface IAnimalMessage {
string getMessage();
}
public class Platypus : IAnimalMessage {
// Add this implementation when Platypus implements IAnimalMessage...
// Not needed before then
public string getMessage() {
return "I'm a cowboy, howdy, howdy, howdy!";
}
}
That's probably the closest to what you're asking for I can suggest... classes that don't need the message won't implement that interface until they do, but the code can easily check if the interface is implemented and act accordingly.
I can offer more helpful/specific thoughts, but I'd need to understand the problem you're trying to solve better.
I'm attempting to extend a class in order to polymorphically run its functions as privileged. I want to avoid modifying the base class, Fooer in the example, and I definitely want to avoid reflection. I've been working mainly with javascript and python lately so my mind keeps repeating, "Use a function pointer" but since functions are not first class objects in java that is not an option. This seems like a valid goal so I'm assuming someone know a good design pattern for this that I'm missing.
public class SecureFooer extends Fooer()
{
#Override
public Object foo()
{
PrivilegedAction<Object> action = new PrivilegedAction<Object>() {
#Override
public Object run() {
// This isn't going to work, i'm inside PrivilegedAction
return super.foo()
}
};
return AccessController.doPrivileged(action);
}
}
The syntax is
return SecureFooer.super.foo();
This works because the PrivilegedAction anonymous class is an inner class of SecureFooer and all inner classes have access to their enclosing instance, and to that instance's super implementation.
public class Parent{
private Object oBase;
public Object getObject(){
// [some logic]
return oBase;
}
public String getObjectValue(){
return getObject().getValue();
}
public class Child extends Parent {
private Object oChild;
public Object getObject(){
return oChild;
}
public Object getObjectValue(){
return getObject().getValue();
}
public String getParentObjectValue(){
return super.getObjectValue();
}
}
In the above template, I need a way to make sure that the getObject() in Parent.getObjectValue() calls Parent.getObject() and not Child.getObject(), so that the child class can have getters to oBase and oChild.
I've tried using ((Parent)this).getObject().getValue() in Parent.getObjectValue(), but it still polymorphs to the child definition. Is there way to force static binding in java for a specific call?
I'm trying to avoid duplicating the [some logic] from Parent.getObject() in Parent.getObjectValue(), but I guess I'll have to if there's really no way around it.
You can either make the getObject() method private, or change the method name so that polymorphism will not kick on. Overall, you'll have to rethink your design.
Other options are to extract the [some logic] to a third method and invoke this from both getObject() and getObjectValue(). Please keep in mind the Command Query separation principle when you use this design.
You could just refer to the private field 'oBase' directly, instead of using the 'getObject()' method.
You can't force a call to the Parent's method from outside the child class, due to polymorphism. Indeed, for a Child object, the parent method does not exist anymore, because it has been overriden.
You don't seem to need any aspect of polymorphism here (though it's hard to tell without more information). If, indeed, you do not need it (different use cases), then change your methods' names so that it does not happen.
Note: If you're in the child class, then you can use super, but I don't think this is your case.
I have a variable: Abstract a. It is a class that extends the Abstract class. However, I need to cast this Abstract variable into a more specific class variable that extends the Abstract class.
My situation: I have two classes, Class1 and Class2 that both extend the Abstract class with methods implemented in each one. I now have an Abstract class variable to work with. I do not know if it is Class1 or Class2, so I cannot simply do a (Class1) a or a (Class2) a (casting).
So how would I successfully cast this variable so that I can use the inner methods?
I was thinking along the lines of using a.getClass().getName() to determine how to cast it, but I am stuck from here on out.
Your new question appears to be asking how to dynamically cast a variable to an arbitrary type unknown at runtime. This is probably a duplicate of java: how can i do dynamic casting of a variable from one type to another? but to summarize, this is not (easily) possible, isn't recommended, and speaks to other issues in your code.
Think about it this way, what variable would you possibly be able to use to store your newly cast object? Imagine if we had a (child) cast operation in Java, that took a variable defined as a parent class, and cast it down to its child (e.g. List -> LinkedList):
public static void func(Abstract a){
???? var = (child)a;
// Do something with var?
}
Notice that 1) there's no way you could ever specify a type for var, since we don't know at runtime what type it will be; and 2) there's nothing we'd be able to do with var beyond the behavior defined in Abstract anyways, because the compiler can't predict which methods will be availible to var other than what's available to Abstract.
If you need to implement class-specific behavior, you should do so inside the class. Have an abstract method which each class has to implement, and which can do whatever you need them to do. Or, if you cannot ensure that, don't define a function that takes an Abstract as an argument; instead define however many functions that take Class1, Class2, etc. objects as parameters, like so:
Abstract method to require all child classes behave similarly
public abstract class Abstract{
/** Do the class-specific behavior you want to do currently in func */
public abstract void operation();
public static void func(Abstract a){
a.operation();
}
}
Functions only for classes that can actually handle what you want
public static void func(Class1 a){
// do something
}
public static void func(Class2 a){
// do something
}
Again, if neither of these options are viable for you (and of course, blocks of instanceof calls aren't acceptable) then I'd be willing to bet money there's something structural in the way you're using Java that's fundamentally incorrect. If you want to post a code sample of exactly what you're trying to accomplish by child-casting, perhaps we can shed some light as to what the issue is.
Leaving this here for posterity - OP's original question asked about creating new instances of an object cast as its abstract parent.
Pretty straightforward, get the object's class object, and create a new instance. For more complex constructors, see the Java documentation on creating new instances dynamically.
public class ClassVar
{
public static abstract class Abstract
{
}
public static class Class1 extends Abstract
{
}
public static class Class2 extends Abstract
{
}
/**
* Given an instance of a child of Abstract, returns a new instance
* of the same class
*/
public static Abstract newInstance(Abstract obj) throws InstantiationException, IllegalAccessException
{
return obj.getClass().newInstance();
}
public static void main(String[] args) throws InstantiationException, IllegalAccessException
{
System.out.println(newInstance(new Class1()).getClass());
System.out.println(newInstance(new Class2()).getClass());
}
}
Result:
class ClassVar$Class1
class ClassVar$Class2
Basically you can use reflection by using
Class cl = ...
cl.newInstance()
The more 'expanded' answer you can find here
Since you edited your question again 3h ago at the time of writing here's my second answer to a problem I thought was solved. It's obvious nobody got what you're really asking for in the first place. Try to improve how you're asking questions.
However, the answer is simple:
From the point of view of object orientation you simply shouldn't have to (Liskov Substitution principle). Even if you have exact knowledge about exactly two possible instances, you should look for a better approach for the problem you are trying to model.
If you have to, determine the class name and check for equality or carry an extra identifier and compare that one. Implementation couldn't be simpler.
I have a big method doComplicateCalculation in abstract class - AbstractClass.
Also have small class Descendant that extends AbstractClass.
I need to introduce in method doComplicateCalculation small changes like:
..............
if (val<0){
continue;
}
..................
The problem also more difficulta that big method in internal class of abstract class.
How it can be done?
Thanks.
This might not be the best answer; but it is the best answer I can give with the information provided. If anything it will get you thinking in the about ways you can address this (because if you're going to be programming for a while, then it won't be the last time you run into problems like this).
In your abstract class, put this:
if (doContinue(val)){
continue;
}
Then, define the method in your abstract class...
protected boolean doContinue(int val) {
// Or, put return true if you always want it to do this
return false;
}
Then, override this method in your concrete class, like this...
protected boolean doContinue(int val) {
return val < 0;
}
You need to break the big method in pieces, so that you can override the part you need.
That is a difficult question to try to answer generically. One thing that you could do is to try to break up the algorithm in doComplicateCalculation as much as possible. To add the validation maybe make each class extending doComplicateCalculation implement a public boolean
validate
You could even do this before or at different times throughout the algorithm. If that isn't possible you could also just override this method (or override some part of the method if you could break it up).