I am new in Functional Interface and today i am learning from few of tutorial sites. I have a question plz provide your suggestions and guide me.
Below mentioned code have an question for me.
#FunctionalInterface
interface Demo {
Object clone(); // protected
//int hashCode(); // public
//boolean equals(Object c); // public
//public void wait(); // final so we cannot override this one.
}
Object class is parent for all java classes.
Here wait() method says not overrided because this one is final. So it means Demo interface also child of Object class (in general terms).
> #FunctionalInterface means interface with exact one method declaration.
Question: So, Now code is working when Object clone(); method is not commented. So means this method is declared in interface Demo. But when we click on its implementation we move on Object class's clone() method.
When we comment clone() method and un-comment equals() method, then we get compile time error, interface is not FunctionalInterface. Why ?????? and why its functional interface with clone() method.
Please don't say clone() is protected, what's the matter if clone is protected in Object class. Please explain for me.
Thanks,
sawai
It's because clone() is protected. I know you asked me not to say that, but I'm going to say it anyway because it's the answer.
http://docs.oracle.com/javase/specs/jls/se8/html/jls-9.html#jls-9.8 specifically says:
For an interface I, let M be the set of abstract methods that are
members of I that do not have the same signature as any public
instance method of the class Object. Then, I is a functional interface
if there exists a method m in M for which both of the following are
true:
The signature of m is a subsignature (§8.4.2) of every method's
signature in M.
m is return-type-substitutable (§8.4.5) for every method in M.
Note that it says public instance. When you've uncommented clone(), this is a method that does not have the same signature as a public instance method, because clone() in Object is a protected instance method. Thus, your clone() method will satisfy the conditions. You can't say the same about equals(), since equals() is a public instance method in Object. That means that the set M referred to by this rule is empty, and therefore the method m that must be in this set cannot exist.
There's a comment in the JLS a couple paragraphs down which explains why they decided to treat clone() differently.
Since public boolean equals(Object c) already exists in Object, Demo doesn't declare any new method. To be a FunctionalInterface, it should declare only one method.
When instead you declare public Object clone(), it is a new method because the original one in Object is protected. Therefore it can be considered as a FunctionalInterface.
Related
I'm new to Java Programming and learning polymorphism.
__EDIT__
As per the answers I received from everyone,I have code:
Here I'm typecasting my Derived object (obj) to Base type and then calling method().
public class Tester {
public static void main(String[] args) {
Base obj=(Base)new Derived();
obj.method();
}
}
class Base{
public void method(){
System.out.println("In Base");
}
}
class Derived extends Base{
public void method(){
System.out.println("In Derived");
}
}
Output I'm getting is: "In Derived".
So after typecasting my object should become of type Base referenced by Base type.
But it's not happening? Why?
Does typecast work on child->parent conversion or it has no effect here?
Base obj=new Derived();
In the above statement, the reference part points to type Base. This is how the compiler identifies which class to consider. But your code will create an error. Let me explain the structure of the above statement before explaining why will it show an error.
Structure of the above statement:
Declaration-The reference part is Base obj.
Instantiation: The new keyword is a Java operator that creates the object/allocates space in the memory.
Initialization: The new operator is followed by a call to a constructor, which initializes the new object.
Since, Derived is a sub-class of Base, you are allowed to call the constructor in the Derived class. This is how inheritance and polymorphism works.
Okay, Now let us go back to the error part.
The obj.method() in your code is looking for a function method() in Base class but the method(int a) function in Base class requires an argument of type integer to be passed. So for the code to work, the calling statement has to be something like obj.method(5).This statement works because the calling statement is actually passing 5 to the function.
There is an easy fix for your code:
Derived obj=new Derived();
Have you noticed?
I have relaced the reference to type Derived.
Why does that work?
Because there is method() function in your Derived class which doesn't require an integer argument.
There is one more amazing fact about inheritance in Java:
Everything possessed by a super-class is also possessed by the sub-class but the reverse is not true. And yes, the sub-class has the right to redefine any method/function it has inherited from super-class.
The above statement means the following code will work:
Derived obj=new Derived();
obj.method(5);
You must be wondering-How come this code works even though method() in Derived requires no argument. In fact, Derived has no method(int a).
Well, the answer to this is the amazing fact I have mentioned above.
Yes, method(int a) also belongs to Derived since it's a sub-class of Base.
But How does the code mentioned below work?
Derived obj=new Derived();
obj.method(5);
Simple, the JVM looks for the method(int a) in class Derived and it finds the function since Derived has inherited the function from Base class.
Remember this too, the sub-class also has a privilege to over-ride a method in super class. This means that you can add method(int a) function in class Derived which over-rides the original method inherited from Base.
How inheritance works?
When you call obj.method(5) in the above code, the JVM first looks for any over-ridden method of the same type in Derived. If it does not find any over-ridden method, it moves up in the inheritance hierarchy chain to the super class and looks for the same method. But the reverse is not the true.
how does compiler comes to know which method is to be called & too from which class?
The compiler searches for the method in the class (in this case Base) of the object (in this case obj). If the method is not found in that class, then it looks for the method in the super class (in this case Object). If still not found, it flags an error.
Is it that compiler checks the reference type class & if method to be invoked is not present in reference type class it gives error??
Yes. But, as said before, If the method is not found in that class, then it looks for the method in the super class (in this case Object). If still not found, it flags an error.
Your obj.method() will fail, because Base does not have a method with the signature method() (it has method(int))
If your obj was of type Derived, then both these case will work:
obj.method(); // will call this method from the Derived class
obj.method(1); // will call this method from the Base class
when there are same method names in different classes , the compiler comes to know by:
1-if you are passing any argument , then the type of argument which you are passing will tell the compiler which method to be called
2-if there are two classes , then make the object of that class for which you want to call the method
public class Color {
String color;
Color(String color)
{
this.color=color;
}
}
public class ColoredCircle {
int x;
Color color;
ColoredCircle(int x, Color color)
{
this.x=x;
this.color=color;
}
public Object testClone()
{
Color c = new Color(this.color.color);
ColoredCircle cc1 = new ColoredCircle(this.x, c);
return cc1;
}
}
In the class ColoredCircle mentioned above we have a method named testClone() and it works exactly as Deep Cloning.
Now I am confused about the fact that is it necessary to implement Cloneable to clone?
And Is the above program a kind of Deep cloning?
Implementing the Cloneable interface is needed in order for a call to Object.clone() to not throw an exception. (That's the entire purpose of Cloneable.)
You are not using Object.clone(). So implementing Cloneable or not has no effect. It has nothing to do with what your method is called. Your method could be called testClone() and it can call up to super.clone(). Or your method could be called clone() and it could not use super.clone(). What matters is you are not using Object.clone().
The advantage of using Object.clone() is that the object it returns has the same exact runtime class as the object it is called on. On the other hand, your method creates a new ColoredCircle object always. So when your testClone() method is inherited in a subclass, it will still create a ColoredCircle, and not an instance of that subclass. Whereas if your method called super.clone() it will be able to get an instance of whatever subclass the current instance is.
Is it necessary to implement Cloneable to clone? Yes.The clone() method is having protected access modifier with the following Javadoc explantion :-
This method creates a new instance of the class of this object and initializes all its fields with exactly the contents of the corresponding fields of this object, as if by assignment; the contents of the fields are not themselves cloned. Thus, this method performs a shallow copy of this object, not a deep copy operation.
Your method testClone although may be correct in cloning behavior but is not a Cloneable Object in itself.A Cloneable object must implement Cloneable interface and preferably have a public access for clone() so that it can be used outside the class.
Someone reaading your class will have a hard time understanding the importance of testClone() method.
Cloneable is a marker interface. It contains no methods.
The thing is that the clone method is defined in the Object class. Since all classes implement the Object class, that means that all classes have a clone method. However, not all objects actually support it. Some of them will just throw a CloneNotSupportedException. But this clone method is a native method, and therefor the exact behavior of this method is not visible in the java source code. So, it lacks some transparency.
The Cloneable interface is there to help us recognize which classes are really cloneable and which are not. By convention, classes that don't implement Cloneable will throw the CloneNotSupportedException.
Note: the clone method is also marked protected. So, it's also convention to override it to make it public in supporting classes.
The clone design was introduced in JDK1. These days the general concensus is that the java clone design contains some flaws. Some prefer to just create a cloning constructor (e.g. public Color(Color toCopy) {this.color = toCopy.color;})
I am Learning Java, while trying to understand inheritance. I couldn't figure out why the overridden method at the subclass walk() executed but not the other xyz() method.
class Person{
public void walk() { System.out.println("walking like a person "); }
}
public class Soldier extends Person{
#override
public void walk() { System.out.println("marching like a soldier "); }
public void xyz() { System.out.println("xyzng like a pro"); }
public static void main(String[] args) {
Person sp = new Soldier();
sp.walk();
sp.xyz();
}
}
Here is my question, if the following method call works fine and calls the Soldier method walk,
sp.walk();
why the compiler complain about the this call?
sp.xyz();
At the compile time parent class reference 'sp' can only see method inside it. if you want to access as ((Soldier) sp).xyz()
You may want to take a look at this answer.
Basically, xyz method is defined in a subclass of Person and in general case compiler can't know (and should not know) whether the referenced instance is Soldier or some other subclass which does not define xyz method.
In Java, "objects" are not values themselves -- they must always be manipulated through references; when you create an object, you get a reference; when you access a field or call a method, you do it through the reference. When you assign one reference to another, it copies the reference, so you have multiple pointers to the same object.
Your question asks why Soldier.xyz() is not accessible when the
Soldier object is stored in a Person reference. The answer is the
intersection of "polymorphism" and "static typing". Because Java is
statically typed at compile time you get certain guarantees from the
compiler but you are forced to follow rules in exchange or the code
won't compile. Here, the relevant guarantee is that every instance of
a subclass (e.g. Soldier) can be used as an instance of its super
class (e.g. Person).
Please take a look at this it is explained in more details thread
As of the tutorial guide to truly understand the inheritance please take a look at this article
That's clear.
because your reference to object(sp) is of type Person, that means sp contains all property and methods of Person only.
Even you get instance of Soldier, but your reference is from Person type yet.
Person is a class.
sp is an object, it is an instance of Person
Class Person haven't method named xyz(), thereforce sp.xyz() not working.
(You have a typo, we use #Override, not #override)
In the compile-time, IDE only knows about the static Object type is Person class. You can see compile-time reference rule here: https://www.cs.cornell.edu/courses/JavaAndDS/files/compiletimeReferenceRule.pdf
Let's say I want to override the method equals() of Object:
public boolean equals(Object o){
//something
}
public boolean equals(SomeClass s){
//something else
}
SomeClass is obviously also an Object, so which method will be called if I use equals with an Instance of SomeClass as parameter?
That's not overriding, it's overloading. If you do that you'll end up with two equals methods: one that will be invoked for (subclasees of) SomeClass instances and one for any other objects.
One thing to note is that the method binding will be static: the compiler will decide which one to call based on the declared type of your reference. Therefore, the following will invoke the equals(Object), not equals(SomeClass):
Object o = new SomeClass();
o.equals(o); // invokes SomeClass.equals(Object)
If you overload the function like in your example, and instantiate the object normally, the equals function with SomeClass as parameter will be called if you provide a SomeClass to the equals function. For any other class, the equals function with an Object as parameter will be called.
If you instantiate your object as a parent class, however, the behaviour is different. This has to do with dynamic binding, which is explained quite well here: Question about Java overloading & dynamic binding
Note that if you're looking to do something else if the Object is of a SomeClass type, you could also use instanceof SomeClass in your standard equals function. (Not trying to start a discussing, but it's an option)
Your public boolean equals(SomeClass s) will be called when you invoke it with a parameter SomeClass or a sub class of SomeClass.
With any other object it will be public boolean equals(Object o) that's called.
But when you equals method is being called in other APIs they will call public boolean equals(Object o). Which will lead to erroneous behavior. Java Collection API is an example.
So do not overload the equals method like this.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Do interfaces inherit from Object class in java
package inheritance;
class A{
public String display(){
return "This is A!";
}
}
interface Workable{
public String work();
}
class B extends A implements Workable{
public String work(){
return "B is working!";
}
}
public class TestInterfaceObject{
public static void main(String... args){
B obj=new B();
Workable w=obj;
//System.out.println(w.work());
//invoking work method on Workable type reference
System.out.println(w.display());
//invoking display method on Workable type reference
//System.out.println(w.hashCode());
// invoking Object's hashCode method on Workable type reference
}
}
As we know that methods which can be invoked depend upon the type of the reference variable on which we are going to invoke. Here, in the code, work() method was invoked on "w" reference (which is Workable type) so method invoking will compile successfully. Then, display() method is invoked on "w" which yields a compilation error which says display method was not found, quite obvious as Workable doesn't know about it. Then we try to invoke the Object class's method i.e. hashCode() which yields a successful compilation and execution. How is it possible? Any logical explanation?
The intuitive answer is that regardless of what interface you refer to, the object implementing the interface must be a subclass of Object.
Section 9.2 of the JLS specifically defines this behaviour: http://docs.oracle.com/javase/specs/jls/se7/html/jls-9.html#jls-9.2
If an interface has no direct superinterfaces, then the interface implicitly declares a public abstract member method m with signature s, return type r, and throws clause t corresponding to each public instance method m with signature s, return type r, and throws clause t declared in Object, unless a method with the same signature, same return type, and a compatible throws clause is explicitly declared by the interface.
i.e. all interfaces are assumed to contain method signatures corresponding to methods in the Object class.
I think what's happening here is that even though w is known only to be Workable, all objects must derive from Object, so no matter what class w eventually is, it must have the Object methods.
The reason w.display() doesnt work is as you have save the reference as your interface type. The compiler only sees the methods exposed by the interface. If you were to call ((B)w).display() this would work. You are able to call hashCode() as the compiler is smart enough to know that interfaces are inherited by Objects and all object's superclass is Object