Abstract Class, OOP Design Pattern - java

I have an abstract class called "Operation"
and this class has an abstract method called "Prepare".
public abstract class Operation {
public abstract void prepare() throws Exception;
public abstract void run() throws Exception;
// other stuff here that's not abstract
public void printHelloWorld() {
System.out.println("Hello World!");
}
}
The only issue is that some things that are "Operation" (
some classes that extends Operation ) need arguments to prepare ( some
need ints, some need String, some need more complex data types..so it's not always an int )
public class Teleportation extends Operation {
#Override
public void prepare(int capacityRequired ) throws Exception {
// do stuff
}
#Override
public void run() throws Exception {
}
}
What OOP pattern do I use to achieve this
and how do I set up this code ?
EDIT :
Ideally, I want to prepare and run operations like this :
for (Operation operation : operations ) {
operation.prepare();
operation.run();
}
Assuming I use this solution :
public class Teleportation extends Operation {
private int cReq;
public void setCapacityRequired(int cReq) {
this.cReq = cReq;
}
#Override
public void prepare() throws Exception {
// I can do the preparation stuff
// since I have access to cReq here
}
#Override
public void run() throws Exception {
}
}
Then - I wonder if it's possible to avoid this :
for (Operation operation : operations ) {
if (operation.getClass().isInstanceOf(Teleporation.class)) {
((Teleporation)operation).setCapacityRequired( 5 );
}
operation.prepare();
operation.run();
}

I would recommend having an additional constructor where you can add the necessary data that the implementation requires and store it in fields for the class implementation.
For your example:
public class Teleportation extends Operation {
private final int capacityRequired;
public Teleportation(int capacityRequired) {
this.capacityRequired = capacityRequired;
}
public void prepare() throws Exception {
// do stuff using the capacityRequired field...
}
}
This approach applies for more complex parameters as well.

The very first thing to do here is to override the abstract class operation and overload with your capacity.
public class Teleportation extends Operation {
public void prepare() throws Exception {
prepare(0);
}
public void prepare(int capacityRequired) throws Exception {
//do stuff
}
}
And remember the KISS and YAGNI statements, there is no need to use design patterns anywhere in your code, just where they makes things simpler.

You either need to expand the abstract class to include two method signatures or change the signature to take a varargs int parameter:
public abstract class Operation {
public abstract void prepare(int... args) throws Exception;
}

You can use generic class for your operation class:
public abstract class Operation<T>
{
private T operationModel;
public Operation(T operationModel)
{
super();
this.operationModel = operationModel;
}
public abstract void prepare() throws Exception;
public abstract void run() throws Exception;
public T getOperationModel()
{
return operationModel;
}
}
Then for concrete classes, extend it with proper parameter-type (You can have a specific class for each operation):
public class TeleOperation extends Operation<TeleOperationModel>
{
public TeleOperation(TeleOperationModel operationModel)
{
super(operationModel);
}
#Override
public void prepare() throws Exception
{
TeleOperationModel teleOperationModel = getOperationModel();
//...
}
#Override
public void run() throws Exception
{
}
}
public class TeleOperationModel
{
private int capacity;
....
}
and:
public class MicroOperation extends Operation<MicroOperationModel>
{
public MicroOperation(MicroOperationModel operationModel)
{
super(operationModel);
}
#Override
public void prepare() throws Exception
{
MicroOperationModel microOperationModel = getOperationModel();
//...
}
#Override
public void run() throws Exception
{
}
}
public class MicroOperationModel
{
private int x;
private int y;
private int z;
....
}

Related

getThis() trick and ClassCastException

I've been wondering about the getThis() trick, and the alternative of the unsafe cast from a self-bounded type to its type parameter.
public abstract class SelfBound<T extends SelfBound<T>> {
protected abstract T getThis();
public void doSomething(T instance) { ... }
public final void doSomethingWithThis() { doSomething(getThis()); }
public final void doSomethingWithThisUnsafe() { doSomething((T) this); }
}
Is it possible to subclass SelfBound such that doSomethingWithThisUnsafe() throws a ClassCastException? (Is it possible to do this without subclassing SelfBound?)
Surely it's possible to have ClassCastException with subclassing. Here's a simple example:
public abstract class SelfBound<T extends SelfBound<T>> {
protected abstract T getThis();
public void doSomething(T instance) { }
public final void doSomethingWithThis() { doSomething(getThis()); }
public final void doSomethingWithThisUnsafe() { doSomething((T) this); }
public static class A extends SelfBound<A> {
#Override
protected A getThis() {
return this;
}
}
public static class B extends SelfBound<A> {
#Override
public void doSomething(A instance) {
super.doSomething(instance);
}
#Override
protected A getThis() {
return null;
}
}
public static void main(String[] args) {
new B().doSomethingWithThisUnsafe();
}
}
Output:
Exception in thread "main" java.lang.ClassCastException: SelfBound$B cannot be cast to SelfBound$A
at SelfBound$B.doSomething(SelfBound.java:1)
at SelfBound.doSomethingWithThisUnsafe(SelfBound.java:6)
at SelfBound.main(SelfBound.java:28)
It's not so clear what do you mean by "without subclassing SelfBound". As SelfBound is an abstract class, you cannot call its methods without subclassing it, thus you cannot have any exception when calling its methods.

How to call instance of variety of classes in java

I create a class to handle some specific job that use variety of classes on my project.
But after finish the job class must call-back specific method on the called classes.
I use interface to handle this call-back method.
How can I store the called class?
I can get the instance from constructor but I'm looking for generic way.
Your question is not clear but it may be possible that you have missed the fact that classes can implement more than one interface.
public interface DoesAJob {
public void doIt();
}
public interface Finishes {
public void finish();
}
class AThing implements DoesAJob, Finishes {
#Override
public void doIt() {
}
#Override
public void finish() {
}
}
private void doTheJob(DoesAJob thing) {
thing.doIt();
}
private void finishUp(Finishes thing) {
thing.finish();
}
public void test() {
AThing thing = new AThing();
doTheJob(thing);
finishUp(thing);
}
You can use just Java Interface, or use Java Reflection.
First the Interface
package test;
public interface MyClassInterface {
public String getName();
}
next, the Interface Implementation
package test;
public class MyClassImplementation implements MyClassInterface {
String name;
public MyClassImplementation() {
name= "Whatever";
}
public String getName() {
return name;
}
}
finally invoke the class. just Interface example:
package test;
public class MainTest {
public static void main(String[] args){
MyClassInterface myClassImplementation = new MyClassImplementation();
System.out.println(myClassImplementation.getName());
}
}
Using Reflection example:
package test;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class MainTest {
public static void main(String[] args)
throws InstantiationException, IllegalAccessException, IllegalArgumentException,
InvocationTargetException, NoSuchMethodException, SecurityException {
//using reflection
Object otherClassImplementation=null;
try {
Class<?> cls = Class.forName("test.MyClassImplementation");
otherClassImplementation = cls.newInstance();
Method method = cls.getMethod("getName");
System.out.println(method.invoke(otherClassImplementation));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}

writing good abstract classes in java

I have the following need and please help me to write good and abstract class.
Different types of operations is needed based on the type
I have a abstract class,
abstract public class FileHelper{
//Template method
//This method defines a generic structure for parsing data
public void parseDataAndGenerateFile(String fileDownloadType)
{
createHeader(fileDownloadType);
generateFile();
}
//We have to write output in a excel file so this step will be same for all subclasses
public void createHeader(String fileDownloadType)
{
System.out.println('Creating HEADER in EXCEL');
}
public void generateFile(String fileDownloadType)
{
System.out.println('Output generated,writing to XLX');
}
}
public class ExcelDataParser extends FileHelper {
String fileDownloadType="";
}
public class TemplateMethodMain {
public static void main(String[] args) {
String fileDownloadType="expired";
ExcelDataParser csvDataParser=new ExcelDataParser();
csvDataParser.parseDataAndGenerateFile(fileDownloadType);
}
}
Please help me and correct me to have a good way of doing this.
If you want to use an abstract base class, you better should declare an abstract method String getDownloadType() in your abstract base class. These method must be overridden by the derived classes and the type could be fix in the derived class.
For example:
abstract public class FileHelper {
abstract String getFileDownloadType();
public void parseDataAndGenerateFile() {
createHeader();
generateFile();
}
public void createHeader() {
if ("expired".equals(getFileDownloadType())) {
} else {
}
}
public void generateFile() {
if ("expired".equals(getFileDownloadType())) {
} else {
}
}
}
public class ExcelDataParser extends FileHelper {
#Override
String getFileDownloadType() {
return "expired";
}
}
public class TemplateMethodMain {
public static void main(String[] args) {
ExcelDataParser csvDataParser = new ExcelDataParser();
csvDataParser.parseDataAndGenerateFile();
}
}
But if you don't need a class for every type, you also could make the type a variable inside a single class and passing the type to the contructor
For example:
public class CsvFileHelper {
private final String fileDownloadType;
public CsvFileHelper(String type) {
fileDownloadType = type;
}
public void parseDataAndGenerateFile() {
createHeader();
generateFile();
}
public void createHeader() {
if ("expired".equals(fileDownloadType)) {
} else {
}
}
public void generateFile() {
if ("expired".equals(fileDownloadType)) {
} else {
}
}
}
public class TemplateMethodMain {
public static void main(String[] args) {
CsvFileHelper csvDataParser = new CsvFileHelper("expired");
csvDataParser.parseDataAndGenerateFile();
}
}

How to reimplement Java listeners with anonymous classes in C#

I am trying to replicate my Java code in C# and I wish to know how can I replicate this Java functionality in C#.
Util.java
public class Util
{
public void function(String s, final SetAvailabilityStatusListener setStatusListener)
{
// ....
}
public static interface SetAvailabilityStatusListener {
public void setAvailabilityStatus(Status status);
}
}
Activity.java
public class Activity
{
public void anotherFunction()
{
util.function("name", new SetAvailabilityStatus()
{
#Override
public void setAvailabilityStatus(Status status) {
loginSetAvailabilityStatus(status);
}
}
}
}
Use delegates. They are used in C# instead of Java anonymous classes that implement interfaces.
public class Util
{
public void Function(String s, Action<Status> setStatusListener)
{
// ....
setStatusListener("myStatus");
}
}
public class Activity
{
private Util util = new Util();
public void AnotherFunction()
{
util.Function("name", status => LoginSetAvailabilityStatus(status));
}
public void LoginSetAvailabilityStatus(string status){
//do something with status
}
}
I was unable to find suitable duplicate, so:
1. C# does not have anonymous classes like Java does, but no one stops you from creating needed listener classes manually
public class Util
{
public void Function(String s, ISetAvailabilityStatusListener setStatusListener)
{
// ....
}
public interface ISetAvailabilityStatusListener {
public void SetAvailabilityStatus(Status status);
}
}
public class Activity
{
private class MySetAvailabilityStatusListener: Util.ISetAvailabilityStatusListener
{
public void SetAvailabilityStatus(Status status)
{
// do your handling, but nested classes have some differences with anonymous Java classes, so it may require additional infrastructure.
}
}
public void AnotherFunction()
{
utilObj.Function("name",
new MySetAvailabilityStatusListener())
}
}
It is so-called observer design pattern (just without unregistration method!!).
2. As it has been already suggested by #AndreySarafanov you can use Action Delegates and lambda expressions:
public class Util
{
public void Function(String s, Action<Status> statusChangeListener)
{
// ....
}
}
public class Activity
{
public void AnotherFunction()
{
utilObj.Function("name",
(status) =>
{
loginSetAvailabilityStatus(status);
}
}
}
3. C# has another more simple mechanism to deal with event-handling(subsrciption) mechanics - events and delegates
public class StatusEventArgs : EventArgs
{
//...
}
public class Util
{
public void SomeFunction()
{
// ....
if (this.OnAvailabilityChanged != null)
OnAvailabilityChanged(this, new StatusEventArgs(status));
}
public event EventHandler<StatusEventArgs> OnAvailabilityChanged
}
public class Activity
{
public void AvailabilityStatusChangedHandler(object sender, EventArgs<Status> eventArgs)
{
}
public void AnotherFunction()
{
utilObj.OnAvailabilityChanged += this.AvailabilityStatusChangedHandler;
}
}
It does not allow you to associate the name property with event handler, well, you can overcome it with special registration method, but it will reduce the usability of events, so you should probably stick with another solution.

Can not cast class to generics in java

Please help resolve an issue regarding generics. I tried many ways but it's still not working.
Problem is:
public static void main(String[] args) {
Utils.execute(new TestAction(), new TestCallBack());
}
Compiler show error:
The method execute(Action<?>, CallBack<?,Action<?>>) in the type Utils is not applicable for the arguments (ImplementClass.TestAction, ImplementClass.TestCallBack)
My classes is:
Action class:
public abstract class Action<R> {
public R getResult() {
return null;
}
}
TestAction class is:
class TestAction extends Action<String> {
#Override
public String getResult() {
return super.getResult();
}
}
Callback class is:
public interface CallBack<R, A extends Action<R>> {
public void onCall(A action);}
TestCallback class is:
class TestCallBack implements CallBack<String, TestAction> {
#Override
public void onCall(TestAction action) {
}
}
And Utils class is:
public class Utils {
public static void execute(Action<?> action, CallBack<?, Action<?>> callback) {
}
}
Thanks a lot.
The second parameter of the execute method is CallBack<?, Action<?>>, and Action there means the Action class itself, subclass of it is not allowed. What you need there is - ? extends Action<?>, which means either Action or some subclass of it.
Try changing the method signature -
public static void execute(Action<?> action, CallBack<?, ? extends Action<?>> callback) {
Note:
Generics are not co-variant. Take for example a method as follows -
static void method(List<Object> l) {}
And an invocation as follows is not allowed -
method(new ArrayList<String>());
You need to change two things,
TestCallBack should be like this -
public static class TestCallBack implements CallBack<String, Action<String>> {
#Override
public void onCall(Action<String> action) {
}
}
and, Utils should be like this -
public static class Utils {
// You need to ensure the same type, not just try and accept anything.
public static <T> void execute(Action<T> action, CallBack<?, Action<T>> callback) {
}
}
or using inner classes of a class called Question -
public abstract class Action<R> {
public R getResult() {
return null;
}
}
public class TestAction extends Action<String> {
#Override
public String getResult() {
return super.getResult();
}
}
public interface CallBack<R, A extends Action<R>> {
public void onCall(A action);
}
public class TestCallBack implements CallBack<String, TestAction> {
#Override
public void onCall(TestAction action) {
}
}
public class Utils {
public void execute(Action<?> action, CallBack<?, ? extends Action<?>> callback) {
}
}
public static void main(String[] args) {
Question question = new Question();
question.new Utils().execute(question.new TestAction(), question.new TestCallBack());
}

Categories

Resources