I want to extend final class in java to add a new method in inherited class. Which pattern should I use?
for example:
final class foo {
}
foo is a final class in java.
I want to extend this in built class to add extra functionality.
class bar extends foo {
dosomething(){
}
}
I can't extend final class. what should I do so that bar acts like foo with added functionality?
Is there a pattern to implement this functionality? So that it will execute all the functions of final class with added functionality
As you can't extend what you can do is to wrap the class and its methods. You won't be able to use the wrapper where the final class is required, but you can implement any interfaces which are on the final class
edit: Also see this discussion Equivalent to extending a final class in Java
final class Foo {
public String getSomething() {
//
}
}
class Bar {
Foo foo;
public Bar() {
foo = new Foo();
}
public String getSomething() {
foo.getSomething();
}
public String doSomethingElse() {
//
}
}
Related
import javax.security.auth.Subject;
abstract class Department extends Subject{
String name;
}
I have this piece of code. Sadly this throws the following error: The type Department cannot subclass the final class Subject
I was reading the documentation: https://docs.oracle.com/javase/7/docs/api/javax/security/auth/Subject.html but there is nothing much on how to use it(a specific use case).
Does anyone know how you can use Subject on an abstract Class (it has to be extended by an abstract class) ?
Edit:
Edit 2: Error Using Implements:
The type Subject cannot be a superinterface of Department; a superinterface must be an interface
Since Subject class is a final class you won't be able to extend it. That's the purpose of the final keyword. The only way I see is wrapping the class and its methods. You won't be able to use the wrapper where the final class is required, but you can implement any interfaces which are on the final class.
ex:
final class Foo {
public String getSomething() {
//
}
}
class Bar {
Foo foo;
public Bar() {
foo = new Foo();
}
public String getSomething() {
foo.getSomething();
}
public String doSomethingElse() {
//
}
}
Not sure it would be helpful in your scenario tho.
An enum can implement an interface. Is it possible for some of the values to implement an interface? The use case that I am thinking of is a tagging interface, so something like the following:
interface Foo {}
interface Bar {}
enum Widgets {
FOO implements Foo,
BAR_1 implements Bar,
BAR_2 implements Bar
}
That does not compile under Java 1.8. I know that internally, there are separate classes created for FOO and BAR_1, so it seems this is possible, but I can easily see the standard not supporting it.
Something similar that should work is
interface Widgets;
enum Foo implements Widgets { FOO };
enum Bar implements Widgets { BAR_1, BAR_2 };
This has the drawback that I cannot just do Widgets.values() and get all of the Widgets.
The Java Language Specification states
The optional class body of an enum constant implicitly defines an
anonymous class declaration (§15.9.5) that extends the immediately
enclosing enum type. The class body is governed by the usual rules of
anonymous classes; in particular it cannot contain any constructors.
Instance methods declared in these class bodies may be invoked outside
the enclosing enum type only if they override accessible methods in
the enclosing enum type (§8.4.8).
An anonymous class can only extend (or implement) the type specified in the new instance creation expression, your enum type in this case. As such, you can't have it additionally implement an interface.
The following
enum Foo {
CONSTANT
}
gets compiled to something similar to
class Foo extends Enum<Foo> {
private Foo() {/* calling Enum superconstructor */}
public static final Foo CONSTANT = new Foo();
}
If you wanted the constant to have a body (to override or declare some methods)
enum Foo {
CONSTANT {
public String toString() {
return name().toUpperCase();
}
}
}
becomes something like
class Foo extends Enum<Foo> {
private Foo() {/* calling Enum superconstructor */}
public static final Foo CONSTANT = new Foo() { // no way to express an additional interface
public String toString() {
return name().toUpperCase();
}
};
}
The enum values are not classes but instances, so they cannot implement an interface.
However, if what you want is just a way to "tag" your values, you can use a field:
enum Widgets {
FOO(true, false),
BAR_1(false, true),
BAR_2(false, true),
BOTH(true, true);
private final boolean isFoo;
private final boolean isBar;
Widgets(boolean isFoo, boolean isBar) {
this.isFoo = isFoo;
this.isBar = isBar;
}
public boolean foo() {
return isFoo;
}
public boolean bar() {
return isBar;
}
}
In that example, you will be able to enumerate your values with Widgets.values() and to know if each value is tagged "foo", "bar" or both.
An other method to "tag" you values can be:
enum Tag {
FOO,
BAR;
}
enum Widgets {
FOO(Tag.FOO),
BAR_1(Tag.BAR),
BAR_2(Tag.BAR),
BOTH(Tag.FOO, Tag.BAR);
private Tag[] tags;
Widgets(Tag... tags) {
this.tags = tags;
}
public Tag[] getTags() {
return tags;
}
}
This is a simplified example of something I'm currently designing.
public class ExampleManager {
private Foo foo;
private ArrayList<Example> examples;
...
public ExampleManager() {
this.foo = new Foo();
this.examples = new ArrayList<Example>();
}
public void add(Example e) {
examples.add(e);
}
public void doSomethingWithExamples() {
for (int i = 0; i < examples.size(); i++) {
examples.get(i).doSomething();
}
}
...
}
public abstract class Example {
private Foo foo;
public Example(Foo foo) {
this.foo = foo;
}
...
}
In order to use the library, I have to extend the Example class and add examples to the ExampleManager, which should be the only class that modifies the Example objects.
So I have this Example1 class:
public class Example1 extends Example {
public Example1(Foo foo) {
super(foo);
}
...
}
and I currently initialize the manager like this:
ExampleManager manager = new ExampleManager();
Example1 example1 = new Example1(manager.getFoo());
manager.add(example1);
My Example needs the Foo object, but I'm wondering if I could get rid of the Foo argument in the Example1 constructor, so if someone uses the library, doesn't have to call manager.getFoo() in order to create an Example.
I'm thinking about the following solution, which will hide the Foo initialization, so the person who makes use of the library just have to implement the initialize(Foo) method, and the Foo would be initialized automatically when adding the example to the ExampleManager)
In ExampleManager: change the add(Example) method for:
public void add(Example e) {
e.initialize(foo);
examples.add(e);
}
In Example, initialize(Foo foo); would be an abstract method, so in Example1 I would have something like this:
#Override
public void initialize(Foo foo) {
this.foo = foo;
}
Is there any better way to do this?
It seems to me that you have some issues with your OO model in the first place if you need to hand objects around like you describe. - Or maybe your sample code does not reveal the real point of things.
Especially
ExampleManager [...] should be the only class that modifies the Foo objects
and
Example needs the Foo object
look somewhat 'special'.
Can you elaborate what the interactions are between the ExampleManager and the Foo instance, and between the Example and the Foo instance?
Ok, with regard to your comment, I propose the observer pattern, much like your initialize() approach:
public abstract class Example {
protected Foo callbackHandler;
public void setCallbackHandler( Foo handler ) {
this.callbackHandler = handler;
}
protected void doCallback( SomeType event ) {
if ( this.callbackHandler != null ) {
this.callbackHandler.doYourThing( event );
}
}
}
and have ExampleManager register itself or its Foo instance as the callback handler when an object is added to it. Non-abstract subclasses will then only need to call doCallback(...) whenever they want to communicate something and won't have to deal with any setup stuff for the callback.
I have a java program which uses arraylists - these arraylists store 'variables' where 'variables' is an abstract class.
Now, to save memory, I want to use a java library called HugeCollections-VanillaJava- however this library requires an interface to be defined.
How do I convert the abstract class into an interface? What rules/restrictions do I have to follow, to correctly perform the conversion?
Finally, is it possible for me to use my abstract class with minimal code changes, so that the library that requires an interface, also works correctly? Ideally I would like not to change the abstract class at all...Is this possible?
how do I convert an abstract class into an interface?
Make a copy of the abstract class source file.
Change "class" to "interface" in the initial declaration.
Change the name (optionally, depends on what you're doing).
Remove the bodies of any methods that are implemented by the class.
Remove the word "abstract" from the other ones.
Remove all private and protected members.
Remove all constructors.
Remove the keyword "public" from the public members.
If you had any code you removed (implemented methods, private or protected stuff), have your original abstract class implement your interface and leave that stuff there.
(Incomplete) Example:
Foo as an abstract class:
public abstact class Foo
{
private int bar;
public static final int SOME_CONSTANT = 42;
public Foo(b) {
this.bar = b;
}
public abstract void doSomething(String s);
protected int doSomethingElse() {
return this.bar * 2;
}
}
Foo as an interface:
public interface Foo
{
int SOME_CONSTANT = 42;
void doSomething(String s);
}
In my case, as I did have some stuff the old Foo did, I'd probably have AbstractFoo or something:
public abstact class AbstractFoo implements Foo
{
private int bar;
public Foo(b) {
this.bar = b;
}
public abstract void doSomething(String s);
protected int doSomethingElse() {
return this.bar * 2;
}
}
...so that an implementation could use it as a starting point if desired (although with that private bar in there, it doesn't make a lot of sense).
Pattern Adapter might help you.
Imagine, you're have to use SomeClass as TargetInterface
public abstract class SomeClass {
// some code here
public abstract void someMethod();
}
public interface TargetInterface {
public void someMethodBlaBla();
}
And they have different signatures of methods - someMethod() and someMethodBlaBla().
So you're might create such adapter class:
public class Adapter implements TargetInterface {
private SomeClass adaptee;
public Adapter( SomeClass adaptee ) {
this.adaptee = adaptee;
}
public void someMethodBlaBla() {
this.adaptee.someMethod();
}
//delegate all calls to adaptee
}
and somewhere in code you might use both - adapter and instance of abstract class, without interference on current code:
SomeClass abstractClassInstance = ... //get instance of your abstract class
TargetInterface targetInterfaceInstance = new Adapter( abstractClassInstance );
If abstract class does not define any concrete methods, you can even use regular expression for that. From:
public abstract class Abstract {
public abstract void method();
//...
}
to:
public interface Interface {
void method();
//...
}
public abstract modifiers are implicit for interfaces. If the abstract class does define some methods (not all methods are abstract) or have some fields this can't be done (at least easily).
I was looking to implement an interface on a package-private java class, but I am having some difficulty achieving this. Below is an example.
class Foo
{
String something(String str)
{
return ""str+"!";
}
}
public interface Bar
{
String something(String str);
}
What is the best approach here? My end goal is to implement the Bar interface on the Foo class. I am hoping to be able to cast Foo as Bar: (Bar)Foo
The Bar interface and the Foo class are in separate packages. Is there a way to do this?
Please advise.
You can't. The point of having the package level access it to precisely avoid seeing that class outside. What you can do however ( granted Foo is not final ) something like this:
C:\>type *.java
//Foo.java
package foo;
class Foo {
String something( String s ) {
return s + "!";
}
}
//Bar.java
package bar;
public interface Bar {
public String something( String s );
}
//Baz.java
package foo;
import bar.Bar;
public class Baz extends Foo implements Bar {
// make sure you're overriding
#Override
public String something ( String s ) {
return super.something( s );
}
}
//Use it: Main.java
package bar;
import foo.Baz;
class Main {
public static void main( String ... args ) {
Bar bar = new Baz();
System.out.println( bar.something("like this?"));
}
}
C:\>java bar.Main
like this?!
Da da!
The trick is to define the child in the same package as the parent so you can create a public version of it.
I hope this helps.
When you doesn't have control on a class but you want to make it look like an API that you have, then you Adapt it to fit your needs. Hint: Adapter Pattern
Foo needs to implement Bar
protected class Foo implements Bar
Also, I think Foo.something needs to be public in order to implement Bar.something
Side Note: While it was probably just as an example,
return ""str+"!";
should be:
return str + "!";
If Foo is package private, and you don't have access to the source, just the classfiles and/or the jar containing Foo.class, there's not much to do -- something that is package private is invisible to classes in the default package (where there is no package specified) and other packages.
You'll need to use inheritance or composition if you don't have access to the source code of Foo.
// By logically including your code in the package containing Foo,
// you can now access it. If Foo belongs to the default package, sorry.
// This also doesn't work if the package is sealed.
package where.foo.resides;
public interface Bar {
String something(String s);
}
// Inheritance
public class FooBar extends Foo implements Bar {
public String something(String s) {
return super.something(s);
}
}
// Composition
public class ComposedFooBar implements Bar {
private final Foo delegate;
public ComposedFooBar(Foo delegate) {
this.delegate = delegate;
}
public String something(String s) {
return delegate.something(s);
}
}
You can try using bytecode injection with BCEL or ASM and setting the interface at runtime. It's tricky, though.
There might also be a way to change interaces with reflection, but I doubt it.
Private is there for a reason.