在Java中,当有人问:
什么是多态性?
重载或重写是可以接受的答案吗?
我认为事情远不止如此。
如果你有一个抽象基类,它定义了一个没有实现的方法,并且你在子类中定义了这个方法,这仍然是覆盖的吗?
我认为超负荷肯定不是正确的答案。
在Java中,当有人问:
什么是多态性?
重载或重写是可以接受的答案吗?
我认为事情远不止如此。
如果你有一个抽象基类,它定义了一个没有实现的方法,并且你在子类中定义了这个方法,这仍然是覆盖的吗?
我认为超负荷肯定不是正确的答案。
当前回答
具体地说重载或重写并没有给出全貌。多态性就是对象根据其类型专门化其行为的能力。
我不同意这里的一些答案,因为重载是一种多态形式(参数多态),在这种情况下,具有相同名称的方法可以具有不同的行为,给出不同的参数类型。一个很好的例子是操作符重载。您可以定义“+”来接受不同类型的参数——例如字符串或int型——并且基于这些类型,“+”将具有不同的行为。
多态性还包括继承和重写方法,尽管它们在基类型中可以是抽象的或虚拟的。在基于继承的多态性方面,Java只支持单个类继承,将其多态行为限制为单个基类型链。Java支持多个接口的实现,这是另一种形式的多态行为。
其他回答
具体地说重载或重写并没有给出全貌。多态性就是对象根据其类型专门化其行为的能力。
我不同意这里的一些答案,因为重载是一种多态形式(参数多态),在这种情况下,具有相同名称的方法可以具有不同的行为,给出不同的参数类型。一个很好的例子是操作符重载。您可以定义“+”来接受不同类型的参数——例如字符串或int型——并且基于这些类型,“+”将具有不同的行为。
多态性还包括继承和重写方法,尽管它们在基类型中可以是抽象的或虚拟的。在基于继承的多态性方面,Java只支持单个类继承,将其多态行为限制为单个基类型链。Java支持多个接口的实现,这是另一种形式的多态行为。
多态是指多个形式,同一对象根据需求执行不同的操作。
多态可以通过以下两种方式实现
方法重写 方法重载
方法重载是指使用相同的方法名在同一个类中编写两个或多个方法,但传递的参数不同。
方法重写意味着我们在不同的类中使用方法名,这意味着父类的方法在子类中使用。
在Java中,为了实现多态,父类引用变量可以容纳子类对象。
为了实现多态,每个开发人员必须在项目中使用相同的方法名。
下面是伪c# /Java中的多态性示例:
class Animal
{
abstract string MakeNoise ();
}
class Cat : Animal {
string MakeNoise () {
return "Meow";
}
}
class Dog : Animal {
string MakeNoise () {
return "Bark";
}
}
Main () {
Animal animal = Zoo.GetAnimal ();
Console.WriteLine (animal.MakeNoise ());
}
Main函数不知道动物的类型,并且依赖于MakeNoise()方法的特定实现的行为。
编辑:看来布莱恩先我一步了。有趣的是我们用了同样的例子。但是上面的代码应该有助于阐明概念。
什么是多态性?
来自java教程
多态性的字典定义是指生物学中的一个原理,在这个原理中,一个有机体或物种可以有许多不同的形式或阶段。这个原则也可以应用于面向对象编程和Java语言等语言。类的子类可以定义它们自己独特的行为,同时还可以共享父类的一些相同功能。
通过对实例和定义的考虑,应采用覆盖式回答。
关于你的第二个问题:
如果你有一个抽象基类,它定义了一个没有实现的方法,并且你在子类中定义了这个方法,这仍然是覆盖的吗?
它应该被称为重写。
看一下这个例子,了解不同类型的覆盖。
基类不提供实现,子类必须重写完整方法-(抽象) 基类提供默认实现,子类可以改变行为 子类通过调用super.methodName()作为第一条语句向基类实现添加扩展 基类定义了算法的结构(Template方法),子类将覆盖算法的一部分
代码片段:
import java.util.HashMap;
abstract class Game implements Runnable{
protected boolean runGame = true;
protected Player player1 = null;
protected Player player2 = null;
protected Player currentPlayer = null;
public Game(){
player1 = new Player("Player 1");
player2 = new Player("Player 2");
currentPlayer = player1;
initializeGame();
}
/* Type 1: Let subclass define own implementation. Base class defines abstract method to force
sub-classes to define implementation
*/
protected abstract void initializeGame();
/* Type 2: Sub-class can change the behaviour. If not, base class behaviour is applicable */
protected void logTimeBetweenMoves(Player player){
System.out.println("Base class: Move Duration: player.PlayerActTime - player.MoveShownTime");
}
/* Type 3: Base class provides implementation. Sub-class can enhance base class implementation by calling
super.methodName() in first line of the child class method and specific implementation later */
protected void logGameStatistics(){
System.out.println("Base class: logGameStatistics:");
}
/* Type 4: Template method: Structure of base class can't be changed but sub-class can some part of behaviour */
protected void runGame() throws Exception{
System.out.println("Base class: Defining the flow for Game:");
while ( runGame) {
/*
1. Set current player
2. Get Player Move
*/
validatePlayerMove(currentPlayer);
logTimeBetweenMoves(currentPlayer);
Thread.sleep(500);
setNextPlayer();
}
logGameStatistics();
}
/* sub-part of the template method, which define child class behaviour */
protected abstract void validatePlayerMove(Player p);
protected void setRunGame(boolean status){
this.runGame = status;
}
public void setCurrentPlayer(Player p){
this.currentPlayer = p;
}
public void setNextPlayer(){
if ( currentPlayer == player1) {
currentPlayer = player2;
}else{
currentPlayer = player1;
}
}
public void run(){
try{
runGame();
}catch(Exception err){
err.printStackTrace();
}
}
}
class Player{
String name;
Player(String name){
this.name = name;
}
public String getName(){
return name;
}
}
/* Concrete Game implementation */
class Chess extends Game{
public Chess(){
super();
}
public void initializeGame(){
System.out.println("Child class: Initialized Chess game");
}
protected void validatePlayerMove(Player p){
System.out.println("Child class: Validate Chess move:"+p.getName());
}
protected void logGameStatistics(){
super.logGameStatistics();
System.out.println("Child class: Add Chess specific logGameStatistics:");
}
}
class TicTacToe extends Game{
public TicTacToe(){
super();
}
public void initializeGame(){
System.out.println("Child class: Initialized TicTacToe game");
}
protected void validatePlayerMove(Player p){
System.out.println("Child class: Validate TicTacToe move:"+p.getName());
}
}
public class Polymorphism{
public static void main(String args[]){
try{
Game game = new Chess();
Thread t1 = new Thread(game);
t1.start();
Thread.sleep(1000);
game.setRunGame(false);
Thread.sleep(1000);
game = new TicTacToe();
Thread t2 = new Thread(game);
t2.start();
Thread.sleep(1000);
game.setRunGame(false);
}catch(Exception err){
err.printStackTrace();
}
}
}
输出:
Child class: Initialized Chess game
Base class: Defining the flow for Game:
Child class: Validate Chess move:Player 1
Base class: Move Duration: player.PlayerActTime - player.MoveShownTime
Child class: Validate Chess move:Player 2
Base class: Move Duration: player.PlayerActTime - player.MoveShownTime
Base class: logGameStatistics:
Child class: Add Chess specific logGameStatistics:
Child class: Initialized TicTacToe game
Base class: Defining the flow for Game:
Child class: Validate TicTacToe move:Player 1
Base class: Move Duration: player.PlayerActTime - player.MoveShownTime
Child class: Validate TicTacToe move:Player 2
Base class: Move Duration: player.PlayerActTime - player.MoveShownTime
Base class: logGameStatistics:
术语重载指的是具有相同名称的东西的多个版本,通常是具有不同参数列表的方法
public int DoSomething(int objectId) { ... }
public int DoSomething(string objectName) { ... }
这些函数可能做同样的事情但你可以选择用ID或名称来调用它。与继承、抽象类等无关。
覆盖通常指的是多态性,就像你在问题中描述的那样