method implemented in abstract class, but appears in interface - java

I'm learning abstract classes vs interfaces at the moment and trying to figure out situations where to use one over the other. I'm having trouble figuring out this example at the moment:
public interface Face {
public void test();
}
public abstract class Tract {
public void test() {
System.out.println("over here");
}
}
public class Thing extends Tract implements Face {
public void test() {
// what should print out?
}
}
Here, the test() function is implemented in the abstract class. If you don't implement it in the subclass, would it call the abstract class' method and print out "over here"? Does the interface accept implementations from an ancestor class or do you have to implement it in the subclass, therefore overriding the abstract class implementation?

All the interface cares about is that the class has implemented a method called test() that returns void. It does not matter whether the method is implemented in the class directly or in any ancestor (parent) class.
In your case, the Thing class has inherited its definition of test() from Tract, and therefore implements the Face interface without you having to provide a definition explicitly.

In the class "Tract" you have given an implementation for the method coming from the interface. Also you override it in "Thing" class so when calling this method on a Thing instance then this version(Thing version) is going to be called.

All java methods are virtual.
lets consider little bit modified code,
I hope, you will get the idea:
public interface Face {
public void test();
}
public abstract class Tract {
public void test() {
System.out.println("Tract here");
}
}
public class Thing extends Tract implements Face {
public void test() {
System.out.println("Thing here");
}
}
public class Thing2 extends Tract implements Face {
}
lets go to output:
Tract tr = new Tract();
tr.test();
will not compile because you can't instantiate abstract class.
Thing th = new Thing();
th.test();
will print "Thing here"
Thing2 th2 = new Thing2();
th2.test();
will print "Tract here",
because you not overwritten the test() method in abstract class.
Main idea of this approach - you can abstract implementation in the future use
class C {
void print(Face face) {
face.test();
}
}
new C(new Thing()).print();
will print "Thing here";
new C(new Thing2()).print();
will print "Tract here";
You can hide different implementations
But this is not main idea of abstract classes.
main idea abstract classes are:
public interface Face {
public void test();
}
public abstract class Abstract {
abstract public void test();
}
public class Thing1 extends Abstract implements Face {
public void test() {
System.out.println("Thing1 here");
}
}
public class Thing2 extends Abstract implements Face {
public void test() {
System.out.println("Thing2 here");
}
}
main idea - you can declare method without implementation
new C(new Thing1()).print();
will print "Thing1 here";
new C(new Thing2()).print();
will print "Thing2 here";
main idea - you declare the method in abstract class, that you MUST override to compile code.
I hope, this is enough explained answer.

Related

Issue with multiple Interface implementation in Java8 [duplicate]

