Lambda Expressions for Abstract Classes - java

I have an abstract class with one abstract method. How can I use lambda expressions to instantiate it. It cannot be made into an interface because it extends a class.
public class Concrete<T> {
// Has a bunch of predefined methods.
}
public abstract class Abstract<T> extends Concrete<T> {
public T getSomething();
// Uses inherited methods from Concrete class
}
public class Driver {
public static void main(String[] args) {
System.out.println(new Abstract<String>() {
public String getSomething() {
// Returns something using inherited methods from Abstract
// Class and Concrete Class
}
});
}
}

You cannot directly make a lambda expression target an abstract class, as Sleiman Jneidi pointed out in his answer. However, you can use a workaround:
public class AbstractLambda<T> extends Abstract<T>
{
private final Supplier<? extends T> supplier;
public AbstractLambda(Supplier<? extends T> supplier)
{
this.supplier = supplier;
}
#Override
public T getSomething()
{
return this.supplier.get();
}
}
This can be used with a lambda expression:
Abstract<String> a = new AbstractLambda<>(() -> "Hello World");
System.out.println(a.getSomething()); // prints 'Hello World'
In case your getSomething(...) method has arguments, use a java.util.function.Function or the appropriate interface from the java.util.function package instead of java.util.function.Supplier.
This is also how the java.lang.Thread lets you use a Runnable lambda instead of having to subclass the class:
Thread t = new Thread(() -> System.out.println("Hello World"));
t.start();

No, You can't do it. Lambdas have to target single abstract method (SAM) on interfaces, and they don't work with single abstract method on abstract classes. This how it is, and you have to accept it,
Although it makes sense to have them, the language designers decided that it is not worth the complexity that will be introduced by allowing lambdas on SAM abstract classes.
As a reference, thats what Brian Goetz said about allowing lambdas on SAM abstract class.
Main key-points from Brian's email:
only 3% of the lambda candidate
inner class instances had abstract classes as their target
Complicating the model for the
sake of a few-percent-use-case seemed a bad trade

In the meantime, we now have default implementations in interfaces. I was in a similar situation, tried with an abstract class. Switched to an interface with 2 methods, one of them having a default implementation. Java identifies the interface as having a single abstract method and I can use the lambda syntax for passing implementations of the interface as arguments.
The downside is that someone could override the method which has a default implementation if they really insist, by explicitly implementing the interface in some (anonymous or not) class. And you can't limit that because on interfaces all methods are public. Depending on your situation, that might not be a big deal.

As already pointed out, you can't.
But here another alternative that maybe usefull for somebody:
depending on your design, consider to use an interface with default functions instead of the abstract class:
This abstract class:
public abstract class RandomNumber {
public abstract int createRandom(int smalles, int highest);
public int rollTheDice() {
return createRandom(1, 6);
}
}
as an interface:
public interface RandomNumber {
public int createRandom(int smalles, int highest);
public default int rollTheDice() {
return createRandom(1, 6);
}
}
Now it is possible to write:
RandomNumber rn = (min, max) -> Math.random()*(max-min) + min;

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.

java and multiple inheritance

Can we call this code as multiple inheritance ?
interface Interface {
public int alpha = 0;
public int calculA(int a, int b);
public int calculB(int a, int b);
}
interface InterfaceA extends Interface {
public default int calculA(int a, int b) {
return a + b;
}
}
interface InterfaceB extends Interface {
public default int calculB(int a, int b) {
return a - b;
}
}
class TestInterface implements InterfaceA, InterfaceB {
public TestInterface() {
System.out.println(alpha);
System.out.println(calculA(5, 2));
System.out.println(calculB(5, 2));
}
public static void main(String[] args) {
new TestInterface();
}
}
It look like the default keyword permit to have a multiple inheritance.
It is correct or this concept have an another name ?
Thank's
Edit
It's not a duplicate of Are defaults in JDK 8 a form of multiple inheritance in Java? because this thread talking about the feature called Virtual Extensions.
My question is to ask if my implementation is called multiple inheritance or something else.
java doesn't supports multiple inheritance.
What you are doing is implementing an interface. You can't extend multiple classes in java but you can implement multiple interfaces.
An interface is a reference type and it is similar to class. It is a collection of abstract methods. A class implements an interface, thereby inheriting the abstract methods of the interface. An interface may also contain constants, default methods, static methods, and nested types. Method bodies exist only for default methods and static methods.
A class describes the attributes and behaviors of an object and an interface contains behaviors that a class implements.
For more on interface, click here
Java doesn't support multiple inheritance.
What you have currently done is implement multiple interfaces which is absolutely permittable.

Why its not necessary to have abstract classes to have abstract method [duplicate]

