interface I
{
void show();
}
class A implements I
{
void show()
{
System.out.println("class A");
}
public static void main(String s[])
{
I i=new A();
i.show();
i.toString();
}
}
Q> As interface I does not contain the abstract method toString() but still The following code gets compiled. How?
when super class variable is used to refer sub class obj then compiler first searches the similar method in the super class if not found gives error.
here Interface does not contain the method toString().
ex=>
class A
{
void show()
{
System.out.println("show");
}
}
class B
{
void show()
{
System.out.println("show B");
}
void display()
{
System.out.println("display B");
}
public static void main(String s[])
{
A a=new B();
a.show(); //will execute
a.display(); //give error
}
All classes inherit from Object. Object has a toString.
To use any interface it must be backed by a actual class. So the Java compiler knows that it can use any method defined in java.lang.Object when dealing with an Interface.
To put it a slightly different way:
interface I { ... }
has an "magic"
interface I extends Object { ... }
So you can use Objects methods when detail with I. However you can not use any methods in the concrete class that do not appear in the interface. So to combine you two examples:
interface Car {
void drive();
}
class Convertible implements Car {
void drive() {}
void openRoof() {}
public static void main() {
Car porscheBoxster = new Convertible();
porscheBoxster.drive(); // OK - exists in interface
porscheBoxster.toString(); // OK - exists in java.lang.Object.
porscheBoxster.openRoof(); // Error. All we know is the porscheBoxster is of type Car.
// We don't know if it is a Convertible or not.
}
}
Every class in Java is an Object, thus, they are always able to run the following methods:
clone()
equals(Object)
finalize()
getClass()
hashCode()
notify()
notifyAll()
toString()
wait()
wait(long)
wait(long, int)
Because 'toString()' is in the class Object which every non-primitive data is derived from. So every object has this method.
In Java, every class you construct, inherits from the base class Object.
This means that your class by default will have a lot of useful methods, amongst others toString().
Related
I have an abstract super class A with a method doSomething(). A sub-class of A must implement doSomething(), but there is also some common code that should be called every time a subclass calls doSomething(). I know this could be achieved thus:
public class A {
public void doSomething() {
// Things that every sub-class should do
}
}
public class B extends A {
public void doSomething() {
super.doSomething();
// Doing class-B-specific stuff here
...
}
}
There seem to be three issues with this, though:
The method signatures have to match, but I might want to return something in the sub-class methods only, but not in the super-class
If I make A.doSomething() abstract, I can't provide a (common) implementation in A. If I don't make it abstract, I can't force sub-class to implement it.
If I use a different method to provide the common functionality, I can't enforce that B.doSomething() calls that common method.
Any ideas how the methods should be implemented?
What about the following?
public abstract class A {
protected abstract void __doSomething();
public void doSomething() {
// Things that every sub-class should do
__doSomething();
}
}
public class B extends A {
protected void __doSomething() {
// Doing class-B-specific stuff here
...
}
}
The first bullet point however is not so clear. The signature can't match if you want to return something different.
add call back to doSomething()
public class A {
public void doSomething() {
// Things that every sub-class should do
doSomethingMore()
}
}
protected abstract void doSomethingMore()
so all subclusses will have to ipmelment doSomethingMore() with additional actions but external classes will call public doSomething()
For first point alone - you can consider the below answer and for enforcing subclass implementation it can be abstract but calling common code functionality can happen if the base class has some implementation.
Return type can be Object in Base Class and returning null. In SubClass the specific return type can be put as given below.
public class InheritanceTutorial {
static class Base{
public Object doSomething(){
System.out.println("parent dosomething");
return null;
}
}
static class SubClass extends Base{
public Integer doSomething(){
super.doSomething();
System.out.println("child dosomething");
return 0;
}
}
/**
* #param args
*/
public static void main(String[] args) {
SubClass subClass = new SubClass();
subClass.doSomething();
}
}
what is the need of having a rule like this in java :
"a subclass cannot weaken the accessibility of a method defined in the superclass"
If you have a class with a public method
public class Foo {
public void method() {}
}
This method is accessible and you can therefore do
Foo foo = new Foo();
foo.method();
If you add a subclass
public class Bar extends Foo {
#Override
public /* private */ void method() {}
}
If it was private, you should not be able to do
Foo bar = new Bar();
bar.method();
In this example, a Bar is a Foo, so it must be able to replace a Foo wherever one is expected.
In order to satisfy the above statement, a sub class cannot make an inheritable member less accessible. It can however make it more accessible. (This basically only applies to methods.)
What it means
The subclass method cannot have a more restrictive visibity than the superclass method.
For example, if the superclass defined
protected void a() { } // visible to package and subclasses
the subclass can override it with one of
public void a() { } // visible to all
protected void a() { } // visible to package and subclasses
but not
void a() { } // visible to package
private void a() { } // visible to itself
Why it is
Suppose the definition was
class A {
public void a() { }
}
class B extends A {
private void a() { }
}
Now, consider the following code
A instance = new B();
instance.a(); // what does this call?
On the one hand, any B has a publically accessible a method. On the other hand, the a method of a B instance is only accessible to B.
More generally, a subclass(interface) must fulfill the contract of its superclass(interface).
Visibility is only one example of this principle. Another example is that a non-abstract class must implement all methods of any interface it implements.
class Person {
public String name() {
return "rambo";
}
}
// subclass reduces visibility to private
class AnonymousPerson {
private String name() {
return "anonymous";
}
}
It's legal to call the following method with either a Person, or an AnonymousPerson as the argument. But, if the method visibility was restricted, it wouldnt' be able to call the name() method.
class Tester {
static void printPersonName(Person p) {
System.out.println(p.name());
}
}
//ok
Tester.printPersonName(new Person());
this call is legal, because a Person is a AnonymousPerson, but it would have to fail inside the method body. This violates "type safety".
Tester.printPersonName(new AnonymousPerson());
To fulfill the interface contract. Let's say I have an interface, IFlying, as:
public interface IFlying {
public void fly();
}
And I have an implementation that weakens accessibility:
public class Bird implements IFlying {
private void fly(){
System.out.println("flap flap");
}
}
I now have some library function that accepts an IFlying, and calls fly upon it. The implementation is private. What happens now? Of course, it means that the fly method cannot be accessed.
Hence, the accessibility may not be made more restrictive in an implementation.
what will be the flow of execution in case of override? What i believe is , when we call a constructor/object of any class, during execution first it call parent constructor and than child. but what will happen in case of over ridding?
lets suppose:
class A {
public A(){
printStatus();
}
public void printStatus(){
System.out.println("In Class A");
}
}
class B extends A{
public B(){
printStatus();
}
#Override
public void printStatus(){
System.out.println("In Class b");
}
}
public class Test2 {
public static void main(String[] args){
B b = new B();
}
}
Out put of this code is:
In Class b
In Class b
what i don't understand is, why it's printing "In Class be" only, it should be "In class A and, In Class b",
when i remove override method from class b. it give me desired output.
All java methods are virtual. It means the method is called with using actual type of this. So inside of constructor A() {} this is the instance of B, so that is why you've got its method call.
Calling like this printStatus() will call the method from the same class. If you call with super.printStatus() it will envoke method from the super class (class which you have extended).
When you over-ride a method you over-ride it completely. The existence of the original implementation is completely invisible to other classes (except via reflection but that's a big topic of its own and not really relevant). Only your own class can access the original method and that is by calling super.methodName().
Note that your class can call super.methodName() anywhere, not just in the overriding function, although the most usual use for it is in the overriding function if you want the super implementation to run as well as your own.
Constructors are a slightly special case as there are rules about how and why constructors are called in order to make sure that your super-class is fully initialized when you try and use it in the inheriting class.
super is always called whether you write super(); or not.
In the example printStatus() method of Class A will never be called. Since you are creating an instance of class B and there will be method overriding. You can use the following to call the Class A printStatus() method.
public B()
{
super.printStatus();
}
When you override a method, it will override the one that you expect from class A.
Should use super keyword for calling super class method.
class A {
public A(){
printStatus();
}
public void printStatus(){
System.out.println("In Class A");
}
}
class B extends A{
public B(){
super.printStatus();
}
#Override
public void printStatus(){
System.out.println("In Class b");
}
}
Constructor public B(){ super.printStatus(); } calls Class A print method and constructor public A(){ printStatus(); } calls Class B print method since you've overridden.
But its wrong with overridable method calls in constructors.
Try with like this :
class A {
public A(){
printStatus();
}
public void printStatus(){
System.out.println("In Class A");
}
}
class B extends A{
public B(){
super.printStatus();
printStatus();
}
#Override
public void printStatus(){
System.out.println("In Class b");
}
}
public class Test2 {
public static void main(String[] args){
B b = new B();
}
}
For better understanding the concepts of Overloading and Overriding just go through this links:
http://en.wikibooks.org/wiki/Java_Programming/Overloading_Methods_and_Constructors
I am trying right now to dig into anonymous classes and one question was just arised I'd prefer not to refer to much details and to pose my question straightforward: How can I invoke the method sizzle() in the following anonymous class:
public class Popcorn {
public void pop() {
System.out.println("popcorn");
}
}
class Food {
Popcorn p = new Popcorn() {
public void sizzle() {
System.out.println("anonymous sizzling popcorn");
}
public void pop() {
System.out.println("anonymous popcorn");
}
};
public void popIt() {
p.pop(); // OK, Popcorn has a pop() method
p.sizzle(); // Not Legal! Popcorn does not have sizzle()
}
}
It is known and definite in polymorphism rules that a refernce of a superclass cannot invoke methods of subclass without downcasting (even if it refers to an object of the given subclass). However in the above case what is the "key" to invoke the sizzle() method?
The sizzle() method simply cannot be accessed from the outside, because the class is anonymous.
The p reference is a type Popcorn, and that doesn't define sizzle().
Anonymous classes are meant to be one-shot, and are heavily used in some design patterns (like Observer) because Java doesn't have first class function, ie you can't pass function objects around.
I kind of didn't expect this to work, but it does:
new Object() {
public void foo() {}
}.foo();
The above will compile and work as expected. The explanation is that the type of the expression new Object() {} is the anonymous type that expression defines, not Object. However, you can't have a variable (or method parameter) of that type, which means that you can't invoke the method anywhere else except chained after the new expression.
Since this doesn't really solve your (unsolvable) problem, I admit it's more of a supplementary answer.
When you call p.sizzle(), you need to have the p variable to be of a type that has the sizzle() method.
The only way is to use a subclass or an interface.
You can even cast, if you don't want to change the type of p, but you can't cast to a anonymous type.
If you need that class only inside the Food class, you should declare it in there
class Food {
EdiblePopcorn p = new EdiblePopcorn() {
#Override
public void sizzle() {
System.out.println("anonymous sizzling popcorn");
}
#Override
public void pop() {
System.out.println("anonymous popcorn");
}
};
public void popIt() {
p.pop(); // OK, Popcorn has a pop() method
p.sizzle(); // Also legal! EdiblePopcorn now has sizzle()
}
private abstract class EdiblePopcorn extends Popcorn {
// if the sizzle body is always the same, you can declare it here.
void sizzle();
}
}
I'm learning java. I was trying to run the code, where I got this error: return type is incompatible.
Part of code where it showed me error.
class A {
public void eat() { }
}
class B extends A {
public boolean eat() { }
}
Why it is happening?
This is because we cannot have two methods in classes that has the same name but different return types.
The sub class cannot declare a method with the same name of an already existing method in the super class with a different return type.
However, the subclass can declare a method with the same signature as in super class.
We call this "Overriding".
You need to have this,
class A {
public void eat() { }
}
class B extends A {
public void eat() { }
}
OR
class A {
public boolean eat() {
// return something...
}
}
class B extends A {
public boolean eat() {
// return something...
}
}
A good practice is marking overwritten methods by annotation #Override:
class A {
public void eat() { }
}
class B extends A {
#Override
public void eat() { }
}
if B extends A then you can override methods (like eat), but you can't change their signatures. So, your B class must be
class B extends A {
public void eat() { }
}
B extends A should be interpreted as B is a A.
If A's method doesn't return anything, B should do the same.
When a method in subclass has same name and arguments (their types, number, and order) as the method in superclass then the method in subclass overrides the one in superclass.
Now for the overriding to be allowed the return type of the method in subclass must comply with that of the method in superclass. This is possible only if the return type of the method in subclass is covariant with that of the method in superclass.
Since, boolean </: void (read: boolean isn't subtype of void), compiler raises the "return type incompatible" error.
This is neither overloading nor overriding. We cannot overload on the return type and we cannot override with different different return types ( unless they are covariant returns wef Java 1.5 ).
This shows error , because we can not create two same methods but different return type in same class. If in parent class contain any method, we can't create same method name with changing the return type in sub class. Now the question arise why we can't create this. we should discuss about following code.
class A {
public void eat() { }
}
class B extends A {
public boolean eat() { }
}
Class MainClass{
public static void main(String[] args){
A a = new B();
a.eat();
}
}
It will shows an error, because a.eat(); will be confused which method JVM should call. and it will return a runtime error. Thats why to overcome runtime error, it returns a compile time error.