An instance method in a subclass with the same signature (name, plus the number and the type of its parameters) and return type as an instance method in the superclass overrides the superclass's method. Show The ability of a subclass to override a method allows a class to inherit from a superclass whose behavior is "close enough" and then to modify behavior as needed. The overriding method has the same name, number and type of parameters, and return type as the method that it overrides. An overriding method can also return a subtype of the type returned by the overridden method. This subtype is called a covariant return type. When overriding a method, you might want to use the public class Cat extends Animal { public static void testClassMethod() { System.out.println("The static method in Cat"); } public void testInstanceMethod() { System.out.println("The instance method in Cat"); } public static void main(String[] args) { Cat myCat = new Cat(); Animal myAnimal = myCat; Animal.testClassMethod(); myAnimal.testInstanceMethod(); } }7 annotation that instructs the compiler that you intend to override a method in the superclass. If, for some reason, the compiler detects that the method does not exist in one of the superclasses, then it will generate an error. For more information on public class Cat extends Animal { public static void testClassMethod() { System.out.println("The static method in Cat"); } public void testInstanceMethod() { System.out.println("The instance method in Cat"); } public static void main(String[] args) { Cat myCat = new Cat(); Animal myAnimal = myCat; Animal.testClassMethod(); myAnimal.testInstanceMethod(); } }7, see public class Cat extends Animal { public static void testClassMethod() { System.out.println("The static method in Cat"); } public void testInstanceMethod() { System.out.println("The instance method in Cat"); } public static void main(String[] args) { Cat myCat = new Cat(); Animal myAnimal = myCat; Animal.testClassMethod(); myAnimal.testInstanceMethod(); } }9. Static MethodsIf a subclass defines a static method with the same signature as a static method in the superclass, then the method in the subclass hides the one in the superclass. The distinction between hiding a static method and overriding an instance method has important implications:
Consider an example that contains two classes. The first is The static method in Animal The instance method in Cat0, which contains one instance method and one static method: public class Animal { public static void testClassMethod() { System.out.println("The static method in Animal"); } public void testInstanceMethod() { System.out.println("The instance method in Animal"); } } The second class, a subclass of The static method in Animal The instance method in Cat0, is called The static method in Animal The instance method in Cat2: public class Cat extends Animal { public static void testClassMethod() { System.out.println("The static method in Cat"); } public void testInstanceMethod() { System.out.println("The instance method in Cat"); } public static void main(String[] args) { Cat myCat = new Cat(); Animal myAnimal = myCat; Animal.testClassMethod(); myAnimal.testInstanceMethod(); } } The The static method in Animal The instance method in Cat2 class overrides the instance method in The static method in Animal The instance method in Cat0 and hides the static method in The static method in Animal The instance method in Cat0. The The static method in Animal The instance method in Cat6 method in this class creates an instance of The static method in Animal The instance method in Cat2 and invokes The static method in Animal The instance method in Cat8 on the class and The static method in Animal The instance method in Cat9 on the instance. The output from this program is as follows: The static method in Animal The instance method in Cat As promised, the version of the hidden static method that gets invoked is the one in the superclass, and the version of the overridden instance method that gets invoked is the one in the subclass. Default methods and abstract methods in interfaces are inherited like instance methods. However, when the supertypes of a class or interface provide multiple default methods with the same signature, the Java compiler follows inheritance rules to resolve the name conflict. These rules are driven by the following two principles:
If two or more independently defined default methods conflict, or a default method conflicts with an abstract method, then the Java compiler produces a compiler error. You must explicitly override the supertype methods. Consider the example about computer-controlled cars that can now fly. You have two interfaces ( public class Horse { public String identifyMyself() { return "I am a horse."; } }4 and public class Horse { public String identifyMyself() { return "I am a horse."; } }5) that provide default implementations for the same method, ( public class Horse { public String identifyMyself() { return "I am a horse."; } }6): public class Cat extends Animal { public static void testClassMethod() { System.out.println("The static method in Cat"); } public void testInstanceMethod() { System.out.println("The instance method in Cat"); } public static void main(String[] args) { Cat myCat = new Cat(); Animal myAnimal = myCat; Animal.testClassMethod(); myAnimal.testInstanceMethod(); } }1 public class Cat extends Animal { public static void testClassMethod() { System.out.println("The static method in Cat"); } public void testInstanceMethod() { System.out.println("The instance method in Cat"); } public static void main(String[] args) { Cat myCat = new Cat(); Animal myAnimal = myCat; Animal.testClassMethod(); myAnimal.testInstanceMethod(); } }2 A class that implements both public class Horse { public String identifyMyself() { return "I am a horse."; } }4 and public class Horse { public String identifyMyself() { return "I am a horse."; } }5 must override the method public class Horse { public String identifyMyself() { return "I am a horse."; } }6. You could invoke any of the of the default implementations with the public interface Flyer { default public String identifyMyself() { return "I am able to fly."; } }0 keyword. public class Cat extends Animal { public static void testClassMethod() { System.out.println("The static method in Cat"); } public void testInstanceMethod() { System.out.println("The instance method in Cat"); } public static void main(String[] args) { Cat myCat = new Cat(); Animal myAnimal = myCat; Animal.testClassMethod(); myAnimal.testInstanceMethod(); } }3 The name preceding public interface Flyer { default public String identifyMyself() { return "I am able to fly."; } }0 (in this example, public class Horse { public String identifyMyself() { return "I am a horse."; } }5 or public class Horse { public String identifyMyself() { return "I am a horse."; } }4) must refer to a direct superinterface that defines or inherits a default for the invoked method. This form of method invocation is not restricted to differentiating between multiple implemented interfaces that contain default methods with the same signature. You can use the public interface Flyer { default public String identifyMyself() { return "I am able to fly."; } }0 keyword to invoke a default method in both classes and interfaces. Inherited instance methods from classes can override abstract interface methods. Consider the following interfaces and classes: public class Cat extends Animal { public static void testClassMethod() { System.out.println("The static method in Cat"); } public void testInstanceMethod() { System.out.println("The instance method in Cat"); } public static void main(String[] args) { Cat myCat = new Cat(); Animal myAnimal = myCat; Animal.testClassMethod(); myAnimal.testInstanceMethod(); } }4 public class Cat extends Animal { public static void testClassMethod() { System.out.println("The static method in Cat"); } public void testInstanceMethod() { System.out.println("The instance method in Cat"); } public static void main(String[] args) { Cat myCat = new Cat(); Animal myAnimal = myCat; Animal.testClassMethod(); myAnimal.testInstanceMethod(); } }5 public class Cat extends Animal { public static void testClassMethod() { System.out.println("The static method in Cat"); } public void testInstanceMethod() { System.out.println("The instance method in Cat"); } public static void main(String[] args) { Cat myCat = new Cat(); Animal myAnimal = myCat; Animal.testClassMethod(); myAnimal.testInstanceMethod(); } }6 The method public interface Flyer { default public String identifyMyself() { return "I am able to fly."; } }5 returns the string public class Horse { public String identifyMyself() { return "I am a horse."; } }1 The class public interface Flyer { default public String identifyMyself() { return "I am able to fly."; } }7 inherits the method public interface Flyer { default public String identifyMyself() { return "I am able to fly."; } }8 from the class public interface Flyer { default public String identifyMyself() { return "I am able to fly."; } }9, which overrides the abstract method of the same name in the interface public interface Mythical { default public String identifyMyself() { return "I am a mythical creature."; } }0. Note: Static methods in interfaces are never inherited. ModifiersThe access specifier for an overriding method can allow more, but not less, access than the overridden method. For example, a protected instance method in the superclass can be made public, but not private, in the subclass. You will get a compile-time error if you attempt to change an instance method in the superclass to a static method in the subclass, and vice versa. SummaryThe following table summarizes what happens when you define a method with the same signature as a method in a superclass. |