Can IntelliJ automatically create a decorator class? - java

Sometimes, I create a decorator class like this:
class MyInterfaceDecorator implements MyInterface {
private final MyInterface delegate;
... constructor taking a MyInterface instance ...
#Override
public Object someInterfaceMethod(Some argument) {
return delegate.someInterfaceMethod(argument);
}
... etc, more methods here...
}
Can IntelliJ automatically create this class for me?

Update//
I noticed that IntelliJ has a "Generate" option for generating delegate methods. Create a new class:
public class MyDecoratorClass {
private MyInterfaceWithManyMethods myInterface;
}
Then mark myInterface, go to Menu > Code > Delegate Methods, select all methods you want to wrap and that's it.
//End of update
You could try the "Refactoring" -> "Replace inheritance with delegation" refactoring. It should be able to do this, like this. I call this "Code with Alt+Enter"
Go to the interface you want to generate a decorator for.
public interface MyInterfaceWithManyMethods {
void method1();
void method2();
void method3();
}
Press Alt+Enter, select "Implement Interface", give a name to your Decorator like "MyDecorator". This gives you
public class MyDecorator implements MyInterfaceWithManyMethods {
public void method1() {
}
public void method2() {
}
public void method3() {
}
}
In new class, select the class name, then "Refactor" -> "Replace inheritance with delegation", select your interface, tick all method names, press enter. You'll get:
public class MyDecorator {
private final MyObject object = new MyObject();
public void method1() {
object.method1();
}
public void method2() {
object.method2();
}
public void method3() {
object.method3();
}
private class MyObject implements MyInterfaceWithManyMethods {
public void method1() {
}
public void method2() {
}
public void method3() {
}
}
}
Delete the inner class and the object initializer manually. You get:
public class MyDecorator {
public void method1() {
object.method1();
}
public void method2() {
object.method2();
}
public void method3() {
object.method3();
}
}
Press Alt+Enter on the "object" which is now marked red, select "Create field", select MyInterfaceWithManyMethods.
public class MyDecorator {
private MyInterfaceWithManyMethods object;
public void method1() {
object.method1();
}
public void method2() {
object.method2();
}
public void method3() {
object.method3();
}
}
Select the object variable, press Alt+Enter, select "Add constructor Parameter":
public class MyDecorator {
private MyInterfaceWithManyMethods object;
public MyDecorator(MyInterfaceWithManyMethods object) {
this.object = object;
}
public void method1() {
object.method1();
}
public void method2() {
object.method2();
}
public void method3() {
object.method3();
}
}
You see it's all done with a few strokes of Alt+Enter. Reads like a lot of work but it can be done in less than 20 seconds. If you just have like 2 or 3 methods you might be faster with a live template, however if you have many methods with complex signatures you'll get a working result in about 20 seconds with this method. Alt+Enter simply rocks :D