Two interfaces with same method names and signatures. But implemented by a single class then how the compiler will identify the which method is for which interface?
Ex:
interface A{
int f();
}
interface B{
int f();
}
class Test implements A, B{
public static void main(String... args) throws Exception{
}
#Override
public int f() { // from which interface A or B
return 0;
}
}
If a type implements two interfaces, and each interface define a method that has identical signature, then in effect there is only one method, and they are not distinguishable. If, say, the two methods have conflicting return types, then it will be a compilation error. This is the general rule of inheritance, method overriding, hiding, and declarations, and applies also to possible conflicts not only between 2 inherited interface methods, but also an interface and a super class method, or even just conflicts due to type erasure of generics.
Compatibility example
Here's an example where you have an interface Gift, which has a present() method (as in, presenting gifts), and also an interface Guest, which also has a present() method (as in, the guest is present and not absent).
Presentable johnny is both a Gift and a Guest.
public class InterfaceTest {
interface Gift { void present(); }
interface Guest { void present(); }
interface Presentable extends Gift, Guest { }
public static void main(String[] args) {
Presentable johnny = new Presentable() {
#Override public void present() {
System.out.println("Heeeereee's Johnny!!!");
}
};
johnny.present(); // "Heeeereee's Johnny!!!"
((Gift) johnny).present(); // "Heeeereee's Johnny!!!"
((Guest) johnny).present(); // "Heeeereee's Johnny!!!"
Gift johnnyAsGift = (Gift) johnny;
johnnyAsGift.present(); // "Heeeereee's Johnny!!!"
Guest johnnyAsGuest = (Guest) johnny;
johnnyAsGuest.present(); // "Heeeereee's Johnny!!!"
}
}
The above snippet compiles and runs.
Note that there is only one #Override necessary!!!. This is because Gift.present() and Guest.present() are "#Override-equivalent" (JLS 8.4.2).
Thus, johnny only has one implementation of present(), and it doesn't matter how you treat johnny, whether as a Gift or as a Guest, there is only one method to invoke.
Incompatibility example
Here's an example where the two inherited methods are NOT #Override-equivalent:
public class InterfaceTest {
interface Gift { void present(); }
interface Guest { boolean present(); }
interface Presentable extends Gift, Guest { } // DOES NOT COMPILE!!!
// "types InterfaceTest.Guest and InterfaceTest.Gift are incompatible;
// both define present(), but with unrelated return types"
}
This further reiterates that inheriting members from an interface must obey the general rule of member declarations. Here we have Gift and Guest define present() with incompatible return types: one void the other boolean. For the same reason that you can't an void present() and a boolean present() in one type, this example results in a compilation error.
Summary
You can inherit methods that are #Override-equivalent, subject to the usual requirements of method overriding and hiding. Since they ARE #Override-equivalent, effectively there is only one method to implement, and thus there's nothing to distinguish/select from.
The compiler does not have to identify which method is for which interface, because once they are determined to be #Override-equivalent, they're the same method.
Resolving potential incompatibilities may be a tricky task, but that's another issue altogether.
References
JLS 8.4.2 Method Signature
JLS 8.4.8 Inheritance, Overriding, and Hiding
JLS 8.4.8.3 Requirements in Overriding and Hiding
JLS 8.4.8.4 Inheriting Methods with Override-Equivalent Signatures
"It is possible for a class to inherit multiple methods with override-equivalent signatures."
This was marked as a duplicate to this question https://stackoverflow.com/questions/24401064/understanding-and-solving-the-diamond-problems-in-java
You need Java 8 to get a multiple inheritance problem, but it is still not a diamon problem as such.
interface A {
default void hi() { System.out.println("A"); }
}
interface B {
default void hi() { System.out.println("B"); }
}
class AB implements A, B { // won't compile
}
new AB().hi(); // won't compile.
As JB Nizet comments you can fix this my overriding.
class AB implements A, B {
public void hi() { A.super.hi(); }
}
However, you don't have a problem with
interface D extends A { }
interface E extends A { }
interface F extends A {
default void hi() { System.out.println("F"); }
}
class DE implement D, E { }
new DE().hi(); // prints A
class DEF implement D, E, F { }
new DEF().hi(); // prints F as it is closer in the heirarchy than A.
As far as the compiler is concerned, those two methods are identical. There will be one implementation of both.
This isn't a problem if the two methods are effectively identical, in that they should have the same implementation. If they are contractually different (as per the documentation for each interface), you'll be in trouble.
There is nothing to identify. Interfaces only proscribe a method name and signature. If both interfaces have a method of exactly the same name and signature, the implementing class can implement both interface methods with a single concrete method.
However, if the semantic contracts of the two interface method are contradicting, you've pretty much lost; you cannot implement both interfaces in a single class then.
Well if they are both the same it doesn't matter. It implements both of them with a single concrete method per interface method.
As in interface,we are just declaring methods,concrete class which implements these both interfaces understands is that there is only one method(as you described both have same name in return type). so there should not be an issue with it.You will be able to define that method in concrete class.
But when two interface have a method with the same name but different return type and you implement two methods in concrete class:
Please look at below code:
public interface InterfaceA {
public void print();
}
public interface InterfaceB {
public int print();
}
public class ClassAB implements InterfaceA, InterfaceB {
public void print()
{
System.out.println("Inside InterfaceA");
}
public int print()
{
System.out.println("Inside InterfaceB");
return 5;
}
}
when compiler gets method "public void print()" it first looks in InterfaceA and it gets it.But still it gives compile time error that return type is not compatible with method of InterfaceB.
So it goes haywire for compiler.
In this way, you will not be able to implement two interface having a method of same name but different return type.
Try implementing the interface as anonymous.
public class MyClass extends MySuperClass implements MyInterface{
MyInterface myInterface = new MyInterface(){
/* Overrided method from interface */
#override
public void method1(){
}
};
/* Overrided method from superclass*/
#override
public void method1(){
}
}
The following two approaches can also be taken to implement both the duplicate methods and avoid ambiguity -
APPROACH 1:
App.java -
public class App {
public static void main(String[] args) {
TestInterface1 testInterface1 = new TestInterface1();
TestInterface2 testInterface2 = new TestInterface2();
testInterface1.draw();
testInterface2.draw();
}
}
TestInterface1.java -
public class TestInterface1 implements Circle {
}
TestInterface2.java -
public class TestInterface2 implements Rectangle {
}
Circle.java -
public interface Circle extends Drawable {
#Override
default void draw() {
System.out.println("Drawing circle");
}
}
Rectangle.java -
public interface Rectangle extends Drawable {
#Override
default void draw() {
System.out.println("Drawing rectangle");
}
}
Drawable.java -
public interface Drawable {
default void draw() {
System.out.println("Drawing");
}
}
Output -
Drawing circle
Drawing rectangle
APPROACH 2:
App.java -
public class App {
public static void main(String[] args) {
Circle circle = new Circle() {
};
Rectangle rectangle = new Rectangle() {
};
circle.draw();
rectangle.draw();
}
}
Circle.java -
public interface Circle extends Drawable {
#Override
default void draw() {
System.out.println("Drawing circle");
}
}
Rectangle.java -
public interface Rectangle extends Drawable {
#Override
default void draw() {
System.out.println("Drawing rectangle");
}
}
Drawable.java -
public interface Drawable {
default void draw() {
System.out.println("Drawing");
}
}
Output -
Drawing circle
Drawing rectangle

