class DonkeyBattler {
static void doBattle(){
System.out.println("Weaponized donkey battling");
}
}
class FunkyBattler extends DonkeyBattler {
static void doBattle(){
System.out.println("Weaponized donkey battling with bellbottoms");
}
}
doBattle方法应该是重新定义还是覆盖?哦,顺便说一句,这就是Java。
答案 0 :(得分:12)
我从来没有听说过“重新定义”作为适用于Java的OO术语。
但是,您提供的示例是 not 覆盖,因为静态方法不是继承的,而是基于变量的类型静态分派(与成员方法发生的动态分派相反) )。
我不会称之为 re 定义,但是你有一个名为DonkeyBattler.doBattle
的方法,现在你已经定义了一个名为FunkyBattler.doBattle
的编译独立方法。
答案 1 :(得分:6)
术语“重定义”通常不用于Java方法和继承。通常使用两个术语:如你所说的“覆盖”和“重载”。在Java中重载是在同一个类中创建两个具有相同名称但签名不同的方法(参数的数量和/或类型)。例如:
public interface MyInterface
{
public int doStuff(int first, int second);
public int doStuff(double only);
}
要覆盖是执行类似于您在示例中所执行的操作:使用具有相同名称和签名的方法创建子类,作为将使用的父类中的方法对于子类的所有实例,但不包括父类的任何实例或该父类的任何其他子类。
您的示例与重载相关的唯一问题是使用关键字static
。覆盖是动态确定的,但根据定义静态方法不是。
答案 2 :(得分:3)
覆盖的意图实际上是从父类重新定义继承的方法。
重新定义涉及:
替换
1. **Replacement** is the case in which child class is overriding
具有行为(功能)的父类的继承方法与相应的父方法完全不同,并且这个过程的符号不是在子方法体中调用super.method()。
细化
2. Refinement is the case in which child is overriding inherited
来自父级的方法具有与父方法功能相关的功能,此过程的符号通常在子方法的主体中调用super.method()。
答案 3 :(得分:2)
一个方法只能在同一个类中重载,这是一个错误的概念。 相反,方法也可以在子类中重载。
答案 4 :(得分:2)
覆盖和重新定义(也称为隐藏)几乎是一些东西,除了:
覆盖是例如方法,重新定义或隐藏用于Class方法。仅在静态方法的情况下重新定义,因为静态方法没有运行时多态性。
请参阅以下代码以澄清:
class Foo {
public static void classMethod()
{
SOP("classMethod() in Foo");
}
public void instanceMethod()
{
SOP ("instanceMethod() in Foo");
}
}
class Bar extends Foo {
public static void class Method()
{
SOP ("classMethod() in Bar");
}
public void instanceMethod() {
SOP ("instanceMethod() in Bar");
}
}
class Test {
public static void main(String[] args) {
Foo f = new Bar();
f.instanceMethod();
f.classMethod();
}
}
此代码的输出为: Bar中的instanceMethod() Foo中的classMethod()
此输出的原因:
由于instanceMethod()是一个实例方法,其中Bar在运行时覆盖了Foo中的方法,J.V.M。使用实例f的实际类来确定要运行的方法。虽然f被声明为Foo,但我们创建的实际实例是一个新的Bar()。所以在运行时,J.V.M。发现f是一个Bar实例,所以它调用Bar中的instanceMethod()而不是Foo中的实例。
使用classMethod(),因为它是一个类方法,编译器和J.V.M.不要指望需要一个实际的实例来调用该方法。即使你提供一个J.V.M.永远不会看它。编译器只会查看引用的声明类型,并使用该声明的类型在编译时确定要调用的方法。由于f被声明为Foo类型,编译器会查看f.classMethod()并确定它意味着Foo。类方法。 f引用的实例实际上是一个Bar并不重要 - 对于静态方法,编译器只使用声明的引用类型。
这就是为什么我在开始时说静态方法没有运行时多态性。
答案 5 :(得分:0)
重新定义对Java有效,适用于静态方法。如果要更改静态方法对类的作用,可以重新定义它。这不受多态性的影响,因为它不适用于静态方法。
使用您的示例,对类名称或所有子类的所有调用都将获得原始的doBattle( )
方法。对FunkyBattler.doBattle()
的特定调用将调用FunkyBattler
类中重新定义的静态方法。
答案 6 :(得分:0)
你有方法“doBattle”这是静态并且在Java静态方法中无法覆盖,这并不意味着它们不能在子类中重新定义,因此,您要在 FunkyBattler 类中重新定义 doBatler 方法 DonkeyBattler
的子类答案 7 :(得分:0)
public class Animal{
public static void doStuff(){
System.out.println("In animal");
}
}
public class Dog extends Animal {
//redifinition of the method, since it is... Static
static void doStuff() {
System.out.println("In Dog...");
}
public static void main(String[] args) {
Animal animal = new Dog();
animal.doStuff();
}
}
即使你调用了静态的Dog引用方法,输出仍然是'动物',你应该推断出运行时多态性不会像OVERRIDING一样工作。
答案 8 :(得分:-1)
重新定义和覆盖在相同的场景中出现。唯一不同的是,如果使用的方法是静态,则重新定义。
例如:
<强>重写:强>
Class A{
public void show(){
SOP("class a");
}
}
Class B extends A{
public void show(){
SOP("class B");
}
}
<强>重新定义强>
Class A{
public static void show(){
SOP("class a");
}
}
Class B extends A{
public static void show(){
SOP("class B");
}
}
注意:静态方法看起来好像被过度使用,但实际上是重新定义的。