In below example (in the commented block) I'm trying to override jump() method of an anonymous class, however getting compilation error. Can someone help me understand what's wrong here?
class Animal {
public void bark() {
System.out.println("Inside bark");
}
public void jump() {
System.out.println("Inside jump");
}
}
public class AnonymousClassExample001 {
public static void main(String[] args) {
Animal animal = new Animal() {
public void bark() {
System.out.println("Subclass bark");
}
}; /* {
public void jump() {
System.out.println("Subclass jump");
}
};*/
/**
* Question is: Why can't we override by extending an anonymous class
* as attempted (and commented) above?
* */
animal.bark(); // Subclass bark
animal.jump(); // Trying to print "Subclass jump", by overriding (the subclass of Animal) above
}
}
Edit:
Here's the compilation error I'm getting in IDE - ';' expected.
And from the comments, it seems some folks are not getting my question. With the above example, I wanted to understand whether we can override an anonymous class's methods or not?.
Again, the main motive is to see (and understand) why Java compiler allowed to create an anonymous class by starting a {} block followed by new Animal(), and didn't allow the same behaviour further (chaining of {} blocks to allow creation of further subclasses)
Don't end and restart the block, override both methods in one block, same as you would in a regular subclass:
class AnonymousClassExample001 {
public static void main(String[] args) {
Animal animal = new Animal() {
#Override
public void bark() {
System.out.println("Subclass bark");
}
#Override
public void jump() {
System.out.println("Subclass jump");
}
};
animal.bark(); // Subclass bark
animal.jump(); // Subclass jump
}
}
UPDATE
Updates to the question says you're trying to subclass an anonymous class, e.g. you're trying to do this:
class AnonymousClassExample001 {
public static void main(String[] args) {
Animal barkingAnimal = new Animal() {
#Override
public void bark() {
System.out.println("Subclass bark");
}
};
Animal jumpingAnimal = <subclass barkingAnimal> { // Can't be done
#Override
public void jump() {
System.out.println("Subclass jump");
}
};
barkingAnimal.bark(); // Subclass bark
barkingAnimal.jump(); // Inside jump
jumpingAnimal.bark(); // Subclass bark
jumpingAnimal.jump(); // Subclass jump
}
}
You can't do that, because the unnamed anonymous class cannot be identified as the base class. You can however do it using local classes, which are like named anonymous classes, as contradictory as that sounds:
class AnonymousClassExample001 {
public static void main(String[] args) {
class BarkingAnimal extends Animal {
#Override
public void bark() {
System.out.println("Subclass bark");
}
};
class JumpingAnimal extends BarkingAnimal {
#Override
public void jump() {
System.out.println("Subclass jump");
}
};
Animal barkingAnimal = new BarkingAnimal();
Animal jumpingAnimal = new JumpingAnimal();
barkingAnimal.bark(); // Subclass bark
barkingAnimal.jump(); // Inside jump
jumpingAnimal.bark(); // Subclass bark
jumpingAnimal.jump(); // Subclass jump
}
}
Alternatively, jumpingAnimal could also be done using anonymous class syntax, instead of local class syntax.
I think it should be like this
public class AnonymousClassExample001 {
public static void main(String[] args) {
Animal animal = new Animal() {
public void bark() {
System.out.println("Subclass bark");
}
public void jump() {
System.out.println("Subclass jump");
}
};
/**
* Question is: Why can't we override by extending an anonymous class
* as attempted (and commented) above?
* */
animal.bark(); // Subclass bark
animal.jump(); // Trying to print "Subclass jump", by overriding (the subclass of Animal) above
}
}
Related
This question already has answers here:
Java superclass calls subclass method
(5 answers)
Closed 1 year ago.
Why does method() call the overridden subclass method2 instead of method2 in the BaseClass?
public class BaseClass {
public void method(){
System.out.println("method() called");
method2();
}
public void method2(){
System.out.println("method2() called");
}
}
public class ChildClass extends BaseClass {
public void method2(){
System.out.println("method2() from BaseClass");
}
}
public class Main {
public static void main(String[] args) {
ChildClass obj = new ChildClass();
obj.method();
}
}
This is the concept of Runtime polymorphism (Dynamic Method Dispatch). Because you are assigning the object (instance) of ChildClass to obj reference variable, it will call the method of child class.
Always the method of the class whose instance is created gets called first. If that method is not present in that particular child class, then the parent's inherited method gets called.
If you come from the C++ corner:
all instance methods (non-static) in Java are virtual.
All class methods (static) are NOT.
This is why your case happens.
This is also, why the Java compiler will complain (warn) that if you access a static method via an object, that you should call via the distinct class, because calls to the "static method of a object" could be ambiguous, because it could be two static methods with the same signature that get called.
Extending your Example:
package stackoverflow.staticcalls;
public class BaseClass {
public void method() {
System.out.println("method() called");
method2();
}
public void method2() {
System.out.println("method2() called");
}
static public void sayHello() {
System.out.println("BaseClass.sayHello()");
}
}
and
package stackoverflow.staticcalls;
public class ChildClass extends BaseClass {
public void method2() { // compiler warning: The method method2() of type ChildClass should be tagged with #Override since it actually overrides a superclass method
System.out.println("method2() from BaseClass");
}
public void originalCallToBaseMethod2() {
super.method2(); // will run BaseClass.method2()
}
static public void sayHello() {
System.out.println("ChildClass.sayHello()");
}
}
and
package stackoverflow.staticcalls;
public class Main {
public static void main(final String[] args) {
final ChildClass obj = new ChildClass();
System.out.println("\nCalling obj.method(); ...");
obj.method();
System.out.println("\nCalling obj.sayHello(); ...");
obj.sayHello(); // compiler warning: The static method sayHello() from the type ChildClass should be accessed in a static way
System.out.println("\nCalling ChildClass.sayHello(); ...");
ChildClass.sayHello(); // the proper call
System.out.println("\nCalling BaseClass.sayHello(); ...");
BaseClass.sayHello(); // but you can also explpicitly call the other method
System.out.println("\nCalling obj.originalCallToBaseMethod2(); ...");
obj.originalCallToBaseMethod2(); //
}
}
Here you see the examples to what I said.
Note: In the last call in Main.main() we still can call BaseClass.method2(), but not directly. We have to be within ChildClass to do that, and it's done via the super keyword/reference.
A little off-topic note, to complete addressing patterns:
If you're inside an inner class and need to call to a overshadowed name in the outer class, you can use Outer.this.method():
package stackoverflow.staticcalls;
import stackoverflow.staticcalls.OuterInner.Outer.Inner;
public class OuterInner {
class Outer {
void method() {
System.out.println("OuterInner.Outer.method()");
}
class Inner {
void method() {
System.out.println("OuterInner.Outer.Inner.method()");
}
void callOuter() {
Outer.this.method();
}
}
}
public static void main(final String[] args) {
final OuterInner oi = new OuterInner();
final Outer outer = oi.new Outer();
final Inner inner = outer.new Inner();
System.out.println("\nCalling inner.method(); ...");
inner.method();
System.out.println("\nCalling inner.callOuter(); ...");
inner.callOuter();
}
}
Suggested to pass a File class object to playClip() that references the animal sound file and catches any exceptions outputting "Meow" if any exceptions were caught. When I run Main function I hear the cat sound in the speakers.
Have I passed the File object reference to playClip() the right way?
public void makeSound() {
try {
playClip(new File("Cat.wav"));
} catch (Exception e) {
System.out.println("Meow");
}
}
With the following main function
public class Main {
public static void main(String[] args) {
Cat sound = new Cat();
sound.makeSound();
}
}
In your abstract class, create the method playClip:
public abstract class Sound {
abstract public void makeSound();
public void playClip(File clipFile) {
// code plays a file and has some exception handling
}
}
public class Cat extends Sound {
public Cat() {
super();
}
#Override
public void makeSound() {
playClip(new File("/sound_file"));
}
}
Of course, playClip() could also be abstract. It depends what you want.
This question already has answers here:
Overriding member variables in Java ( Variable Hiding)
(13 answers)
Closed 5 years ago.
I know that when you overload method then java resolves it on compilation stage so that's why when you writing something like this:
public class SomeClass{
private static void someMethod(Object obj){
System.out.println("obj");
}
private static void someMethod(String str){
System.out.println("str");
}
public static void main(String[] args) {
Object obj = new SomeClass();
obj.someMethod(obj);
}
}
you will get obj, because oveloading is resolved on compilation and doing something like that:
public abstract class Animal {
public void careFor() {
play();
}
public void play() {
System.out.println("pet animal");
}
}
public class Lion extends Animal {
public void play() {
System.out.println("toss in meat");
}
public static void main(String[] args) {
Animal animal = new Lion();
animal.careFor();
}
}
you will get toss in meat beacuse overriding method is resolved on runtime stage.
But what I don't understand. Why when you overrding instance variable you will get situation like resolving on compilation stage. For example:
public abstract class Animal {
String name = "???";
public void printName() {
System.out.println(name);
}
}
public class Lion extends Animal {
String name = "Leo";
public static void main(String[] args) {
Animal animal = new Lion();
animal.printName();
}
}
In this situation I will get ??? . So it looks like resolving on compilation stage when you overriding variable. Is it so?
In Java Only methods are Polymorphism and not variables.
So when you do
Animal animal = new Lion();
You get all the variables from Animal and methods from Lion gets execute.
In Java, I use an anonymous class inside a class A which extends B. How can I access to B from this anonymous class? I can't use the keyword super, because this means super class of the anonymous class, not super class of A.
public class A {
void foo() {
System.out.println("Good");
}
}
public class B extends A {
void bar() {
Runnable r = new Runnable() {
#Override
public void run() {
foo(); // Bad: this call B.foo(), not A.foo()
// super.foo(); // Bad: "Method foo is undefined for type Object"
}
};
r.run();
}
#Override
void foo() {
System.out.println("Bad");
}
}
In run, you could change foo() to B.super.foo(); when I changed that and then ran B.bar() I get Good.
In such a case, you need to qualify this to capture the outer class, B
B.this.foo()
Or, in your case, as you want the super class, use
B.super.foo()
Relevant parts of Java Language Spec:
Qualified this
Accessing superclass members with super
Please call as fallows:
B.super.foo();
After this change B class looks as follows:
public class B extends A {
public static void main(String[] args) {
new B().bar();
}
void bar() {
Runnable r = new Runnable() {
#Override
public void run() {
B.super.foo(); // this calls A.foo()
}
};
r.run();
}
#Override
void foo() {
System.out.println("Bad");
}
}
Java 8 introduces default methods to provide the ability to extend interfaces without the need to modify existing implementations.
I wonder if it's possible to explicitly invoke the default implementation of a method when that method has been overridden or is not available because of conflicting default implementations in different interfaces.
interface A {
default void foo() {
System.out.println("A.foo");
}
}
class B implements A {
#Override
public void foo() {
System.out.println("B.foo");
}
public void afoo() {
// how to invoke A.foo() here?
}
}
Considering the code above, how would you call A.foo() from a method of class B?
As per this article you access default method in interface A using
A.super.foo();
This could be used as follows (assuming interfaces A and C both have default methods foo())
public class ChildClass implements A, C {
#Override
public void foo() {
//you could completely override the default implementations
doSomethingElse();
//or manage conflicts between the same method foo() in both A and C
A.super.foo();
}
public void bah() {
A.super.foo(); //original foo() from A accessed
C.super.foo(); //original foo() from C accessed
}
}
A and C can both have .foo() methods and the specific default implementation can be chosen or you can use one (or both) as part of your new foo() method. You can also use the same syntax to access the default versions in other methods in your implementing class.
Formal description of the method invocation syntax can be found in the chapter 15 of the JLS.
This answer is written mainly for users who are coming from question 45047550 which is closed.
Java 8 interfaces introduce some aspects of multiple inheritance. Default methods have an implemented function body. To call a method from the super class you can use the keyword super, but if you want to make this with a super interface it's required to name it explicitly.
class ParentClass {
public void hello() {
System.out.println("Hello ParentClass!");
}
}
interface InterfaceFoo {
public default void hello() {
System.out.println("Hello InterfaceFoo!");
}
}
interface InterfaceBar {
public default void hello() {
System.out.println("Hello InterfaceBar!");
}
}
public class Example extends ParentClass implements InterfaceFoo, InterfaceBar {
public void hello() {
super.hello(); // (note: ParentClass.super could not be used)
InterfaceFoo.super.hello();
InterfaceBar.super.hello();
}
public static void main(String[] args) {
new Example().hello();
}
}
Output:
Hello ParentClass!
Hello InterfaceFoo!
Hello InterfaceBar!
The code below should work.
public class B implements A {
#Override
public void foo() {
System.out.println("B.foo");
}
void aFoo() {
A.super.foo();
}
public static void main(String[] args) {
B b = new B();
b.foo();
b.aFoo();
}
}
interface A {
default void foo() {
System.out.println("A.foo");
}
}
Output:
B.foo
A.foo
You don't need to override the default method of an interface. Just call it like the following:
public class B implements A {
#Override
public void foo() {
System.out.println("B.foo");
}
public void afoo() {
A.super.foo();
}
public static void main(String[] args) {
B b=new B();
b.afoo();
}
}
Output:
A.foo
It depends on your choice whether you want to override the default method of an interface or not. Because default are similar to instance method of a class which can be directly called upon the implementing class object. (In short default method of an interface is inherited by implementing class)
Consider the following example:
interface I{
default void print(){
System.out.println("Interface");
}
}
abstract class Abs{
public void print(){
System.out.println("Abstract");
}
}
public class Test extends Abs implements I{
public static void main(String[] args) throws ExecutionException, InterruptedException
{
Test t = new Test();
t.print();// calls Abstract's print method and How to call interface's defaut method?
}
}