Can we create instantiation of interface and abstract class with the help of anonymous class in Java?

I went to an interview. Interviewer asked me if one can instantiate an interface and abstract class? As per my knowledge I said "No". But he said "Yes, we can with the help of an anonymous class".
Can you please explain to me how?
This was a trick questions.
No you can not instantiate an interface or abstract class.
But you can instantiate an anonymous class that implements/extends the interface or abstract class without defining a class object. But it is just a shortcut to defining a fully named class.
So I would say technically your answer was correct.
I don't know what is "instantiation of interface and abstract class".
I think it's an inaccurate, improper expression of something,
we can only guess at the intended meaning.
You cannot create an instance of an interface or an abstract class in Java.
But you can create anonymous classes that implement an interface or an abstract class.
These won't be instances of the interface or the abstract class.
They will be instance of the anonymous class.
Here's an example iterator from the Iterator interface that gives you an infinity of "not really":
new Iterator<String>() {
#Override
public boolean hasNext() {
return true;
}
#Override
public String next() {
return "not really";
}
};
Or a funky AbstractList that contains 5 "not really":
List<String> list = new AbstractList<String>() {
#Override
public int size() {
return 5;
}
#Override
public String get(int index) {
return "yes";
}
};
Assume you have an abstract class: MyAbstractClass with abstract void method myAbstractMethod. Then you can make an "instance" of this class via this code:
MyAbstractClass myAbstractClassInstance = new MyAbstractClass() {
public void myAbstractMethod() {
// add abstract method implementation here
}
};
myAbstractClassInstance extends your MyAbstractClass in this case. When you instantiate this class you have to implement all abstract methods as you can see from the code above.
The same way works for interfaces, assume you have an interface MyInterface with a void method myInterfaceMethod inside, then you can create an "instance" (implementation of this instance) via this code:
MyInterface myInterfaceImpl = new MyInterface() {
public void myInterfaceMethod() {
// add method implementation here
}
}
myInterfaceImpl is an implemetation of MyInterface in this case. When you create an object using interface, you have to implement interface methods as it is shown above.
Interface :
interface Interface1 {
public void m1();
}
When you right
new Interface1() {
public void m1() {
}
}
Its not actually creating the instance of Interface. Its creating an instance of its subtype which doesnt have any name/reference. Hence we cannot create an instance of interface or abstract class
You cannot create instances of abstract classes or interfaces using the new operator. For example,
new AbstractSet(); // That's wrong.
You can, however, use them to declare reference variables. For example, You can do this:
AbstractSet set;
You can instantiate anonymous as well as declared implementing classes or subclass.
For example, Set extends AbstractSet, so you can instantiate Set.
Yes, we can create by having defining the abstract methods or the interface methods on the fly during instantiation. That's like a Named anonymous class.
//interface
Runnable r = new Runnable(){
public void run() {
System.out.println("Here we go");
}
};
//Abstract class
abstract class MyAbstract {
abstract void run();
}
MyAbstract ab = new MyAbstract(){
#Override
void run() {
System.out.println("Here we go");
}};

implement an abstract method in derived class as static

