I saw the following code in a tutorial. My question is why the interface Drawable is not implemented by the class LambdaExpressionExample2? I am familiar with composition between classes. Is that the case here as well ? Thank you.
#FunctionalInterface //It is optional
interface Drawable{
public void draw();
}
public class LambdaExpressionExample2 {
public static void main(String[] args) {
int width=10;
//with lambda
Drawable d2=()->{
System.out.println("Drawing "+width);
};
d2.draw();
}
}
You can implement in main class also:
public class LambdaExpressionExample2 implements Drawable{
#Override
public void draw() {
System.out.println("Implemented it in main class !!!");
}
public static void main(String[] args) {
LambdaExpressionExample2 lm = new LambdaExpressionExample2();
lm.draw();
}
}
But that won't be lambda.
Or you can define another implementation like :
public class DrawableImpl implements Drawable {
#Override
public void draw() {
System.out.println("I have implemented Drawable !!!");
}
}
public class LambdaExpressionExample2{
public static void main(String[] args) {
DrawableImpl dm = new DrawableImpl();
dm.draw();
}
}
But that is also not lambda.
You can also use anonymous class as below (old style):
public class LambdaExpressionExample2 {
public static void main(String[] args) {
Drawable anonymus_class = new Drawable() {
#Override
public void draw() {
System.out.println("Anonymus class");
}
};
anonymus_class.draw();
}
}
If you compare all, you will see lambda notation is most precise and intuitive.
The interface is used for the lambda function itself, not the LambdaExpressionExample2 class.
To see what I mean let's have a look at other ways you could achieve this functionality.
Instead of using a lambda, you could use an anonymous inner class. Before lambda functions became a thing in Java 8, this is how you would have had to do it.
public static void main(String[] args) {
int width=10;
// with anonymous inner class
Drawable d1 = new Drawable() {
#Override
public void draw() {
System.out.println("Anonymous Class: Drawing " + width);
}
};
d1.draw();
}
Here you can see the anonymous class is implementing the Drawable interface, by providing an implementation for the draw method.
We could use a concrete class that implements the Drawable interface
#FunctionalInterface
interface Drawable{
public void draw();
}
class ConcreteDrawable implements Drawable {
#Override
public void draw() {
System.out.println("Concrete Class: Drawing");
}
}
public class LambdaExpressionExample2 {
public static void main(String[] args) {
// with concrete class
Drawable d1 = new ConcreteDrawable();
d1.draw();
}
}
In this example, we no longer have access to the local width variable in the draw method. But you can see that the ConcreteDrawable class also provides an implementation of the Drawable interface.
Or finally we can use a lambda function.
public static void main(String[] args) {
int width = 10;
// with lambda
Drawable d1 = () -> { System.out.println("Lambda: Drawing " + width); };
d1.draw();
}
Here the lambda function is implementing the Drawable interface, by giving an implementation of the draw method. The only reason why we can use a lambda function here is that the Drawable interface only declares one method.
So in summary, it is not the LambdaExpressionExample2 class that should implement Drawable but instead the lambda function itself.
Related
interface Interface {
void m1();
}
class Child implements Interface {
public void m1() {
System.out.println("Child.....");
}
}
public class InterfaceDemo {
public static void main(String[] args) {
Child c = new Child();
c.m1();
Interface i = new Child();
i.m1();
}
}
This is useful when you have several classes implementing same interface. It allows to use polymorphism. You can also use abstract classes to implement some common functionality. And starting Java 8 you can provide default implementation in interfaces themselves.
interface Shape {
void draw();
double getSquare();
}
class Circle implements Shape {
public void draw() {}
public double getSquare() {return 4 * PI * r * r;}
}
class Square implements Shape {
public void draw() {}
public double getSquare() {return w * w;}
}
class Main {
public static void main(String[] args) {
for (Shape s : Arrays.asList(new Circle(), new Square(), new Square(), new Circle())) {
s.draw(); //draw a shape. In this case it doesn't matter what exact shapes are in collection since it is possible to call interface method
}
}
}
In this class abstract class object is instantiated by overriding the getNum(), what is the purpose of this?
public abstract class AbstractTest {
public int getNum() {
return 45;
}
public static void main(String[] args) // main function
{
AbstractTest t = new AbstractTest() // From this point didn't understand
{
public int getNum() // function
{
return 22;
}
}; //use of this
System.out.println(t.getNum()); // output
}
}
The instantiation in your main() method is simply an inline class definition of a concrete instance of the abstract class AbstractTest. To be clear, the variable t is an anonymous, non abstract class instance. The following code would achieve the same thing:
public class ConcreteTest extends AbstractTest {
#Override
public int getNum() {
return 22;
}
}
public static void main (String [] args) {
ConcreteTest t = new ConcreteTest();
System.out.println(t.getNum());
}
There are instances in the course of development where it can be cumbersome to have to create a formal class definition. For example, if you only need a single instance of the abstract AbstractTest class, it would be easier to use an inline definition.
We call this 'Anonymous Class': When you need to create and use a class, but do not need to give its name or reused use, you can use an anonymous class. Here is the offical doc. Not only used for abstract class, can also be used for interface and general extensible class.
interface Base {
void print();
}
public static void main(String[] args) {
Base aInterface = new Base() {
#Override
public void print() {
System.out.println("A anonymous implement.");
}
};
Thread aThread = new Thread() {
#Override
public void run() {
super.run();
}
};
}
interface Y {
void search(String name);
}
class A implements Y {
void search(String name) {
//Is it possible to say: "If I was called from class B then do a search("B");
}
}
class B extends A {
}
public class Main {
public static void main(String[] args) {
B b = new B();
b.search();
}
}
Given the above code is it possible to reason in superclass which subclass was used for calling a method?
The reason I want to do this is because the code in Search is very similar for all Subclasses, the only thing that changes is the Classname, so I thought there is no need to Override in each subclass. I have updated the code to reflect this. Please let me know if there is a better way of doing it/
Calling this.getClass() inside your search method will give you the concrete class of the current instance.
For example:
class Example
{
static class A {
public void search() {
System.out.println(getClass());
}
}
static class B extends A {}
public static void main (String[] args) throws java.lang.Exception
{
new A().search();
new B().search();
}
}
outputs
class Example$A
class Example$B
The cleanest way to do it is to override the method in each subclass.
interface Y {
void search();
}
class A implements Y {
public void search(){
search("A");
}
protected void search(String name) {
// implement your searching algoithm here
}
}
class B extends A {
public void search(){
search("B");
}
}
public class Main {
public static void main(String[] args) {
B b = new B();
b.search();
}
}
That's the way inheritance is suppose to works. A super class should not know its subclasses.
And, in case you extends your class B, you can easily either:
-Keep the same behaviour as B:
class C extends B {
// do nothing, when calling search, it calls the method implemented in B
}
-Change the behaviour to search for "C"
class C extends B {
public void search(){
search("C"); // or search("whateveryouwant")
}
}
You can simply override the method in class B.
The other way could be to write the search() method as
void search() {
if (this.getClass().equals(B.class)) {
//The logic for B
} else if (this.getClass().equals(A.class)) {
//The logic for A
}
}
You have to provide the fully qualified name for the class.
Better follow template pattern.
interface Y {
void search(String name);
}
abstract class AbstractionTemplate implements Y{
#Override
public void search(String name) {
//a lot of code.
System.out.println("common stuff start");
doImplspecificStuffOnly();
System.out.println("common stuff end");
//a lot of code.
}
abstract void doImplspecificStuffOnly();
}
class A extends AbstractionTemplate{
#Override
void doImplspecificStuffOnly() {
System.out.println("a's stuff");
}
}
class B extends A {
#Override
void doImplspecificStuffOnly() {
System.out.println("B's stuff");
}
}
public class Main {
public static void main(String[] args) {
B b = new B();
b.search("hey");
}
}
Can Someone tell me with an example why an class should be defined inside an interface.
The below is the simple code i was trying.
interface Watsapp
{
class A
{
public void Validate()
{
}
};
abstract public void SendText();
public void SendPic();
};
its totally depends on logic requirements.
whenever we declare inner class, it treats as a data member so here also you can treat this class as a data member
just assume scenario some one needs object of A inside Interface and there is no class right now.
see eg.
public interface Watsapp
{
class A
{
public void Validate()
{
}
public String iDoSomething()
{
return "i did";
}
};
public A objOfA = new A();
abstract public void SendText();
public void SendPic();
};
And main Class is bellow:
public class TestMain {
public static void main(String[] str){
System.out.println( Watsapp.objOfA.iDoSomething());
}
}
mostly people create anonymous class for one time use, but here You created a class with name.
see:
public interface Watsapp
{
/*class A
{
public void Validate()
{
}
public String iDoSomething()
{
return "i did";
}
};*/
Thread t = new Thread()
{
public void run() {
// something ...
}
};
abstract public void SendText();
public void SendPic();
};
Thank you.
wondering how it is possible to call public m method?
public class Test1 {
public static void main(String[] args) {
Test1 test = new Test1() {
public void m() {
System.out.println("m");
}
};
}
}
I don't believe you can. You'd have to create an interface or subclass. (Well, okay, that's probably not true. You could probably do it with reflection.)
E.g., like this (where you call it via test.m() after construction):
public class Test1 {
public static void main(String[] args) {
SubTest1 test = new SubTest1() {
public void m() {
System.out.println("m");
}
};
test.m();
}
private static abstract class SubTest1 extends Test1 {
public abstract void m();
}
}
Or like this, where it happens during construction:
public class Test1 {
public static void main(String[] args) {
SubTest1 test = new SubTest1() {
public void m() {
System.out.println("m");
}
};
}
private static abstract class SubTest1 extends Test1 {
public SubTest1() {
this.m();
}
public abstract void m();
}
}
You can't define an anonymous class constructor, so that last uses the constructor of the SubTest1 class and the abstract method.
You cannot directly invoke m since test is of type Test1 which does not contain a method called m, but you should never find yourself in a situation like this. The whole point of anonymous classes is to alter some already-existent aspect of the base class's functionality, so adding new methods makes no sense. Consider rethinking your design or using a named class instead.
Of course, if you won't care about test in the future you could do this:
new Test1() {
public void m() {
System.out.println("m");
}
}.m();
Although you would rarely want to do something like this, it could be useful if you're working with Thread or Runnable and need to invoke the run method.
If Test1 had a method called "m" you could just call test.m() after you instantiated the inner class:
public class Test1 {
public static void main(String[] args) {
Test1 test = new Test1() {
public void m() {
System.out.println("New Behavior");
}
};
test.m();
}
public void m() {
System.out.println ("Default Behavior");
}
}
Running this would output:
New Behavior