You can perhaps add a file template like:
class ${NAME} implements ${INTERFACE} {
private final ${INTERFACE} delegate;
public ${NAME}(final ${INTERFACE} delegate) {
this.delegate = delegate;
}
and then when you have created the file using this template, just use
Alt+Inser and choice delegate Methods.
It's not perfect, but this could be a shortcut

Related

Abstract method with different parameters Java

public abstract class CommonClass {
abstract void send(<what should i put here???>) {}
}
public class ClassA extends CommonClass {
void send(List<Comments> commentsList) {
// do stuff
}
}
public class ClassB extends CommonClass {
void send(List<Post> postList) {
// do stuff
}
}
I am new to OODP, I am trying to have a method that is able to take in any kind of List data so that I can abstract things out. How can i do this?
You could make it generic on some type T. Like,
public abstract class CommonClass<T> {
abstract void send(List<T> al);
}
And then, to implement it - use the generic. Like,
public class ClassA extends CommonClass<Comments> {
#Override
void send(List<Comments> commentsList) {
// do stuff
}
}
public class ClassB extends CommonClass<Post> {
#Override
void send(List<Post> postList) {
// do stuff
}
}
Also, as discussed in the comments, your class names could be improved to be more intuitive; something like,
public abstract class AbstractSender<T> {
abstract void send(List<T> al);
}
and then
public class CommentSender extends AbstractSender<Comment> {
#Override
void send(List<Comment> commentsList) {
// do stuff
}
}
public class PostSender extends AbstractSender<Post> {
#Override
void send(List<Post> postList) {
// do stuff
}
}
That has the advantage(s) of being more readable and easier to reason about (I can tell what a PostSender does by reading the name, ClassB not so much).
Finally, this looks like a case where an interface would work since your abstract class is purely virtual (and should be preferred since you can implement multiple interface, but can only extend from a single parent class);
public interface ISender<T> {
void send(List<T> al);
}
public class CommentSender implements ISender<Comment> {
#Override
void send(List<Comment> commentsList) {
// do stuff
}
}
public class PostSender implements ISender<Post> {
#Override
void send(List<Post> postList) {
// do stuff
}
}
In order to achieve this, you can take multiple approaches, I would suggest looking into Generics: https://docs.oracle.com/javase/tutorial/java/generics/index.html
With that said, there is one approach that is the most elegant and simple: you can supply a List<T> where T is a generic type.
public abstract class CommonClass<T> {
abstract void send(List<T>) {}
}
public class ClassA extends CommonClass<Comment> {
void send(List<Comments> commentsList) {
// do stuff
}
}
public class ClassB extends CommonClass<Post> {
void send(List<Post> postList) {
// do stuff
}
}
You can do that with the help of generics. https://www.tutorialspoint.com/java/java_generics.htm
Example
The abstract class
public abstract class CommonClass {
public abstract <T> void send(List<T> data);
}
Its child
public class Child extends CommonClass {
public <T> void send(List<T> data) {
// code here
}
}
Retrieving the list's contents
Retrieving the generified list's contents is similar to retrieving any list's contents. In the scope of the method, "T" is a type of object contained in the list.
for (T t : data) {
// to check if t is a string
if (t instanceof String) {
// code
}
}
You can also use lambdas to retrieve every element in the list.

Triggering event from Class A to Class B using interface in Java

Suppose I have defined a class with interface like this:
public class myClass {
public void test() {
//here I want to trigger `onStartListener`
}
interface OnStartListener {
public void onStart();
}
}
and class B I have defined like this:
public class ClassB implements myClass.OnStartListener {
public void ClassB() {
myClass test1 = new myClass();
myClass.test();
}
#Override
public void onStart() {
System.out.println("start triggered");
}
}
How can I trigger OnStartListener from test method of myClass so ClassB can handle it?
Yes, you need to subscribe your listener and call the method in the class A:
public class ClassB implements myClass.OnStartListener {
public void ClassB() {
myClass test1 = new myClass(this);
//test1.setListener(this);
myClass.test();
}
#Override
public void onStart() {
System.out.println("start triggered");
}
}
and
public class myClass {
OnStartListener myListener;
public myClass(OnStartListener myListener) {
this.myListener = myListener;
}
public void test() {
//here I want to trigger `onStartListener`
myListener.onStart();
}
interface OnStartListener {
public void onStart();
}
}
Have a look at how frameworks like swing handle listeners. Basically you need to "register" the listener instance (ClassB instance) with myClass and call onStart() on it.
ClassB would probably contain a List<OnStartListener> which is used in a loop and onStart() is called on each element. Registering would mean assing the instance of ClassB to that list.

Get enum size from parent interface in java

I have an interface ParentInterface and have multiple enums that implement it: ChildEnum1 and ChildEnum2. I have a method to which I pass the ParentInterface as a parameter.
Based on what ChildEnum is passed to this method, I want to get the size of the enum. How can I do this? The values.length() method works only on enums, but we are only passing in the ParentInterface to the caller.
How can we achieve this?
With reflection, using Class#getEnumConstants() (quick and dirty demo):
package com.stackoverflow.so21821751;
public class Test {
interface ParentInterface {
void someMethod();
}
static enum ChildEnum1 implements ParentInterface {
FOO, BAR, LOL;
#Override
public void someMethod() {
// something
}
}
static enum ChildEnum2 implements ParentInterface {
FOO, BAR;
#Override
public void someMethod() {
// something
}
}
public static void main(final String[] args) {
foo(ChildEnum1.BAR); // 3
foo(ChildEnum2.FOO); // 2
}
private static void foo(final ParentInterface i) {
System.out.println(i.getClass().getEnumConstants().length);
}
}

Sad logic on types

Code base is littered with code like this:
BaseRecord record = // some BaseRecord
switch(record.source()) {
case FOO:
return process((FooRecord)record);
case BAR:
return process((BarRecord)record);
case QUUX:
return process((QuuxRecord)record);
.
. // ~25 more cases
.
}
and then
private SomeClass process(BarRecord record) { }
private SomeClass process(FooRecord record) { }
private SomeClass process(QuuxRecord record) { }
It makes me terribly sad. Then, every time a new class is derived from BaseRecord, we have to chase all over our code base updating these case statements and adding new process methods. This kind of logic is repeated everywhere, I think too many to add a method for each and override in the classes. How can I improve this?
First solution: good old polymorphism.
Simply add an abstract process() method to the BaseRecord class, and override it in every subclass. The code will thus become:
BaseRecord record = ...;
record.process();
If you can't add the process() method into the BaseRecord class (and its subclasses), then implement the visitor pattern. It will leave the process method outside of the BaseRecord class, but each time you add a new subclass, you'll be forced to modify the Visitor interface, and all its implementations. The compiler will thus check for you that you haven't forgotten a case somwhere in a switch.
public interface RecordVisitor<T> {
T visitFoo(FooRecord foo);
T visitBar(BarRecord foo);
...
}
public abstract class BaseRecord {
public abstract <T> T accept(RecordVisitor<T> visitor);
}
public class FooRecord extends BaseRecord {
#Override
public <T> T accept(RecordVisitor<T> visitor) {
return visitor.visitFoo(this);
}
}
public class BarRecord extends BaseRecord {
#Override
public <T> T accept(RecordVisitor<T> visitor) {
return visitor.visitBar(this);
}
}
Now you simply have to implement RecordVisitor for each block of logic described in the question:
RecordVisitor<Void> visitor = new ProcessRecordVisitor();
record.accept(visitor);
Both Visitor Pattern and Strategy pattern can be put in use here. http://en.wikipedia.org/wiki/Strategy_pattern and http://en.wikipedia.org/wiki/Visitor_pattern
I think this is instructive:
package classplay;
public class ClassPlay
{
public void say(String msg) { System.out.println(msg); }
public static void main(String[] args)
{
ClassPlay cp = new ClassPlay();
cp.go();
}
public void go()
{
A someClass = new C();
say("calling process with double dispatch");
someClass.dueProcess(this);
say("now calling process directly");
process(someClass);
}
public void process(A a)
{
say("processing A");
a.id();
}
public void process(B b)
{
say("processing B");
b.id();
}
public void process(C c)
{
say("processing C");
c.id();
}
abstract class A
{
abstract public void id(); // { System.out.println("Class A"); }
public void dueProcess(ClassPlay cp) { cp.process(this); }
}
class B extends A
{
public void id() { System.out.println("Class B"); }
public void dueProcess(ClassPlay cp) { cp.process(this); }
}
class C extends A
{
public void id() { System.out.println("class C"); }
public void dueProcess(ClassPlay cp) { cp.process(this); }
}
}

calling overridden function in superclass from subclass in JAVA

Suppose I have two classes A and B where A is a superclass of B. Now, I write a function (override), say funct() in both the classes. Then, if I want to call the funct() in A from an object of B, is it possible?
class A {
public void f() {...}
}
class B extends A {
#Override public void f() { super.f(); }
}
Is that what you want?
If instead you want to call A#f() directly on an instance of type B, you must provide a placeholder function for that:
class B extends A {
#Override public void f() { ... }
public void superF() { super.f(); }
}
new B().f(); // calls B#f();
new B().superF(); // calls A#f();
I have trick such as this situation to operate it in an illogical manner using Flag argument in funct() method :D, like this:
class A {
public void funct(boolean callSuper) {
// avoid using callSuper arg here
}
}
class B extends A {
#Override
public void funct(boolean callSuper) {
if (callSuper) {
super.funct(callSuper);
return;//if return type is void
} else {
//do here the functionality if the flag is false
}
}
}
or
class A {
public void funct() {
}
}
class B extends A {
private boolean callSuper = false;
#Override
public void funct() {
if (callSuper) {
super.funct(); // call A.funct() functionality
setCallSuper(false);
} else {
//do here the functionality of B.funct() if the flag is false
}
}
public void setCallSuper(boolean callSuper){
this.callSuper = callSuper;
}
}
Given classes like
class A {
public void funct() {...}
}
class B extends A {
#Override
public void funct() {...}
}
You ask
Then, if I want to call the funct() in A from an object of B, is it
possible?
So let's take
B b = new B();
b.funct();
A a = b;
a.funct();
((A)b).funct();
The above all do the same thing because of polymorphism and late-binding.
The only way to call the superclass' implementation is to get a reference to that member through the super keyword.
class A {
public void funct() {...}
}
class B extends A {
#Override
public void funct() {
super.funct();
}
}

Categories

Resources