cannot subclass the final class Subject Interface - java

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.

Related

Why can't an interface type invoke a non-implemented public method of an object of the "subclass"? [duplicate]

I have the following scenario in Java. Let's say I have an interface, and two classes that implement this interface. As follows:
public interface myInterface {
public String printStuff();
}
public class A implements myInterface {
#Override
public String printStuff(){
return "Stuff";
}
}
public class B implements myInterface {
#Override
public String printStuff(){
return "Stuff";
}
public String printOtherStuff(){
return "Other Stuff";
}
}
How do I call the printOtherStuff method above if I define it as follows:
public static void main(String... args) {
myInterface myinterface = new B();
String str = myinterface.printOtherStuff(); // ? This does not work
}
The above calling code does not seem work. Any ideas?
myInterface myinterface = new B();
The reference type of myinterface is myInterface. That means you can only access the methods defined in the interface. You can cast it to type B in order to make the method call.
NOTE: From here on out I'll be using the proper naming conventions.
Example
MyInterface myInterface = new B();
String str = ((B)myInterface).printOtherStuff();
Just a note on this
If you need to do this, then you need to have a look at your class design. The idea of using an interface in this way is to abstract away from the details of the object's concrete implementation. If you're having to perform an explicit cast like this, then you might want to look into either changing your interface to accommodate the necessary methods, or change your class so that the method is moved into a global location (like a util file or something).
Extra Reading
You should read about reference types here, and you should have a look at casting here. My answer is a combination of the understanding of both of these things.
As an added note, take a look at the Java Naming Conventions. This is a vital piece of information for any Java developer to make understandable code.
Surely this wouldn't work because you have reference type of Interface MyInterface. At the time of method binding compiler would try to find this method in your Interface MyInterface which is not available. So you need to cast it to your class like this.
MyInterface myInterface = new B();
B newB=(B) myInterface ;//casting to class
newB.printOtherStuff();// would work fine
change myInterface
public interface myInterface {
public String printStuff();
public String printOtherStuff();
}
If you cant change myInterface, then extends myInterface
public interface myOtherInterface extends myInterface {
public String printOtherStuff();
}
Then Implements myOtherInterface
public class B implements myOtherInterface {
#Override
public String printStuff(){
return "Stuff";
}
#Override
public String printOtherStuff(){
return "Other Stuff";
}
}
public static void main(String... args) {
myOtherInterface myotherinterface = new B();
String str = myotherinterface.printOtherStuff();
}

Find private inner class using reflection

In the context of android.accounts.AccountManager:
public class AccountManager {
private abstract class AmsTask extends FutureTask<Bundle> implements AccountManagerFuture<Bundle> {
...
}
}
I would like to find the inner class by name using reflection, as I require a Class object to determine staticness of member methods. In the simple case
public class AccountManager {
public class Foo {
...
}
}
This can be done using Class.forName("android.accounts.AccountManager$Foo"). However, the private modifier eliminates this possibility. I tried searching through Class.forName("android.accounts.AccountManager").getDeclaredClasses(), but it returns an empty list. Its specification covers private member classes, so I am at a loss why it is not returned by the getter. I presume it has something to do with abstract.
EDIT: Experiments have shown getDeclaredClasses() to work with the following snippet, but not with the actual Android class.
public class Test {
private abstract class AmsTask extends LinkedList implements TestInterface {
...
}
private interface TestInterface{}
}
The suggestion that using AccountManager's class loader might help, did not turn out to be fruitful.
Class am = Class.forName("android.accounts.AccountManager");
Class.forName("android.accounts.AccountManager$AmsTask",false,am);
resulted in a ClassNotFoundException during the latter call.

Equivalent to extend final class to add extra functionality in java

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() {
//
}
}

How do I convert an abstract class into an interface?

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).

How to implement an interface on a protected java class

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.

Categories

Resources