Override is not allowed when implementing interface method Bytecode Version Overriding and Hiding Methods 重载 重写
java - @Override is not allowed when implementing interface method - Stack Overflow https://stackoverflow.com/questions/15402615/override-is-not-allowed-when-implementing-interface-method
Intellij IDEA Module 的Language Level的问题 - LarryZeal - 博客园 https://www.cnblogs.com/larryzeal/p/5552360.html
Bytecode Version Inspector http://alumnus.caltech.edu/~leif/opensource/bcver/
Open Source Project
Bytecode Version Inspector
Bytecode Version Inspector is a tool that examines class and jar files for Java bytecode version information.
Bytecode Version Inspector is distributed under the Apache License, Version 2.0.
Downloads
Executable (bcver.jar). To use the executable, you will need to download this file and use it, either as an ant task or as a command-line application. The tool requires Java 1.4.2 or newer to run.
Source (bcver-src.zip). To use the source, you will need to have a working Ant installation (1.6.2 or newer), and will need to copy two additional binary distribution files to the bin
subdirectory (created when you unpack the source). These two files are an Ant binary distribution (available from the Apache Ant project; version 1.6.2 or newer), and a CheckStyle binary distribution (available from the CheckStyle website; version 3.5 or newer). Two additional files, junit.jar and jsch-0.1.20.jar, must be present in the Ant lib
directory, and may be obtained from the classchecker lib
directory after unpacking the source. You will also need a Java Development Kit; the tool requires JDK 1.4.2 or newer to compile.
To build a fresh copy, unpack the source, obtain the tools mentioned in the previous paragraph, and invoke Ant with no arguments in the directory the source was unpacked into.
Documentation
Overriding and Hiding Methods (The Java™ Tutorials > Learning the Java Language > Interfaces and Inheritance) https://docs.oracle.com/javase/tutorial/java/IandI/override.html
The Java Tutorials have been written for JDK 8. Examples and practices described in this page don't take advantage of improvements introduced in later releases.
Overriding and Hiding Methods
Instance Methods
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.
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 @Override
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 @Override
, see Annotations
.
Static Methods
If 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:
- The version of the overridden instance method that gets invoked is the one in the subclass.
- The version of the hidden static method that gets invoked depends on whether it is invoked from the superclass or the subclass.
Consider an example that contains two classes. The first is Animal
, 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 Animal
, is called Cat
:
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 Cat
class overrides the instance method in Animal
and hides the static method in Animal
. The main
method in this class creates an instance of Cat
and invokes testClassMethod()
on the class and testInstanceMethod()
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.
Interface Methods
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:
-
Instance methods are preferred over interface default methods.
Consider the following classes and interfaces:
public class Horse { public String identifyMyself() { return "I am a horse."; } }
public interface Flyer { default public String identifyMyself() { return "I am able to fly."; } }
public interface Mythical { default public String identifyMyself() { return "I am a mythical creature."; } }
public class Pegasus extends Horse implements Flyer, Mythical { public static void main(String... args) { Pegasus myApp = new Pegasus(); System.out.println(myApp.identifyMyself()); } }
The method
Pegasus.identifyMyself
returns the stringI am a horse.
-
Methods that are already overridden by other candidates are ignored. This circumstance can arise when supertypes share a common ancestor.
Consider the following interfaces and classes:
public interface Animal { default public String identifyMyself() { return "I am an animal."; } }
public interface EggLayer extends Animal { default public String identifyMyself() { return "I am able to lay eggs."; } }
public interface FireBreather extends Animal { }
public class Dragon implements EggLayer, FireBreather { public static void main (String... args) { Dragon myApp = new Dragon(); System.out.println(myApp.identifyMyself()); } }
The method
Dragon.identifyMyself
returns the stringI am able to lay eggs.
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 (OperateCar
and FlyCar
) that provide default implementations for the same method, (startEngine
):
public interface OperateCar { // ... default public int startEngine(EncryptedKey key) { // Implementation } }
public interface FlyCar { // ... default public int startEngine(EncryptedKey key) { // Implementation } }
A class that implements both OperateCar
and FlyCar
must override the method startEngine
. You could invoke any of the of the default implementations with the super
keyword.
public class FlyingCar implements OperateCar, FlyCar { // ... public int startEngine(EncryptedKey key) { FlyCar.super.startEngine(key); OperateCar.super.startEngine(key); } }
The name preceding super
(in this example, FlyCar
or OperateCar
) 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 super
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 interface Mammal { String identifyMyself(); }
public class Horse { public String identifyMyself() { return "I am a horse."; } }
public class Mustang extends Horse implements Mammal { public static void main(String... args) { Mustang myApp = new Mustang(); System.out.println(myApp.identifyMyself()); } }
The method Mustang.identifyMyself
returns the string I am a horse.
The class Mustang
inherits the method identifyMyself
from the class Horse
, which overrides the abstract method of the same name in the interface Mammal
.
Note: Static methods in interfaces are never inherited.
Modifiers
The 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.
Summary
The following table summarizes what happens when you define a method with the same signature as a method in a superclass.
Superclass Instance Method | Superclass Static Method | |
---|---|---|
Subclass Instance Method | Overrides | Generates a compile-time error |
Subclass Static Method | Generates a compile-time error | Hides |
Note: In a subclass, you can overload the methods inherited from the superclass. Such overloaded methods neither hide nor override the superclass instance methods—they are new methods, unique to the subclass.
重写与重载之间的区别
区别点 | 重载方法 | 重写方法 |
---|---|---|
参数列表 | 必须修改 | 一定不能修改 |
返回类型 | 可以修改 | 一定不能修改 |
异常 | 可以修改 | 可以减少或删除,一定不能抛出新的或者更广的异常 |
访问 | 可以修改 | 一定不能做更严格的限制(可以降低限制) |
总结
方法的重写(Overriding)和重载(Overloading)是java多态性的不同表现,重写是父类与子类之间多态性的一种表现,重载可以理解成多态的具体表现形式。
- (1)方法重载是一个类中定义了多个方法名相同,而他们的参数的数量不同或数量相同而类型和次序不同,则称为方法的重载(Overloading)。
- (2)方法重写是在子类存在方法与父类的方法的名字相同,而且参数的个数与类型一样,返回值也一样的方法,就称为重写(Overriding)。
- (3)方法重载是一个类的多态性表现,而方法重写是子类与父类的一种多态性表现。
Java 重写(Override)与重载(Overload)
重写(Override)
重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!
重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。
重写方法不能抛出新的检查异常或者比被重写方法申明更加宽泛的异常。例如: 父类的一个方法申明了一个检查异常 IOException,但是在重写这个方法的时候不能抛出 Exception 异常,因为 Exception 是 IOException 的父类,只能抛出 IOException 的子类异常。
在面向对象原则里,重写意味着可以重写任何现有方法。实例如下:
TestDog.java 文件代码:
以上实例编译运行结果如下:
动物可以移动
狗可以跑和走
在上面的例子中可以看到,尽管b属于Animal类型,但是它运行的是Dog类的move方法。
这是由于在编译阶段,只是检查参数的引用类型。
然而在运行时,Java虚拟机(JVM)指定对象的类型并且运行该对象的方法。
因此在上面的例子中,之所以能编译成功,是因为Animal类中存在move方法,然而运行时,运行的是特定对象的方法。
思考以下例子:
TestDog.java 文件代码:
以上实例编译运行结果如下:
TestDog.java:30: cannot find symbol
symbol : method bark()
location: class Animal
b.bark();
^
该程序将抛出一个编译错误,因为b的引用类型Animal没有bark方法。
方法的重写规则
- 参数列表必须完全与被重写方法的相同;
- 返回类型必须完全与被重写方法的返回类型相同;
- 访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为public,那么在子类中重写该方法就不能声明为protected。
- 父类的成员方法只能被它的子类重写。
- 声明为final的方法不能被重写。
- 声明为static的方法不能被重写,但是能够被再次声明。
- 子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为private和final的方法。
- 子类和父类不在同一个包中,那么子类只能够重写父类的声明为public和protected的非final方法。
- 重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。
- 构造方法不能被重写。
- 如果不能继承一个方法,则不能重写这个方法。
Super关键字的使用
当需要在子类中调用父类的被重写方法时,要使用super关键字。
TestDog.java 文件代码:
以上实例编译运行结果如下:
动物可以移动
狗可以跑和走
重载(Overload)
重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。
每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。
最常用的地方就是构造器的重载。
重载规则:
- 被重载的方法必须改变参数列表(参数个数或类型不一样);
- 被重载的方法可以改变返回类型;
- 被重载的方法可以改变访问修饰符;
- 被重载的方法可以声明新的或更广的检查异常;
- 方法能够在同一个类中或者在一个子类中被重载。
- 无法以返回值类型作为重载函数的区分标准。
实例
Overloading.java 文件代码:
Java 中override、overload、overwrite区别,以及与多态的关系 - youJumpILook - 博客园 https://www.cnblogs.com/darknife/archive/2013/10/23/3384127.html
Java 中override、overload、overwrite区别,以及与多态的关系
from:http://blog.csdn.net/lzhang007/article/details/7960950
一
overload:是重载的意思,这没啥能混淆的了,就是在同一个类当中,为了增加通用性,写了很多方法,这些方法只有一个要求,参数的数量和类型不同,但返回值和方法属性必须相同,否则不属于重载,
比如:1.public class Parent{
public int add(int a, int b){}
public int add(int a,float b){}
public int add(int a,int b,float c){}
以上均属于overload
protected int add(int a,float b){}
public float add(int a,float b){} }(注意:java中明确声明在同一个类中两个方法名字和参数相同而返回值不同是不被允许的)
public class Child extends Parent{
public int add(int a,float b){}(这种在The Java™ Tutorial Fourth Edition中也称作overload但是跟superclass中的同名方法是两种完全不同的方法)
}
均不属于overload
参考:http://docs.oracle.com/javase/tutorial/java/javaOO/methods.html
提示:Note: Overloaded methods should be used sparingly, as they can make code much less readable.
它不决定java的多态
二
override有人翻译是重写,有人翻译是覆写,覆盖等。其实我认为是一种扩展
因为它是在父类中声明方法(一般是抽象的),在子类中根据需求去具体定义方法的行为(即modify behavior as needed)
它要求override的方法有相同的名字、相同的参数、相同的返回值类型(即the same name, number and type of parameters, and return type)
它是一种晚绑定,是决定java多态的一种方式
参考:http://docs.oracle.com/javase/tutorial/java/IandI/override.html
三
overwrite:java中就没有它的存在,就别以讹传讹了,java官方文档没有该词的出现,但是国外有人把overwrite解释为override,
比如:http://stackoverflow.com/questions/837864/java-overloading-vs-overwriting
Overriding, which is what I think you mean by "overwriting" is the act of providing a different implementation of a method inherited from a base type, and is basically the point of polymorphism by inheritance, i.e.
public class Bicycle implements Vehicle { public void drive() { ... } } public class Motorcycle extends Bicycle { public void drive() { // Do motorcycle-specific driving here, overriding Bicycle.drive() // (we can still call the base method if it's useful to us here) } }
C++ 重载运算符和重载函数 | 菜鸟教程 https://www.runoob.com/cplusplus/cpp-overloading.html
C++ 重载运算符和重载函数
C++ 允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载。
重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是它们的参数列表和定义(实现)不相同。
当您调用一个重载函数或重载运算符时,编译器通过把您所使用的参数类型与定义中的参数类型进行比较,决定选用最合适的定义。选择最合适的重载函数或重载运算符的过程,称为重载决策。
C++ 中的函数重载
在同一个作用域内,可以声明几个功能类似的同名函数,但是这些同名函数的形式参数(指参数的个数、类型或者顺序)必须不同。您不能仅通过返回类型的不同来重载函数。
下面的实例中,同名函数 print() 被用于输出不同的数据类型:
实例
当上面的代码被编译和执行时,它会产生下列结果:
整数为: 5
浮点数为: 500.263
字符串为: Hello C++
C++ 中的运算符重载
您可以重定义或重载大部分 C++ 内置的运算符。这样,您就能使用自定义类型的运算符。
重载的运算符是带有特殊名称的函数,函数名是由关键字 operator 和其后要重载的运算符符号构成的。与其他函数一样,重载运算符有一个返回类型和一个参数列表。
Box operator+(const Box&);
声明加法运算符用于把两个 Box 对象相加,返回最终的 Box 对象。大多数的重载运算符可被定义为普通的非成员函数或者被定义为类成员函数。如果我们定义上面的函数为类的非成员函数,那么我们需要为每次操作传递两个参数,如下所示:
Box operator+(const Box&, const Box&);
下面的实例使用成员函数演示了运算符重载的概念。在这里,对象作为参数进行传递,对象的属性使用 this 运算符进行访问,如下所示: