在Java中,当有人问:
什么是多态性?
重载或重写是可以接受的答案吗?
我认为事情远不止如此。
如果你有一个抽象基类,它定义了一个没有实现的方法,并且你在子类中定义了这个方法,这仍然是覆盖的吗?
我认为超负荷肯定不是正确的答案。
在Java中,当有人问:
什么是多态性?
重载或重写是可以接受的答案吗?
我认为事情远不止如此。
如果你有一个抽象基类,它定义了一个没有实现的方法,并且你在子类中定义了这个方法,这仍然是覆盖的吗?
我认为超负荷肯定不是正确的答案。
当前回答
重写和重载都用于实现多态性。
你可以在一个类中有一个方法 它在或中被覆盖 更多的子类。这个方法可以 不同的东西取决于哪个 类用于实例化对象。
abstract class Beverage {
boolean isAcceptableTemperature();
}
class Coffee extends Beverage {
boolean isAcceptableTemperature() {
return temperature > 70;
}
}
class Wine extends Beverage {
boolean isAcceptableTemperature() {
return temperature < 10;
}
}
你也可以有一种方法 用两组或多组参数重载。这个方法可以 不同的东西基于 传递的参数类型。
class Server {
public void pour (Coffee liquid) {
new Cup().fillToTopWith(liquid);
}
public void pour (Wine liquid) {
new WineGlass().fillHalfwayWith(liquid);
}
public void pour (Lemonade liquid, boolean ice) {
Glass glass = new Glass();
if (ice) {
glass.fillToTopWith(new Ice());
}
glass.fillToTopWith(liquid);
}
}
其他回答
重载是指定义两个名称相同但参数不同的方法
重写是通过子类中具有相同名称的函数更改基类的行为。
所以多态性与覆盖有关,但不是真正的重载。
然而,如果有人对“什么是多态性?”这个问题给出了一个简单的“重写”的答案。我要求进一步解释。
术语重载指的是具有相同名称的东西的多个版本,通常是具有不同参数列表的方法
public int DoSomething(int objectId) { ... }
public int DoSomething(string objectName) { ... }
这些函数可能做同样的事情但你可以选择用ID或名称来调用它。与继承、抽象类等无关。
覆盖通常指的是多态性,就像你在问题中描述的那样
具体地说重载或重写并没有给出全貌。多态性就是对象根据其类型专门化其行为的能力。
我不同意这里的一些答案,因为重载是一种多态形式(参数多态),在这种情况下,具有相同名称的方法可以具有不同的行为,给出不同的参数类型。一个很好的例子是操作符重载。您可以定义“+”来接受不同类型的参数——例如字符串或int型——并且基于这些类型,“+”将具有不同的行为。
多态性还包括继承和重写方法,尽管它们在基类型中可以是抽象的或虚拟的。在基于继承的多态性方面,Java只支持单个类继承,将其多态行为限制为单个基类型链。Java支持多个接口的实现,这是另一种形式的多态行为。
经典的例子,狗和猫是动物,动物有制造声音的方法。我可以迭代调用makeNoise的动物数组,并期望它们在各自的实现。
调用代码不需要知道它们是什么特定的动物。
这就是我所说的多态性。
import java.io.IOException;
class Super {
protected Super getClassName(Super s) throws IOException {
System.out.println(this.getClass().getSimpleName() + " - I'm parent");
return null;
}
}
class SubOne extends Super {
@Override
protected Super getClassName(Super s) {
System.out.println(this.getClass().getSimpleName() + " - I'm Perfect Overriding");
return null;
}
}
class SubTwo extends Super {
@Override
protected Super getClassName(Super s) throws NullPointerException {
System.out.println(this.getClass().getSimpleName() + " - I'm Overriding and Throwing Runtime Exception");
return null;
}
}
class SubThree extends Super {
@Override
protected SubThree getClassName(Super s) {
System.out.println(this.getClass().getSimpleName()+ " - I'm Overriding and Returning SubClass Type");
return null;
}
}
class SubFour extends Super {
@Override
protected Super getClassName(Super s) throws IOException {
System.out.println(this.getClass().getSimpleName()+ " - I'm Overriding and Throwing Narrower Exception ");
return null;
}
}
class SubFive extends Super {
@Override
public Super getClassName(Super s) {
System.out.println(this.getClass().getSimpleName()+ " - I'm Overriding and have broader Access ");
return null;
}
}
class SubSix extends Super {
public Super getClassName(Super s, String ol) {
System.out.println(this.getClass().getSimpleName()+ " - I'm Perfect Overloading ");
return null;
}
}
class SubSeven extends Super {
public Super getClassName(SubSeven s) {
System.out.println(this.getClass().getSimpleName()+ " - I'm Perfect Overloading because Method signature (Argument) changed.");
return null;
}
}
public class Test{
public static void main(String[] args) throws Exception {
System.out.println("Overriding\n");
Super s1 = new SubOne(); s1.getClassName(null);
Super s2 = new SubTwo(); s2.getClassName(null);
Super s3 = new SubThree(); s3.getClassName(null);
Super s4 = new SubFour(); s4.getClassName(null);
Super s5 = new SubFive(); s5.getClassName(null);
System.out.println("Overloading\n");
SubSix s6 = new SubSix(); s6.getClassName(null, null);
s6 = new SubSix(); s6.getClassName(null);
SubSeven s7 = new SubSeven(); s7.getClassName(s7);
s7 = new SubSeven(); s7.getClassName(new Super());
}
}