Passing Abstract Class in Java - java

Trying to call a static method from an abstract class inside an instanced class. This is a primitive coding example of what I'm trying to do, but not sure how to go about it.
DataSource myDataSource = new DataSource();
DataAdapterTest.initialize(myDataSource);
public abstract class DataAdapterTest extends DataAdapter {
public static void initialize(DataSource d) {
d.addDataAdapter(DataAdapterTest.class);
}
public static void onCreate() {
does something here
}
}
public class DataSource {
public void addDataAdapter(Class<DataAdapter> c) {
c.onCreate();
}
}

Your problem is unclear. I'll answer to what I guess the problem is.
Signature compile error
I guess you have the following compile error:
The method addDataAdapter(Class) in the type
Main.DataSource is not applicable for the arguments
(Class)
Just use a wider signature for addDataAdapter()
public void addDataAdapter(Class<? extends DataAdapter> c) {
onCreate call
You seem to be trying to use polymorphism with static methods, which is not a good idea since static methods are relative to a class.
c.onCreate();
You can't directly call a method from the class this way, because c is a Class object instance, and does not have such a method.
It is not the same as calling:
DataAdapterTest.onCreate();
You should pass an instance of the class instead of a Class object, and use instance methods instead of static methods. On this aspect, it is hard to give advice because we don't know what you're trying to achieve.
Design problem
Needless Class parameter
You commented:
I need the DataSource to be able to call a method of varying
DataAdapter abstract classes
The code you gave here only uses one class extending DataAdapter. If you need several, then put at least 2 in your minimal example.
As of right now, I don't see the need of passing on a class here. You could as well do the following:
DataSource myDataSource = new DataSource();
DataAdapterTest.initialize(myDataSource);
public abstract class DataAdapterTest extends DataAdapter {
public static void initialize(DataSource d) {
d.addDataAdapter();
}
public static void onCreate() {
//does something here
}
}
public class DataSource {
public void addDataAdapter() {
DataAdapterTest.onCreate();
}
}
Needless static stuff
If everything in your DataAdapterTest class is static, then what is the purpose of extending DataAdapter? You can't use any inherited stuff without an instance of your child class.

Related

Require subclass to implement a static method [duplicate]

This question already has answers here:
Is there a way to make sure classes implementing an Interface implement static methods?
(9 answers)
Closed 2 years ago.
Coming from Python and Objective-C land, I may not fully understand what static methods are in Java, I think of them as "methods that operate on all members of the class" or "class-specific methods that are available when you don't have an instance of that class."
But is there a syntax for saying: "This abstract superclass requires each concrete subclass to implement this static method"? I know that static abstract isn't permitted, but it would conceptually be something like this:
public abstract class Lander {
#RequireImplmentationInSubclass // clearly my made-up name...
static abstract boolean probe(Radio radio);
}
public class MarsLander extends Lander {
static boolean probe(Radio radio) {
// ... some MarsLander specific implementation
}
}
public class LunarLander extends Lander {
static boolean probe(Radio radio) {
// ... some LunarLander specific implementation
}
}
update
... and somewhere else, a factory method does something like:
if (MarsLander.probe(radio)) {
... create an instance of MarsLander and work with it
} else if (LunarLander.probe(radio)) {
... create an instance of LunarLander and work with it
}
In my application, creating an instance invokes a lot of machinery, so I need to call probe() on a class method before I create an instance of the class.
I looked over Is there a way to make sure classes implementing an Interface implement static methods? and most of the responses were "why would you want to do that?".
I hope this example makes it clear(er). Perhaps there's' a more Java-esque way to remind the developer that a class-visible probe() method is required?
There is no way to require a static method.
But you can create a factory class with non-static methods:
public abstract class LanderFactory<L extends Lander> {
public abstract L createLander();
public abstract boolean probe(Radio radio);
}
You can even have a registry of LanderFactory implementations, so they effectively act as singletons:
public abstract class LanderFactory<L extends Lander> {
private static final Map<Class<? extends Lander>,
LanderFactory<? extends Lander>> registry
= Map.of(MarsLander.class, new MarsLanderFactory(),
LunarLander.class, new LunarLanderFactory());
public static LanderFactory<? extends Lander> getInstance(
Class<? extends Lander> type) {
LanderFactory<? extends Lander> factory = registry.get(type);
if (factory == null) {
throw new IllegalArgumentException("No factory known for " + type);
}
return factory;
}
public abstract L createLander();
public abstract boolean probe(Radio radio);
}
public class MarsLanderFactory extends LanderFactory<MarsLander> {
#Override
public MarsLander createLander() {
return new MarsLander();
}
#Override
public boolean probe(Radio radio) {
// ...
}
}
public class LunarLanderFactory extends LanderFactory<LunarLander> {
#Override
public LunarLander createLander() {
return new LunarLander();
}
#Override
public boolean probe(Radio radio) {
// ...
}
}
"methods that operate on all members of the class"
This is not right. static methods operate on no members of a class.
Use of this is prohibited in static contexts.
I feel your question itself has the answer you are looking for. static abstract doesnt exists because on one hand you want it to behave differently (based on if it is a LunarProbe or a MarsProbe) and on the other hand you want it to be independent of the instance of LunarProbe and MarsProbe. static abstract contradicts itself.
Besides
static boolean probe() {
// ... some MarsLander specific implementation
// what goes here? you dont have access to any instance of this class.
}
static abstract violates a tenet of OOP called polymorphism.
I tried your code(and other things surrounding this), and I'd like to tell you there's a way but I don't think there is.
I would instead recommend using a utility class that supports this static functionality you're looking for.For example, a LanderUtility class that has static methods in it might solve this in a reasonable way.
Mostly though, I don't think of using static methods in that way in Java. The real power in what is going on with this abstract class is that you can count on(somewhat) a certain type of behavior from a child. Notably, for this to matter, the child needs to be instantiated in the first place and you can use a normal, non-static method and have the child implement that instead.
In Java, static methods is allowed to be invoked directly on class references. It does not matter whether it is a abstract class or a normal class.
Due to this reason, static and abstract modifiers can't be used together. Otherwise, what would be the output of this code if the lander method is not implemented ? That's why it is illegal.
Lander.probe();
But, I think we can throw an exception from our super class static method with some hint in the exception message. We can enforce implementation of the static method.
public abstract class Lander {
static boolean probe() {
throw new RuntimeException("Oh oh !!! Why am I here ??");
}
}
public class MarsLander extends Lander {
static boolean probe() {
// ... some MarsLander specific implementation
}
}
public class LunarLander extends Lander {
static boolean probe() {
// ... some LunarLander specific implementation'
}
}
That way, if there is a Lander implementation which has not implemented a static probe method, the probe method will get inherited but this will throw a run time exception.
Methods can't be both abstract and static, because abstract methods have to be overridden, and static methods in Java cannot be overridden. Which class implementation of a static method is used is determined at compile time. You can declare a static method with the same signature in a subclass, but it is not considered overriding because there won’t be any run-time polymorphism. The static method of the superclass is 'masked' in the subclass. If a derived class defines a static method with the same signature as a static method in the base class, the method in the derived class hides the method in the base class.

Why my interface methods cannot be overridden?

I'm trying to implement interface like this :
public interface Human{
void talk();
}
public class Ame implements Human{
public static void talk(){
System.out.println("Speak English");
}
}
public class Chin implements Human{
public static void talk(){
System.out.println("Speak Chinese");
}
}
public class test {
public static void main(String[] args){
Chin c = new Chin();
c.talk();
Ame a = new Ame();
a.talk();
}
}
But it shows errors :Ame and Chin talk() cannot implement Human talk().
Methods is overridden as static .
Please tell me why this heppened and how to fix this error.
Static methods are part of Class and not Objects. Overriding is concept of polymorphism, ie, a method associated with an instance can have multiple behaviour.
Static methods are not associated with instance and polymorphism cannot be applied.
When you declare a method as static, it belongs to the class as a whole and not a specific instance. The methods of an interface cannot be static in Java. When you implement an interface, you are expected to provide an instance method for the abstract methods of the interface. When you use a static method, your static method tries to hide the instance method of the same name. But this would violate the rules to be followed while implementing an interface. Thus we cannot make the interface methods as static in the implementing class.
You cannot reference a non-static interface from a static method this way. In essence, a static method is one that can be accessed directly without recreating a local duplicate object, but its values cannot be modified in the same way. Really, the solution to this problem is quite simple. Remove the static modifier from the overriding talk() methods

What class has access to my methods?

My question today is about creating an object, and what other classes with have access to its methods. I am trying to learn about threading, but since JPanels don't support threads I have gotten all confused.
I create a simplified class like this:
public class MyMethodClass {
public MyMethodClass () {
MyClass myClass = new MyClass();
}
public void MyMethod() {
//do something with the variables
}
}
so I now have a new class object called myClass (MyClass is another class, its content not important). As they are all public, does myClass have access to MyMethod?
If not, is there a way to pass a copy MyMethodClass to myClass so that it can use myMethod, knowing that MyMethodClass created myClass in the first place?
If the class MyClass was a nested class, does it get access to MyMethod?
MyClass will not be able to access methods within MyMethodClass unless it creates an instance of it and in this case, that's a bad idea.
You could could pass MyClass an instance of MyMethodClass via its constructor or a setter method, but you'd actually be better using a common interface, which would decouple the two classes and improve its reusability
Start by defining the contract between the two class (as an interface)...
public interface SomeMethods {
public void MyMethod();
}
Add the ability to pass an implementation of SomeMethods to MyClass via it's constructor or setter method...
public class MyClass {
private SomeMethods someMethods;
public MyClass(SomeMethods someMethods) {
this.someMethods = someMethods;
}
public void someWork() {
someMethods.MyMethod();
}
}
Have MyMethodClass implement the SomeMethods interface and pass a reference of itself to MyClass
public MyMethodsClass implements SomeMethods {
public MyMethodClass () {
MyClass myClass = new MyClass(this);
}
#Override
public void MyMethod() {
//do something with the variables
}
}
Just beware, it's generally not considered a good idea to pass this to other classes or methods from within the constructor, as the state of the object may not be fully realised and some value that the methods/classes rely on may not yet be initialised.

Changing a class variables type

I have two different interfaces which employ the same methods but dont implement or extend each other. These two interfaces are each extended by another class which implements the interfaces methods
I then have a class which is located in a seperate package which calls the interface methods.
So the class has methods which calls the methods of the interfaces, which are all the same.
public void doThis(){
connection.doThis();
}
public void doThat(){
connection.doThat();
}
public void doAnother(){
connection.doAnother();
}
Now, i want to make the variable connection work for both interface1 and interface2.
My idea was to set connection as a class variable
Object connection
and then to change it type to interface1 or interface2 depending on a condition:
if(this){
//condition which converts connection to type interface1
}
else{
//condition which converts connection to type interface2
}
How do i do this. Can i do this?
I have been given an interface which can not be changed, yet does not implement remote. But my project uses RMI. So i created a 2nd interface in a seperate package which implemets Remote. Thus the reason for 2 different interfaces that do he same thing.
I think it would be easier to make the class containing the method 'connection' public, as it would be accessible from all packages.
This seems like a really weird setup, but I won't question you.
If you know the condition at the method call site (eg, the condition is a constant flag passed to the method), you could parameterize the method with a generic instead. For example:
public class TestGenerics {
public static interface A {
public void a();
}
public static interface B {
public void a();
}
public static class C implements A, B {
public void a() {
System.out.println("a");
}
}
public static <T> T getCAsT() {
return (T) new C();
}
public static void main(String[] args) {
A a = TestGenerics.<A>getCAsT();
B b = TestGenerics.<B>getCAsT();
a.a();
b.a();
}
}
Otherwise, I would try to merge the two interfaces in some way.

How to define nested static classes with static methods, inherited from a nested interface in Java?

I have a Java problem with nested classes.
My first class structure looked like this:
public class TopClass {
public void mainMethod() {
// uses the different "method" methods from
// NestedClass-implementing nested classes
}
private interface NestedClass {
public void method();
}
private class NestedClass1 {
public void method() {
}
}
private class NestedClass2 {
public void method(){
}
}
}
But now I want these method() methods to be static because they should be principally.
I cannot make them static without having them in a static class, but that's no problem, I made the classes static, they should be anyway.
It looks like this right now:
public class TopClass {
public void mainMethod() {
// uses the different "method" methods from
// NestedClass-implementing nested classes
}
private static interface NestedClass {
public void method();
}
private static class NestedClass1 {
public static void method() {
}
}
private static class NestedClass2 {
public static void method(){
}
}
}
But then the trouble begins. A static method does not inherit correctly from a non-static interface method, as I get this message This static method cannot hide the instance method from TopClass.NestedClass in Eclipse.
When I make the interface method static, it gives me this error: Illegal modifier for the interface method method; only public & abstract are permitted
So I thought of an abstract class, and tried this:
public class TopClass {
public void mainMethod() {
// uses the different "method" methods from
// NestedClass-implementing nested classes
}
private static abstract class NestedClass {
public static abstract void method();
}
private static class NestedClass1 {
public static void method() {
}
}
private static class NestedClass2 {
public static void method(){
}
}
}
But again, seemingly abstract methods cannot be declared static: The abstract method method in type NestedClass can only set a visibility modifier, one of public or protected.
Leaving the static away (in the abstract class method), errors this on the method methods in the NestedClass1 & 2: This static method cannot hide the instance method from TopClass.NestedClass.
Isn't there any way to declare some kind of superstructure for covering static methods?
EDIT:
The problem I actually try to solve it the lack of possibility of Java for storing references to methods. So instead I have those classes everyone with just one method, but to store them in a List f.e. they must be able to be "caught" by a superstructure.
I got the hint to try anonymous classes or enums, gonna try that now.
Interfaces and statics don't go together. At all. There is no Java support for creating / imposing patterns on static methods.
A static method declaration must always be followed by a definition. It cannot be implemented by subclasses.
I think you're just not approaching your problem right. Try a different approach!
Make NestedClass an interface NestedInterface and store your different implementations as anonymous classes implementing this interface:
public static final NestedInterface firstNested = new NestedInterface() {
#Override
public void method() {
// ...
}
};
Make NestedClass an enumeration NestedEnum and store your different implementations as enumeration values implementing an abstract method from the enumeration. This only works if you have a fixed number of implementations you which to choose from and you do not want to accept NestedClass implementations from outside sources.
public enum NestedEnum {
FIRST {
#Override
public void method() {
// ...
}
};
public abstract void method();
}
EDIT: In reply to your comment:
The classes itself are static as well..
static in the context of a nested class means that this class can be instantiated without an instance of the containing class.
A regular nested class such as in your first example can be instantiated through TopClass.this.new NestedClass1(). Normally you'd simply write new NestedClass1() from within the constructor or an instance method of TopClass, but in this verbose form you can clearly see the dependence on TopClass.this. This can also be seen from any method of NestedClass1, as you have access to the containing class with TopClass.this.
A static nested class such as in your second example can be instantiated through new TopClass.NestedClass1(). Once again, you could just write new NestedClass1() but the verbose form clearly shows that the construction only depends on TopClass and is not associated with an instance of TopClass. You could even create an instance from an outside class using the same snippet new TopClass.NestedClass1() without ever creating a TopClass instance.
I suggest you take a look at this question on inner classes and static nested classes.
The fact the your interface/abstract class is nested is irrelevant to the problem.
You just can't. There is no way in Java to enforce some class to implement static methods. Just cry and surrender and use instance methods.
static abstract is a contradiction. Static methods are not like other languages' class methods. When you make a static method it goes on a single class, it doesn't get inherited by or have its implementation deferred to subclasses.
You don't explain why you want these methods to be static. If you want these methods to be defined by subclasses then they shouldn't be.

Categories