Pass Class object to a method - java

I am trying to pass a Class to a method. The Class changes as the program runs, so I'd like to reuse the same method through out my program instead of calling the same functions throughout my resetWords() method.
Here is where I am stuck:
private void getWords(Class c) {
singles = c.getSingleSyllables();
doubles = c.getDoubleSyllables();
triples = c.getTripleSyllables();
quadruples = c.getQuadrupleSyllables();
quintuples = c.getQuintupleSyllables();
}
private void resetWords() {
if (generated.equals("SOMETHING")) {
Something c = new Something();
getWords(c);
}
else if (generated.equals("ANOTHER")) {
Another c = new Another();
getWords(c);
}
}

I think what you are looking for is an interface. You should declare an interface like this:
public interface Passable
{
public List<String> getSingleSyllables();
public List<String> getDoubleSyllables();
// ...
}
Then, let Something and Another implement them:
public class Something implements Passable
{
// method declarations
}
Now, change your method to this:
private void getWords (Passable c) {
singles = c.getSingleSyllables();
doubles = c.getDoubleSyllables();
triples = c.getTripleSyllables();
quadruples = c.getQuadrupleSyllables();
quintuples = c.getQuintupleSyllables();
}

A little vague what you're asking but perhaps create an Interface that defines all of the getXSyllables() methods. Have your classes (Something and Another) implement that Interface. Finally, define getWords as private void getWords(YourInterface c).