Can have an abstract class implementing all of its methods-- with no abstract methods in it.
Eg.:
public abstract class someClass {
int a;
public someClass (int a) { this.a = a; }
public void m1 () { /* do something */ }
private void m2 () { /* do something else */ }
}
What's the advantage, if any, of having such an abstract class compared to having the same class as a concrete one instead?
One i can think of is that, when i declare it as abstract, it won't be instantiated.
however, i can have the same effect by making it concrete and its constructor(s) private.
TIA.
//==================
EDIT: One other use I can think of:
it may be extending another abstract class or implementing an interface without implementing that class's abstract methods-- although it is implementing all methods of its own. for whatever it' worth.
It has a conceptual meaning: this class has a behaviour which makes no sense on its own.
Granted, it's difficult to imagine such a scenario without well-defined extension points (i.e. abstract methods), but occasionally it will be a reasonably accurate model of your problem.
You can have something like this:
public abstract class ObjectWithId {
private final String id;
public ObjectWithId( String id ) {
this.id = id;
}
public final String getId() {
return id;
}
}
And then you can extend it to declare different types of objects that have ids. Here you have a fully specified and implemented behaviour but no restriction on any other behaviours subclasses may exhibit.
Note though that a much neater way to model the same thing is to use composition instead of inheritance.
public final class ObjectWithId<T> {
private final String id;
private final T ob;
public ObjectWithId( String id, T ob ) {
this.id = id;
this.ob = ob;
}
public String getId() {
return id;
}
public T getObject() {
return ob;
}
}
But before generics were introduced (up to Java version 1.4), this wouldn't have been as elegant and obviously better than the abstract class solution because you'd have had to trade in type safety.
you can declare to implement an interface and don't provide implementation and then each child implicitly gets interface extended
you prevent to create instance of this class
you in future provide common implementation to all children
As you pointed out, you can prevent the class from being instantiated by making it's constructor private. Othere than that, there is no benefit whatsoever. This is probably supported just to provide language completeness.
We generally use Abstraction concept with inheritance
Consider using abstract classes if any of these statements apply to
your situation:
You want to share code among several closely related classes.
To answer your question,
Why declare a class with concrete methods Abstract?
One possible reason is to support inheritance without actually creating objects
Assume you have two classes one Abstract and other Concrete
Abstract class : AbsClass
abstract class AbsClass {
int a = 5;
//Constructor
public AbsClass() {
System.out.println(a);
}
void methodA() {
System.out.println(a + 10);
}
}
and
Concrete class : ConcreteClass
class ConcreteClass {
int a = 10;
//Made the constructor Private to prevent from creating objects of this class
private ConcreteClass() {
System.out.println(a);
}
void methodA() {
System.out.println(a + 10);
}
}
The above two classes should function similarly (?) Until you try to Subclass them
class AbsImplementer extends AbsClass {
//Works fine
}
class ConcImplementer extends ConcreteClass {
//Compilation Error Implicit super constructor ConcreteClass() is not visible
}
The practical difference is that you can't create an instance of it. You would have to subclass it and create an instance of the subclass.
As to WHY you would want to do this, in practice ... I'm hard pressed to think of a good reason. You could say that the class is only meaningful if someone creates a subclass that implements some function. But then why not make that function abstract in the super-class?
I wouldn't rule out the possibility that someone might come up with some example where this makes sense, but I can't think of one. Just because it's possible to write a piece of code and that code compiles successfully doesn't mean that that it makes sense. I mean, I can write "total_price = item_price * zip_code + customer_height_in_cubits - 7.879", but that doesn't mean such a line of code would be meaningful.
Well assume that you don't care whether the methods of the abstract class are implemented or abstract, but by design it has to be abstract so that when someone extends it, they have to add more methods or override the existing ones or use as is. If they don't want to override the methods then the default behavior is already provided in that abstract class.
In this abstract class, the only criteria you enforce is - one simply cannot instantiate that class and they have to have their only version of class before using it.
So in general, abstract class with few or all methods being implemented, is much better than having an interface which has no methods implemented at all. This is based on the assumption that you are using it as a single inheritance.
Consider something similar to the NVI pattern (not sure what you'd call it in Java):
public abstract class A {
public final void doSomething() {
System.out.println("required");
doOptional();
}
protected void doOptional() {
System.out.println("optional");
}
}
public class B extends A {
#Override
protected void doOptional() {
System.out.println("overridden");
}
}
For your public API, you only expose a public final method which cannot be overridden. It performs some required work inside there and an optional method. When extending this class, you can only override doOptional().
Calling B.doSomething() will always print "required" before it proceeds.
Since doOptional() is not abstract, there's no purely code reason that class A needs to be abstract. But it might be desired for your particular project. For example, a base service that is always extended into specific sub-projects.
This can be useful for cases when the classes derived from the abstract base class must have some behaviour that is different from each other but that behaviour can not be abstracted as residing within a method that has the same signature for all the classes. Being unable to share a signature can occur if the different behaviour requires methods that are passed different primitive types. Because they use primitive types you can not use generics to express the similarity.
An abstract base class without any abstract methods is acting a bit like a marker interface, in that it is declaring that implementing classes must provide some behaviour without having that behaviour encapsulated within a new method with a signature that is the same for all implementations. You would use an abstract base class rather than a marker interface when the implementing classes have some behaviour in common, especially if the base class can implement it for the derived classes.
For example:
abstract class Sender {
protected final void beginMessage() {
...
}
protected final void endMessage() {
...
}
protected final void appendToMessage(int x) {
...
}
}
final class LongSender extends Sender {
public void send(int a, int b, int c) {
beginMessage();
appendToMessage(a);
appendToMessage(b);
appendToMessage(c);
endMessage();
}
}
final class ShortSender extends Sender {
public void send(int a) {
beginMessage();
appendToMessage(a);
endMessage();
}
}
It can be useful if you consider it an utility class.

What's the point in having an abstract class with no abstract methods?

Can have an abstract class implementing all of its methods-- with no abstract methods in it.
Eg.:
public abstract class someClass {
int a;
public someClass (int a) { this.a = a; }
public void m1 () { /* do something */ }
private void m2 () { /* do something else */ }
}
What's the advantage, if any, of having such an abstract class compared to having the same class as a concrete one instead?
One i can think of is that, when i declare it as abstract, it won't be instantiated.
however, i can have the same effect by making it concrete and its constructor(s) private.
TIA.
//==================
EDIT: One other use I can think of:
it may be extending another abstract class or implementing an interface without implementing that class's abstract methods-- although it is implementing all methods of its own. for whatever it' worth.
It has a conceptual meaning: this class has a behaviour which makes no sense on its own.
Granted, it's difficult to imagine such a scenario without well-defined extension points (i.e. abstract methods), but occasionally it will be a reasonably accurate model of your problem.
You can have something like this:
public abstract class ObjectWithId {
private final String id;
public ObjectWithId( String id ) {
this.id = id;
}
public final String getId() {
return id;
}
}
And then you can extend it to declare different types of objects that have ids. Here you have a fully specified and implemented behaviour but no restriction on any other behaviours subclasses may exhibit.
Note though that a much neater way to model the same thing is to use composition instead of inheritance.
public final class ObjectWithId<T> {
private final String id;
private final T ob;
public ObjectWithId( String id, T ob ) {
this.id = id;
this.ob = ob;
}
public String getId() {
return id;
}
public T getObject() {
return ob;
}
}
But before generics were introduced (up to Java version 1.4), this wouldn't have been as elegant and obviously better than the abstract class solution because you'd have had to trade in type safety.
you can declare to implement an interface and don't provide implementation and then each child implicitly gets interface extended
you prevent to create instance of this class
you in future provide common implementation to all children
As you pointed out, you can prevent the class from being instantiated by making it's constructor private. Othere than that, there is no benefit whatsoever. This is probably supported just to provide language completeness.
We generally use Abstraction concept with inheritance
Consider using abstract classes if any of these statements apply to
your situation:
You want to share code among several closely related classes.
To answer your question,
Why declare a class with concrete methods Abstract?
One possible reason is to support inheritance without actually creating objects
Assume you have two classes one Abstract and other Concrete
Abstract class : AbsClass
abstract class AbsClass {
int a = 5;
//Constructor
public AbsClass() {
System.out.println(a);
}
void methodA() {
System.out.println(a + 10);
}
}
and
Concrete class : ConcreteClass
class ConcreteClass {
int a = 10;
//Made the constructor Private to prevent from creating objects of this class
private ConcreteClass() {
System.out.println(a);
}
void methodA() {
System.out.println(a + 10);
}
}
The above two classes should function similarly (?) Until you try to Subclass them
class AbsImplementer extends AbsClass {
//Works fine
}
class ConcImplementer extends ConcreteClass {
//Compilation Error Implicit super constructor ConcreteClass() is not visible
}
The practical difference is that you can't create an instance of it. You would have to subclass it and create an instance of the subclass.
As to WHY you would want to do this, in practice ... I'm hard pressed to think of a good reason. You could say that the class is only meaningful if someone creates a subclass that implements some function. But then why not make that function abstract in the super-class?
I wouldn't rule out the possibility that someone might come up with some example where this makes sense, but I can't think of one. Just because it's possible to write a piece of code and that code compiles successfully doesn't mean that that it makes sense. I mean, I can write "total_price = item_price * zip_code + customer_height_in_cubits - 7.879", but that doesn't mean such a line of code would be meaningful.
Well assume that you don't care whether the methods of the abstract class are implemented or abstract, but by design it has to be abstract so that when someone extends it, they have to add more methods or override the existing ones or use as is. If they don't want to override the methods then the default behavior is already provided in that abstract class.
In this abstract class, the only criteria you enforce is - one simply cannot instantiate that class and they have to have their only version of class before using it.
So in general, abstract class with few or all methods being implemented, is much better than having an interface which has no methods implemented at all. This is based on the assumption that you are using it as a single inheritance.
Consider something similar to the NVI pattern (not sure what you'd call it in Java):
public abstract class A {
public final void doSomething() {
System.out.println("required");
doOptional();
}
protected void doOptional() {
System.out.println("optional");
}
}
public class B extends A {
#Override
protected void doOptional() {
System.out.println("overridden");
}
}
For your public API, you only expose a public final method which cannot be overridden. It performs some required work inside there and an optional method. When extending this class, you can only override doOptional().
Calling B.doSomething() will always print "required" before it proceeds.
Since doOptional() is not abstract, there's no purely code reason that class A needs to be abstract. But it might be desired for your particular project. For example, a base service that is always extended into specific sub-projects.
This can be useful for cases when the classes derived from the abstract base class must have some behaviour that is different from each other but that behaviour can not be abstracted as residing within a method that has the same signature for all the classes. Being unable to share a signature can occur if the different behaviour requires methods that are passed different primitive types. Because they use primitive types you can not use generics to express the similarity.
An abstract base class without any abstract methods is acting a bit like a marker interface, in that it is declaring that implementing classes must provide some behaviour without having that behaviour encapsulated within a new method with a signature that is the same for all implementations. You would use an abstract base class rather than a marker interface when the implementing classes have some behaviour in common, especially if the base class can implement it for the derived classes.
For example:
abstract class Sender {
protected final void beginMessage() {
...
}
protected final void endMessage() {
...
}
protected final void appendToMessage(int x) {
...
}
}
final class LongSender extends Sender {
public void send(int a, int b, int c) {
beginMessage();
appendToMessage(a);
appendToMessage(b);
appendToMessage(c);
endMessage();
}
}
final class ShortSender extends Sender {
public void send(int a) {
beginMessage();
appendToMessage(a);
endMessage();
}
}
It can be useful if you consider it an utility class.

Same method with different return types in abstract class and interface

Just extending the question..
Same method in abstract class and interface
Suppose a class implements an interface and extends an abstract class and both have the same method (name+signature), but different return types. Now when i override the method it compiles only when i make the return type same as that of the interface declaration.
Also, what would happen if the method is declared as private or final in the abstract class or the interface?
**On a side note. Mr. Einstein stuck to this question for an abominable amount of time during an interview. Is there a popular scenario where we do this or he was just showing off?
If the method in abstract class is abstract too, you will have to provide its implementation in the first concrete class it extends. Additionally, you will have to provide implementation of interface. If both the methods differ only in return type, the concrete class will have overloaded methods which differ only in return type. And we can't have overloaded methods which differ only in return type, hence the error.
interface io {
public void show();
}
abstract class Demo {
abstract int show();
}
class Test extends Demo implements io {
void show () { //Overloaded method based on return type, Error
}
int show() { //Error
return 1;
}
public static void main (String args[]) {
}
}
No, same method names and parameters, but different return types is not possible in Java. The underlying Java type system is not able* to determine differences between calls to the methods at runtime.
(*I am sure someone will prove me wrong, but most likely the solution is considered bad style anyways.)
Regarding private/final: Since you have to implement those methods, neither the interface method nor the abstract method can be final. Interface methods are public by default. The abstract method can't be private, since it must be visible in the implementing class, otherwise you can never fulfill the method implementation, because your implementing class can't "see" the method.
With Interfaces the methods are abstract and public by default ,
so they cant have any other access specifier and they cant be final
With abstract class , abstract methods can have any access specifier other than private and because they are abstract they cant be final
While overriding , the method signature has to be same ; and covariant(subclass of the declared return type) return types are allowed
A class cannot implement two interfaces that have methods with same name but different return type. It will give compile time error.
Methods inside interface are by default public abstract they don't have any other specifier.
interface A
{
public void a();
}
interface B
{
public int a();
}
class C implements A,B
{
public void a() // error
{
//implementation
}
public int a() // error
{
//implementation
}
public static void main(String args[])
{
}
}

Categories