I have these 2 classes
class A {
public void foo1() {
...;
foo2();
...;
}
protected abstract foo2();
}
class B extends A {
public foo2() {
......
}
I need foo2 to be static so I can do B.foo2() but I also want the functionality in class A to remain.n
Any suggestions?
}
You can't override static methods or implement abstract methods as static.
Static methods are defined on a class definition, not on a class instance. Abstract methods are defined on a class instance.
What you said doesn't make sense in fact.
Although I don't quite get why you need to do it, there is a workaround:
class B {
#Override
public void foo() {
fooUtil();
}
public static void fooUtil() {
// your impl here
}
}
Then you can do B.fooUtil() instead, and using its behavior to override A.foo().

Declaring an Interface and implementing in classes in an abstract class Java

I am doing an exercise, the book is not helping me grasp the concept, neither are the online resources. This may seem really silly but I don't know what I'm missing!!! I am quite new to Java and have had a look at other examples on stack but to no avail :s I need to declare 3 interfaces. Each interface needs to declare a method with the same name as its interface. Then the abstract class is extended by 3 classes which implement the aforementioned interfaces.Each class needs to be instantiated. If anyone could explain the procedure to this I would be eternally grateful.
interface antiLockBrakes{
public void antiLockBrakes();
}
interface cruiseControl{
public void cruiseControl();
}
interface powerSteering{
public void powerSteering();
}
public abstract class Auto{
abstract class Model1 extends Auto implements antiLockBrakes{
public abstract void antiLockBrakes();
Model1 mod1 = new Model1();
mod1.antiLockBrakes();
}
public static void main(String[] args){
}
}
this is your question: someone to explain how exactly to declare and interface and then have it implemented in the abstract class right??
Here's the answer for it.
See lets consider I have an interface
interface someInterface{
public void someMethod();
}
Now to implement the someInterface in abstract class
public abstract class SomeClass implements someInterface{
public void someMethod(){
System.out.println("Inside someMethod");
}
public abstract myMethod();
}
See in the class SomeClass we have implemented interface by giving definition to method someMethod() and since we want this SomeClass to be a abstract class we have defined one abstract method myMethod() for it.
Now any class which extends from SomeClass will also implement interface someInterface implicitly (because SomeClass has implemented it) and if it want its own definition for someMethod() it can override it. But if a child class wants to be a concrete class ( a class in which all its method will have implementation) then it has to provide implementation for abstract method myMethod().
HTH:)
this is what I like to use to see the difference between abstract classes and interface classes
interface class
//I say all motor vehicles should look like that :
interface MotorVehicle {
void run();
int getFuel();
}
// my team mate complies and write vehicle looking that way
class Car implements MotorVehicle {
int fuel;
public void run() {
System.out.println("Wrroooooooom");
}
public int getFuel() {
return this.fuel;
}
}
abstract class
// I say all motor vehicles should look like that :
abstract class MotorVehicle2 {
int fuel;
// they ALL have fuel, so why let others implement that ?
// let's make it for everybody
int getFuel() {
return this.fuel;
}
// that can be very different, force them to provide their
// implementation
abstract void run();
}
// my team mate complies and write vehicle looking that way
class Car2 extends MotorVehicle2 {
void run() {
System.out.println("Wrroooooooom");
}
}

concrete class method keeps throwing an exception from abstract class despite implementation

I have an abstract class Automobile which has an unimplemented method called move
so
public abstract class Automobile {
public void move() {
throw new UnsupportedOperationException();
}
}
I have a concrete class which extends my abstract class and implements the move method.My problem is the method keeps throwing an UnsupportedOperationException
public class Car extends Automobile{
int x;
public void move(){
x++;
}
}
It could be for many reasons in your concrete class: maybe your concrete doesn't actually extends Foo? Or maybe it calls super.move() somewhere in its body.
Instead of throwing an exception, the correct way is to define the class and method as abstract to force subclasses to override it.
public abstract class Foo {
public abstract void move();
}
Please note if Foo only has abstract methods, like in the example above, that's an interface that you want, not an abstract class. Also, you should name it to define a behaviour
public interface Moving {
void move();
}
And then:
public class MovingObject implements Moving {
....
#Override
public void move() {
// your implementation
}
....
}
Are you calling super.move() in your implementation class? Eclipse generates that call by default if you used Source->Override/Implement Methods...
Otherwise I think, that you did not override the method correctly.

Categories