You're confusing classes, and objects.
What you're passing to getWords() is an object. In the first case, it's an object of type Something. In the second case, it's an object of type Another.
The only way for such code to work is to define a common base class or interface for Something and Another (let's call it HavingSyllabes), containing the 5 methods used in getWords(): getSingleSyllables(), getDoubleSyllabes(), etc. And the signature of getWords() should be
private void getWords(HavingSyllabes c)

If the classes always implement getSingleSyllables(), getDoubleSyllables(), etc.. then you should consider inheriting from an abstract class, or implementing an interface.
Then...
private void getWords(YourInterface / YourAbstractClass foo) {
...
}

Your question does not provide enough detail to answer clearly.
Depending upon your design / end-goals, there are three concepts you should take a look at and understand:
Interfaces
Abstract Classes
Reflection
An Interface will define the methods that classes that implement the interface must provide. Each class that implements the interface must provide the code for the method.
An Abstract Class will provide a single implementation of the behavior that you are looking for.
Reflection is an advanced concept. I would recommend you stay away from it at this time - but you should be aware of it.
Given your example code, you may want to use an Abstract Class. Designed properly, you can increase flexibility/reuse by defining an interface, implementing that interface with an Abstract Class and then extending that Abstract Class as needed. Every class that extends the Abstract will pick up the default implementation you provided in the Abstract class definition; the Interface will make it easy for you to extend in the future.

Related

extract common methods from interfaces

I have the following problem. There's an interface called e.g UserExpactations with a bunch of methods in a builder-style to verify some logic.
Looks like this:
interface UserExpectations {
UserExpectations expectSuccessResponseFromApi;
UserExpectations expectFailResponseFromApi;
UserExpectations expectUserInDB;
// more user-specific methods
}
As you can each method return UserExpactations so we can chain them together.
Now I need to add one more expectator class and there's some common logic, namely the first two methods.
So it's going to look like this:
interface OrderExpectations {
// these are common to UserExpectations
OrderExpectations expectSuccessResponseFromApi;
OrderExpectations expectFailResponseFromApi;
OrderExpectations expectOrderInCart;
OrderExpectations expectOrderInDB;
// some more order specific methods
}
I want to extract these common methods to abstract class or maybe another top level interface. And these methods should be implemented in one place. And each expectators should be aware of their implementation. But the problem is that each common methods should return a specific *Expactations type in order to keep that ability to chain methods.
Can't find a way how to implement this. Maybe is there a nice pattern which can help to facilitate this problem that I'm not aware of.
Any ideas?
UPDATED:
So I wanted to create an abstract Expecations which will contain common methods:
Like this:
abstract class CommonExpactations<T> {
T expectSuccessResponseFromApi() {
// do some logic and then return T
}
T expectFailResponseFromApi() {
// do some logic and return T
}
}
And not each implementation of *Expectations specific interface should also extend CommonExpactations in order to get access to the common methods.
But java doesn't allow to create a new object of type T in abstract class in order to chain some other methods in concrete implementations.
So for example,
UserExpectationsImpl implements UserExpectations extends CommonExpactations<UserExpectations>
How about with generics?
public interface Expecations<T> {
T expectSuccessResponseFromApi();
T expectFailResponseFromApi();
....
}
public interface UserExcpectations extends Expecations<User> {
}
Try with anonymous object creation of abstract class.
abstract class CommonExpactations<T> {
T expectSuccessResponseFromApi() {
// do some logic and then return T
}
T expectFailResponseFromApi() {
// do some logic and return T
}
}
In Child interfaces of CommonExpectations, say UserExpectations
CommonExpectations ce = new CommonExpectations<UserExpectations>(){
//provide abstract method implementations
}

Inheritance type issue: is there a clean solution?

I have an abstract class inherited by two concrete classes.
public abstract class AbstractClass {
public abstract void operation1();
}
public class ConcreteClassA extends AbstractClass {
#Override
public void operation1() {
// Do work
}
public void operation2() {
// Do some other work
}
}
public class ConcreteClassB extends AbstractClass {
#Override
public void operation1() {
// Do work
}
}
Now, to take advantage of dynamic binding I create two objects while programming to the interface.
private AbstractClass classA = new ConcreteClassA();
private AbstractClass classB = new ConcreteClassB();
But this does not allow me to call method operation2() on classA. I can fix this by using a downcast.
((ConcreteClassA) classA).operation2();
But downcasts are considered ugly in OOP especially when you have to use them a lot. Alternatively, I can give up programming to the interface.
private ConcreteClassA classA = new ConcreteClassA();
But then I lose the dynamic binding. Another option is to move operation2() to the AbstractClass so that I can restore the dynamic binding.
public abstract class AbstractClass {
public abstract void operation1();
public abstract void operation2();
}
But then ConcreteClassB needs to override operation2() leaving the implementation empty since this class does not need this method.
Lastly, I could move operation2() to the AbstractClass and provide a default implementation which may be overridden or not.
public abstract class AbstractClass {
public abstract void operation1();
public void operation2() {
// Some default implementation
}
}
But this gives classB access to operation2() which I would rather avoid.
There does not seem to be a clean solution to call subclass specific methods while maintaining dynamic binding at the same time. Or is there?
There are at least a few ways to deal with this circumstance and, really, the right one depends on your particular requirements.
Ask yourself, "are both operation1 and operation2 part of the contract specified by my type?"
If the answer is clearly no, then you should not pollute the contract of your type by adding collateral methods to it. You should next ask yourself, "why am I not using interfaces to specify separate types, eg.: instead of AbstractClass, why am I not using MyInterface1 and MyInterface2 (each with its own separate contract)? Interfaces provide a limited form of multiple inheritance, and your implementing classes can implement any and all interfaces that pertain to it. This is a strategy commonly used by the Java Platform Libraries. In this circumstance, explicit casting to the type whose contract you want to use is exactly the right thing to do.
If the answer is clearly yes, then you should have both methods in your type ... but you should still ask yourself, "why am I not specifying my type with an interface"? In general, you should specify types with interfaces rather than abstract classes, but there are reasons to use the latter.
If the answer is somewhere in between, then you can consider specifying optional methods in your type. These are methods which are included in the contract of your type, but which implementing classes are not required to implement. Before Java 8, each implementing type would need to throw a UnsupportedOperationException for any optional methods that it did not implement. In Java 8, you can do something like this for optional methods:
======
public interface MyType {
void contractOperation1();
default void optionalOperation2() {
throw new UnsupportedOperationException();
}
}
A class that implements this interface will need to provide an implementation for contractOperation1(). However, the class will not need to provide an implementation for optionalOperation2() and if this method is invoked on an implementing class that has provided no implementation of its own, then the exception is thrown by default.
abstract class don't have the object,we just create the reference of that class and use it.
like:
instead of this-
private AbstractClass classA = new ConcreteClassA();
private AbstractClass classB = new ConcreteClassB();
use this one
private AbstractClass classA;
private AbstractClass classB;
If we will create an object of the abstract class and calls the method having no body(as the method is pure virtual) it will give an error. That is why we cant create object of abstract class. Here is a similar StackOverflow question. In short, it is legal to have a public constructor on an abstract class.
more details are here:about abstraction instance

Most concise and efficient way to share common handling code for a per-class object?

I have a series of classes, A,B,C... (several dozen in total) that share common code. There can be many instance of each class A,B,C... . I'm planning to create a superclass, Abstract, that will contain that code instead.
Problem is, the common stuff works on an object that is unique on a per-class (not per-instance) basis. This is currently solved by A,B,C... each having a static field with the corresponding value. Obviously, when I refactor the functionality into Abstract, this needs to be changed into something else.
In practice, it currently looks like this (note that the actual type is not String, this is just for demonstrative purposes) :
public class A implements CommonInterface {
private static final String specificVar = "A";
#Override
public void common() {
specificVar.contains('');
}
}
public class B implements CommonInterface {
private static final String specificVar = "B";
#Override
public void common() {
specificVar.contains('');
}
}
The best idea I've come up with until now is to have a Map<Class<? extends Abstract>,K> (where K is the relevant type) static field in Abstract, and A,B,C... each containing a static initalization block that places the relevant value into the map. However, I'm not convinced this is the best that can be done.
Note that I'm not using any DI framework.
So, what would be the most concise, in terms of code contained in the subclasses, way to refactor the static fields in A,B,C... handled by the common code, without sacrificing field access efficiency?
Perhaps an enum is what you want.
enum MyInstances implements MyInterface {
A {
fields and methods for A
}, B {
fields and methods for B
};
common fields for all MyInstances
common methods for all MyInstances
}
// To lookup an instance
MyInstances mi = MyInstances.valueOf("A");
As you haven't shown any source code, we can't really tell if the use of static fields is a good or a bad design choice.
Considering the use of static fields by the subclasses is indeed a good design choice, the first way of having common code in a superclass to access them is by calling abstract methods that would be implemented in the subclasses.
Example:
public abstract class SuperClass {
public void processCommonLogic() {
// Common logic
// Execute specific logic in subclasses
processSpecificLogic();
}
public abstract void processCommonLogic();
}
public class ASubClass extends SuperClass {
public static int SPECIFIC_SUBCLASS_CONSTANT = 0;
public void processSpecificLogic() {
// Specific subclass logic
doSomethingWith(ASubClass.SPECIFIC_SUBCLASS_CONSTANT);
}
}
You could use the Template Method Pattern.
Have an abstract method getValue() defined in your abstract class and used within your abstract class wherever you require the value. Then each of your subclasses simply need to implement the getValue method and return the correct value for that subclass.

What is the point of an abstract class?

I understand what an abstract class is in OOP paradigm. Yeah an abstract class is an incomplete type, cannot be instantiated.
Subclasses of the abstract class can extend the superclass and so on, and call a method through using a base type variable. But that is what I don't get.
I was reading the book, and the author said using a Superclass variable to reference a subclass and calling a common method calls the correct method. And yeah that's true. For example this little code I wrote:
public class ObjectOne extends SuperObject {
public String objectString()
{
return "objectString() of class ObjectOne\n" ;
}
}
public class ObjectTwo extends SuperObject {
public String objectString()
{
return "objectString() of class ObjectTwo\n" ;
}
}
public class ObjectThree extends SuperObject {
public String objectString()
{
return "objectString() of class ObjectThree\n" ;
}
}
public class SuperObject {
public String objectString()
{
return "SuperObject" ;
}
}
import static java.lang.System.out ;
public class ControlClass {
public static void main(String[] args)
{
SuperObject [] arr = {new ObjectOne(), new ObjectTwo(), new ObjectThree()} ;
for(SuperObject elem:arr)
{
out.println(elem.objectString()) ;
}
}
}
Em, so when main executes the correct methods are called for the objects using just the reference type. My question is so what is the point of an abstract class? Polymorphism works regardless of whether the method or class is abstract.
Unlike C++, polymorphism works only when you specify it. For Java, it works apparently all the time.
So I guess the abstract keyword or abstract concept is just to complete the inheritance hierarchy, make incomplete types impossible to instantiate, or is to promote good OOP practice? Can someone clarify thanks.
I'm not sure you understand what an abstract class is, as none of the classes in your example are abstract, and nothing in there is an interface either. What you are doing is extending an instantiable class. Without the abstract keyword there is nothing to stop me doing:
SuperObject obj = new SuperObject();
I think a better example would be to illustrate how abstract classes are used. What they are commonly used to do is to provide a common method implementation. If a number of classes implement some interface, but all of them implement the same method in the same way using the same code, then what is commonly done is to create an abstract class that contains the common implementation, and get all of the concrete implementations to extend that class. This facilitates code reuse, and decreases the likelihood that one developer will change the common method implementation for one class, but forget the others. For example..
public class ObjectOne extends Thing {
public String objectString()
{
return "objectString() of class ObjectOne\n" ;
}
}
public class ObjectTwo extends Thing {
public String objectString()
{
return "objectString() of class ObjectTwo\n" ;
}
}
public class ObjectThree extends Thing {
public String objectString()
{
return "objectString() of class ObjectThree\n" ;
}
}
public abstract class Thing implements SuperObject {
public String alwaysTheSame() {
return "The same thing";
}
}
public interface SuperObject {
public String objectString();
public String alwaysTheSame();
}
import static java.lang.System.out ;
public class ControlClass {
public static void main(String[] args)
{
SuperObject [] arr = {new ObjectOne(), new ObjectTwo(), new ObjectThree()} ;
for(SuperObject elem : arr)
{
out.println(elem.alwaysTheSame());
out.println(elem.objectString()) ;
}
}
}
What we have done here is introduce an abstract class Thing, which provides a method implementation that is common to all 3 implementations of SuperObject (which is now an interface). This means we don't have to write the same code again in three different places in order to to fully implement the SuperObject interface in each one of our concrete classes.
In addition to this, you can also extend non final classes. You may wish to do this in order to override the default behaviour of one or methods on the concrete class, or to decorate the the class with additional methods. Of course, when you are designing a class hierarchy from scratch you don't stick concrete classes in it that then get extended by other classes, as it's generally considered a bad code smell. However, few of us work with totally new written-from-scratch codebases, and must adapt an exiting codebase to new requirements. Extending a concrete class is one tool in the toolbox to do this.
EDIT: Misunderstood what the OP was asking, but the last paragraph above is relevant.
Let's say you want to deploy an application on an Ipad, Android, Iphone and Desktop application.
You work on an important part that will do 95% of the job in an abstract class. Then you create 4 other small classes that will implement the abstract method differently for each device.
That way, you won't repeat 95% of the work, and each device will instanciate his own class, that extends the abstract common class.
Abstract classes are an excellent way to create planned inheritance hierarchies. They're also a good choice for nonleaf classes in class hierarchies.
Here's a good detailed explanation: (extracted from here)
Choosing interfaces and abstract classes is not an either/or proposition. If you need to change your design, make it an interface. However, you may have abstract classes that provide some default behavior. Abstract classes are excellent candidates inside of application frameworks.
Abstract classes let you define some behaviors; they force your subclasses to provide others. For example, if you have an application framework, an abstract class may provide default services such as event and message handling. Those services allow your application to plug in to your application framework. However, there is some application-specific functionality that only your application can perform. Such functionality might include startup and shutdown tasks, which are often application-dependent. So instead of trying to define that behavior itself, the abstract base class can declare abstract shutdown and startup methods. The base class knows that it needs those methods, but an abstract class lets your class admit that it doesn't know how to perform those actions; it only knows that it must initiate the actions. When it is time to start up, the abstract class can call the startup method. When the base class calls this method, Java calls the method defined by the child class.
You also don't have to implement certain methods in abstract classes. You can decide what have to be declared in Subclasses and what you want declare in the Superclass.
Look at OutputStream for example:
public abstract void write(int i) throws IOException;
public void write(byte abyte0[]) throws IOException {
write(abyte0, 0, abyte0.length);
}
public void write(byte abyte0[], int i, int j) throws IOException {
if(abyte0 == null)
throw new NullPointerException();
if(i < 0 || i > abyte0.length || j < 0 || i + j > abyte0.length || i + j < 0)
throw new IndexOutOfBoundsException();
if(j == 0)
return;
for(int k = 0; k < j; k++)
write(abyte0[i + k]);
}
You have an abstract write method (because you don't knwo where the OutputStream is going to) but all other extra write methods are not abstract and forwarded to this methods. So you only have to declare one method in the Subclass and have some methods "extra" without having to implement it in every Subclass.
You may want a class not to have any instances.
For example assume you have a Person class and two classes derived from it Student and Teacher. In this case you may not want to have any objects created from Person class as it may not have any meaning for your program.
The "point" is to enforce a class hierarchy, potentially with some functionality provided by base class(es), and force some behavior to be implemented by sub-classes.
You would use an abstract class in cases where you do want to specify certain behaviour but don't want anybody to instatiate it directly but having to subclass it.
An abstract class can be full bodied or the skeleton for the subclass. You define your template in the abstract class and its left for the subclass to extend and implement the methods defined in the superclass.
So I guess the abstract keyword or abstract concept is just to complete the inheritance hierarchy, make incomplete types impossible to instantiate, or is to promote good OOP practice?
My answer is yes to everything that you said.
Along with what others have said, you may be using a library written by someone else, where you don't have access to the source code, but want to change it's behavior.

Java - Can the children of an abstract class (the "extends"-ers) instantiate themselves via their parents abstract method?" i.e. m = new this();"?

First things first, please be aware I am trying to express my question as best I can with my current knowledge and vocabulary, so please excuse this...
I have an abstract class in which I want to make a method where it instantiates itself.... Of course this is impossible in an abstract class, however, what I really want is for the concrete children (those classes that "extends") to inherit this instantiation so that they then can instantiate themselves....
Basically what I want to do is this:
MyAbstract a = new this();
However this isn't allowed... Is there any way I can do what I want?
Here is some non-compiling dream-code (i.e. code I wish worked). Basically I am wanting the ConcreteChild to call a method in which it create an object of itself. The method is inherited from it's parent.
public class Abstract {
public void instantiateMyConcreteChild()
{
Abstract a = new this();
}
}
public class ConcreteChild extends Abstract{
public static void main(String[] args) {
ConcreteChild c = new ConcreteChild();
c.instantiateMyConcreteChild();
}
}
* Additional info **
Thanks for the replies but I think I missed something vital....
Basically I wanted to pass an object's self ( "this" ) into some methods of some other classes. However, creating instantiating another object within an object is a bit backwards, I can just pass "this", right...
You can do this using reflection, something like :
Abstract a = getClass().newInstance();
This is because getClass() always returns the concrete class, so this.getClass() will return the real subclass and not the current class.
However, beware that if the subclass defines a custom constructor, having more or less parameters than your abstract class, it could fail. Unless you specify in the documentation that subclasses must have a constructor with such given parameters ... but it's fragile anyway.
You can inspect it, using getClass().getConstructors() and see which constructors are there, and if there is the one you are expecting, or even search for a viable one, otherwise you can catch the exception thrown by newInstance(..), and wrap it in a more descriptive exception for the users, so that they understand better what they missed ... but it would still be a kind of a hack, cause there is no explicit language support for such a situation.
Another approach could be to implement Cloneable in your abstract class, and then use the clone method, but it could be overkill or even wrong if what you want is a new, clean instance.
You can't do this using an instance method. Because as the name implies an instance methods requires that the instance has already instantiated.
What you actually need to do here is to separate the non-changing internal functionality from the abstract class itself. So what I could do is to ,for e.g., have an inner class that really encapsulates the non-changing functionality like so:
public class Abstract {
public void instantiateMyConcreteChild()
{
Abstract a = new NonChangingOperations();
}
class NonChangingOperations
{
public void operationA() {}
}
}
Infact you really dont need to keep the class NonChangingOperations as an inner class, you could make it as an external utility class with its own class hierarchy.
Are you trying to define a constructor that the subclasses of Abstract can use? If so you could simply do it the same way you define any other constructor.
public class Abstract {
Abstract() {
//set fields, etc. whatever you need to do
}
}
public class ConcreteChild extends Abstract{
ConcreteChild() {
//call superclass's constructor
super();
}
}
Could you just have this ?
public abstract class AbstractClassWithConstructor {
public AbstractClassWithConstructor() {
init();
}
protected abstract void init();
}
FYI
In the objective-c you need to set this by calling method init. The the method init() would look like this:
protected AbstractClassWithConstructor init() {
return this;
}

Categories

Resources