Bri*_*n G 340 java oop polymorphism overriding overloading
就Java而言,当有人问:
什么是多态?
将超载或重载是一个可以接受的答案?
我认为还有更多的东西.
如果您有一个抽象基类定义了一个没有实现的方法,并且您在子类中定义了该方法,那还是会覆盖吗?
我认为超载肯定不是正确的答案.
Chr*_*ore 881
表达多态性的最清晰方式是通过抽象基类(或接口)
public abstract class Human{
...
public abstract void goPee();
}
Run Code Online (Sandbox Code Playgroud)
这个类是抽象的,因为这个goPee()方法不适用于人类.它只适用于男性和女性的子类.此外,人类是一个抽象的概念 - 你不能创造一个既不是男性也不是女性的人.它必须是一个或另一个.
所以我们通过使用抽象类来推迟实现.
public class Male extends Human{
...
@Override
public void goPee(){
System.out.println("Stand Up");
}
}
Run Code Online (Sandbox Code Playgroud)
和
public class Female extends Human{
...
@Override
public void goPee(){
System.out.println("Sit Down");
}
}
Run Code Online (Sandbox Code Playgroud)
现在我们可以告诉整个房间充满了人类去撒尿.
public static void main(String[] args){
ArrayList<Human> group = new ArrayList<Human>();
group.add(new Male());
group.add(new Female());
// ... add more...
// tell the class to take a pee break
for (Human person : group) person.goPee();
}
Run Code Online (Sandbox Code Playgroud)
运行这将产生:
Stand Up
Sit Down
...
Run Code Online (Sandbox Code Playgroud)
The*_*beg 94
多态性是类实例的行为能力,就好像它是其继承树中另一个类的实例,通常是其祖先类之一.例如,在Java中,所有类都继承自Object.因此,您可以创建Object类型的变量,并为其分配任何类的实例.
一个覆盖是一种函数,它发生在一个继承自另一个类的类中.覆盖函数"替换"从基类继承的函数,但这样做的方式是,即使其类的实例假装通过多态而成为不同的类型,也会调用它.参考前面的示例,您可以定义自己的类并覆盖toString()函数.因为此函数是从Object继承的,所以如果将此类的实例复制到Object类型变量中,它仍然可用.通常,如果在假装是Object时调用类上的toString(),实际触发的toString版本就是在Object本身定义的版本.但是,因为函数是一个覆盖,所以即使在类实例中,也会使用类中toString()的定义.
重载是定义具有相同名称但具有不同参数的多个方法的操作.它与重写或多态无关.
Mar*_*osi 43
这是伪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 ());
}
Run Code Online (Sandbox Code Playgroud)
Main函数不知道动物的类型,并且取决于MakeNoise()方法的特定实现的行为.
编辑:看起来Brian打败了我.有趣的是我们使用相同的例子.但上面的代码应该有助于澄清这些概念.
小智 43
多态性是指不止一种形式,同一对象根据需要执行不同的操作.
多态性可以通过两种方式实现,即那些方式
方法重载意味着使用相同的方法名称在同一个类中编写两个或多个方法,但传递参数不同.
方法重写意味着我们在不同的类中使用方法名称,这意味着在子类中使用父类方法.
在Java中实现多态,超类引用变量可以保存子类对象.
要实现多态性,每个开发人员必须在项目中使用相同的方法名称.
Pat*_*ney 39
覆盖和重载都用于实现多态性.
您可以在一个或多个子类中重写的类中拥有一个方法.该方法根据用于实例化对象的类来执行不同的操作.
abstract class Beverage {
boolean isAcceptableTemperature();
}
class Coffee extends Beverage {
boolean isAcceptableTemperature() {
return temperature > 70;
}
}
class Wine extends Beverage {
boolean isAcceptableTemperature() {
return temperature < 10;
}
}
Run Code Online (Sandbox Code Playgroud)
您还可以使用两个或多个参数集重载的方法 .该方法根据传递的参数类型执行不同的操作.
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);
}
}
Run Code Online (Sandbox Code Playgroud)
Ale*_*x B 14
你是正确的,重载不是答案.
两者都不是最重要的.覆盖是获得多态性的手段.多态性是对象根据其类型改变行为的能力.当展示多态性的对象的调用者不知道对象是什么特定类型时,这是最好的证明.
Pet*_*yer 11
特别是说重载或覆盖不能全面展示.多态性只是一个对象根据其类型专门化其行为的能力.
我不同意这里的一些答案,因为在具有相同名称的方法可以表现不同的情况下,重载是多态(参数多态)的一种形式,给出不同的参数类型.一个很好的例子是运算符重载.您可以定义"+"以接受不同类型的参数 - 比如字符串或int - 并且基于这些类型,"+"将表现不同.
多态性还包括继承和重写方法,尽管它们可以是基本类型中的抽象或虚拟.就基于继承的多态性而言,Java仅支持单类继承,将其多态行为限制为单个基类型链的行为.Java确实支持多接口的实现,这是多态行为的另一种形式.
小智 7
多态只是意味着"多种形式".
它没有要求继承来实现...因为接口实现(根本不是继承)满足多态需求.可以说,接口实现为继承提供了"更好"的多态需求.
例如,你会创建一个超类来描述所有可以飞行的东西吗?我不应该想.您最好能够创建一个描述航班的界面并将其留在那里.
因此,由于接口描述了行为,并且方法名称描述了行为(对程序员而言),因此将方法重载视为较小形式的多态性并不是一件容易的事.
多态性是一个对象以多种形式出现的能力。这涉及到使用继承和虚函数来构建一系列可以互换的对象。基类包含虚拟函数的原型,可能未实现或具有应用程序指定的默认实现,并且各个派生类各自以不同的方式实现它们以影响不同的行为。
经典的例子,狗和猫是动物,动物有makeNoise的方法.我可以遍历一系列动物,在它们上面调用makeNoise,并期望它们会在那里进行相应的实现.
调用代码不必知道它们是什么特定的动物.
这就是我认为的多态性.
重载是指定义两个名称相同但参数不同的方法
重写是通过子类中具有相同名称的函数来更改基类的行为。
所以多态性与重写有关,但与真正的重载无关。
然而,如果有人对“什么是多态性?”这个问题给了我一个简单的“重写”答案。我想要求进一步的解释。
虽然在这篇文章中已经详细解释了多态性,但我想更加强调为什么是它的一部分。
为什么多态在任何 OOP 语言中都如此重要。
让我们尝试为有和没有继承/多态性的电视构建一个简单的应用程序。发布应用程序的每个版本,我们做一个小的回顾。
假设您是一家电视公司的软件工程师,您需要为 Volume、Brightness 和 Color 控制器编写软件,以根据用户命令增加和减少它们的值。
您首先通过添加为这些功能中的每一个编写类
应用程序版本 1
import java.util.Scanner;
class VolumeControllerV1 {
private int value;
int get() {
return value;
}
void set(int value) {
System.out.println("Old value of VolumeController \t"+this.value);
this.value = value;
System.out.println("New value of VolumeController \t"+this.value);
}
void adjust(int value) {
int temp = this.get();
if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0))) {
System.out.println("Can not adjust any further");
return;
}
this.set(temp + value);
}
}
class BrightnessControllerV1 {
private int value;
int get() {
return value;
}
void set(int value) {
System.out.println("Old value of BrightnessController \t"+this.value);
this.value = value;
System.out.println("New value of BrightnessController \t"+this.value);
}
void adjust(int value) {
int temp = this.get();
if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0))) {
System.out.println("Can not adjust any further");
return;
}
this.set(temp + value);
}
}
class ColourControllerV1 {
private int value;
int get() {
return value;
}
void set(int value) {
System.out.println("Old value of ColourController \t"+this.value);
this.value = value;
System.out.println("New value of ColourController \t"+this.value);
}
void adjust(int value) {
int temp = this.get();
if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0))) {
System.out.println("Can not adjust any further");
return;
}
this.set(temp + value);
}
}
/*
* There can be n number of controllers
* */
public class TvApplicationV1 {
public static void main(String[] args) {
VolumeControllerV1 volumeControllerV1 = new VolumeControllerV1();
BrightnessControllerV1 brightnessControllerV1 = new BrightnessControllerV1();
ColourControllerV1 colourControllerV1 = new ColourControllerV1();
OUTER: while(true) {
Scanner sc=new Scanner(System.in);
System.out.println(" Enter your option \n Press 1 to increase volume \n Press 2 to decrease volume");
System.out.println(" Press 3 to increase brightness \n Press 4 to decrease brightness");
System.out.println(" Press 5 to increase color \n Press 6 to decrease color");
System.out.println("Press any other Button to shutdown");
int button = sc.nextInt();
switch (button) {
case 1: {
volumeControllerV1.adjust(5);
break;
}
case 2: {
volumeControllerV1.adjust(-5);
break;
}
case 3: {
brightnessControllerV1.adjust(5);
break;
}
case 4: {
brightnessControllerV1.adjust(-5);
break;
}
case 5: {
colourControllerV1.adjust(5);
break;
}
case 6: {
colourControllerV1.adjust(-5);
break;
}
default:
System.out.println("Shutting down...........");
break OUTER;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在您已经准备好部署我们的第一个工作应用程序版本。是时候分析迄今为止所做的工作了。
TV 应用程序版本 1 中的问题
只要您的应用程序按预期工作,您就决定接受它。
有时,您的老板会回来找您并要求您向现有应用程序添加重置功能。重置会将所有 3 个三个控制器设置为各自的默认值。
您开始为新功能编写一个新类 (ResetFunctionV2),并为这个新功能映射用户输入映射代码。
应用程序版本 2
import java.util.Scanner;
class VolumeControllerV2 {
private int defaultValue = 25;
private int value;
int getDefaultValue() {
return defaultValue;
}
int get() {
return value;
}
void set(int value) {
System.out.println("Old value of VolumeController \t"+this.value);
this.value = value;
System.out.println("New value of VolumeController \t"+this.value);
}
void adjust(int value) {
int temp = this.get();
if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0))) {
System.out.println("Can not adjust any further");
return;
}
this.set(temp + value);
}
}
class BrightnessControllerV2 {
private int defaultValue = 50;
private int value;
int get() {
return value;
}
int getDefaultValue() {
return defaultValue;
}
void set(int value) {
System.out.println("Old value of BrightnessController \t"+this.value);
this.value = value;
System.out.println("New value of BrightnessController \t"+this.value);
}
void adjust(int value) {
int temp = this.get();
if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0))) {
System.out.println("Can not adjust any further");
return;
}
this.set(temp + value);
}
}
class ColourControllerV2 {
private int defaultValue = 40;
private int value;
int get() {
return value;
}
int getDefaultValue() {
return defaultValue;
}
void set(int value) {
System.out.println("Old value of ColourController \t"+this.value);
this.value = value;
System.out.println("New value of ColourController \t"+this.value);
}
void adjust(int value) {
int temp = this.get();
if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0))) {
System.out.println("Can not adjust any further");
return;
}
this.set(temp + value);
}
}
class ResetFunctionV2 {
private VolumeControllerV2 volumeControllerV2 ;
private BrightnessControllerV2 brightnessControllerV2;
private ColourControllerV2 colourControllerV2;
ResetFunctionV2(VolumeControllerV2 volumeControllerV2, BrightnessControllerV2 brightnessControllerV2, ColourControllerV2 colourControllerV2) {
this.volumeControllerV2 = volumeControllerV2;
this.brightnessControllerV2 = brightnessControllerV2;
this.colourControllerV2 = colourControllerV2;
}
void onReset() {
volumeControllerV2.set(volumeControllerV2.getDefaultValue());
brightnessControllerV2.set(brightnessControllerV2.getDefaultValue());
colourControllerV2.set(colourControllerV2.getDefaultValue());
}
}
/*
* so on
* There can be n number of controllers
*
* */
public class TvApplicationV2 {
public static void main(String[] args) {
VolumeControllerV2 volumeControllerV2 = new VolumeControllerV2();
BrightnessControllerV2 brightnessControllerV2 = new BrightnessControllerV2();
ColourControllerV2 colourControllerV2 = new ColourControllerV2();
ResetFunctionV2 resetFunctionV2 = new ResetFunctionV2(volumeControllerV2, brightnessControllerV2, colourControllerV2);
OUTER: while(true) {
Scanner sc=new Scanner(System.in);
System.out.println(" Enter your option \n Press 1 to increase volume \n Press 2 to decrease volume");
System.out.println(" Press 3 to increase brightness \n Press 4 to decrease brightness");
System.out.println(" Press 5 to increase color \n Press 6 to decrease color");
System.out.println(" Press 7 to reset TV \n Press any other Button to shutdown");
int button = sc.nextInt();
switch (button) {
case 1: {
volumeControllerV2.adjust(5);
break;
}
case 2: {
volumeControllerV2.adjust(-5);
break;
}
case 3: {
brightnessControllerV2.adjust(5);
break;
}
case 4: {
brightnessControllerV2.adjust(-5);
break;
}
case 5: {
colourControllerV2.adjust(5);
break;
}
case 6: {
colourControllerV2.adjust(-5);
break;
}
case 7: {
resetFunctionV2.onReset();
break;
}
default:
System.out.println("Shutting down...........");
break OUTER;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
因此,您的应用程序已准备好具有重置功能。但是,现在你开始意识到
TV 应用程序版本 2 中的问题
同时,您从老板那里听说您可能需要添加一项功能,其中每个控制器在启动时都需要通过互联网从公司托管的驱动程序存储库中检查最新版本的驱动程序。
现在您开始认为要添加的这个新功能类似于重置功能,如果您不重构您的应用程序,应用程序问题 (V2) 将成倍增加。
您开始考虑使用继承,以便您可以利用 JAVA 的多态能力,并添加一个新的抽象类 (ControllerV3) 到
通过这些改进,您的电视应用程序版本 3 已准备就绪。
应用程序版本 3
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
abstract class ControllerV3 {
abstract void set(int value);
abstract int get();
void adjust(int value) {
int temp = this.get();
if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0))) {
System.out.println("Can not adjust any further");
return;
}
this.set(temp + value);
}
abstract void setDefault();
}
class VolumeControllerV3 extends ControllerV3 {
private int defaultValue = 25;
private int value;
public void setDefault() {
set(defaultValue);
}
int get() {
return value;
}
void set(int value) {
System.out.println("Old value of VolumeController \t"+this.value);
this.value = value;
System.out.println("New value of VolumeController \t"+this.value);
}
}
class BrightnessControllerV3 extends ControllerV3 {
private int defaultValue = 50;
private int value;
public void setDefault() {
set(defaultValue);
}
int get() {
return value;
}
void set(int value) {
System.out.println("Old value of BrightnessController \t"+this.value);
this.value = value;
System.out.println("New value of BrightnessController \t"+this.value);
}
}
class ColourControllerV3 extends ControllerV3 {
private int defaultValue = 40;
private int value;
public void setDefault() {
set(defaultValue);
}
int get() {
return value;
}
void set(int value) {
System.out.println("Old value of ColourController \t"+this.value);
this.value = value;
System.out.println("New value of ColourController \t"+this.value);
}
}
class ResetFunctionV3 {
private List<ControllerV3> controllers = null;
ResetFunctionV3(List<ControllerV3> controllers) {
this.controllers = controllers;
}
void onReset() {
for (ControllerV3 controllerV3 :this.controllers) {
controllerV3.setDefault();
}
}
}
/*
* so on
* There can be n number of controllers
*
* */
public class TvApplicationV3 {
public static void main(String[] args) {
VolumeControllerV3 volumeControllerV3 = new VolumeControllerV3();
BrightnessControllerV3 brightnessControllerV3 = new BrightnessControllerV3();
ColourControllerV3 colourControllerV3 = new ColourControllerV3();
List<ControllerV3> controllerV3s = new ArrayList<>();
controllerV3s.add(volumeControllerV3);
controllerV3s.add(brightnessControllerV3);
controllerV3s.add(colourControllerV3);
ResetFunctionV3 resetFunctionV3 = new ResetFunctionV3(controllerV3s);
OUTER: while(true) {
Scanner sc=new Scanner(System.in);
System.out.println(" Enter your option \n Press 1 to increase volume \n Press 2 to decrease volume");
System.out.println(" Press 3 to increase brightness \n Press 4 to decrease brightness");
System.out.println(" Press 5 to increase color \n Press 6 to decrease color");
System.out.println(" Press 7 to reset TV \n Press any other Button to shutdown");
int button = sc.nextInt();
switch (button) {
case 1: {
volumeControllerV3.adjust(5);
break;
}
case 2: {
volumeControllerV3.adjust(-5);
break;
}
case 3: {
brightnessControllerV3.adjust(5);
break;
}
case 4: {
brightnessControllerV3.adjust(-5);
break;
}
case 5: {
colourControllerV3.adjust(5);
break;
}
case 6: {
colourControllerV3.adjust(-5);
break;
}
case 7: {
resetFunctionV3.onReset();
break;
}
default:
System.out.println("Shutting down...........");
break OUTER;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
尽管 V2 的问题列表中列出的大部分问题都得到了解决,除了
TV 应用程序版本 3 中的问题
同样,您考虑解决这个问题,因为现在您还有另一个功能(启动时更新驱动程序)要实现。如果您不修复它,它也会被复制到新功能中。
所以你划分抽象类中定义的契约并为
并让您的第一个具体类实现它们,如下所示
应用程序版本 4
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
interface OnReset {
void setDefault();
}
interface OnStart {
void checkForDriverUpdate();
}
abstract class ControllerV4 implements OnReset,OnStart {
abstract void set(int value);
abstract int get();
void adjust(int value) {
int temp = this.get();
if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0))) {
System.out.println("Can not adjust any further");
return;
}
this.set(temp + value);
}
}
class VolumeControllerV4 extends ControllerV4 {
private int defaultValue = 25;
private int value;
@Override
int get() {
return value;
}
void set(int value) {
System.out.println("Old value of VolumeController \t"+this.value);
this.value = value;
System.out.println("New value of VolumeController \t"+this.value);
}
@Override
public void setDefault() {
set(defaultValue);
}
@Override
public void checkForDriverUpdate() {
System.out.println("Checking driver update for VolumeController .... Done");
}
}
class BrightnessControllerV4 extends ControllerV4 {
private int defaultValue = 50;
private int value;
@Override
int get() {
return value;
}
@Override
void set(int value) {
System.out.println("Old value of BrightnessController \t"+this.value);
this.value = value;
System.out.println("New value of BrightnessController \t"+this.value);
}
@Override
public void setDefault() {
set(defaultValue);
}
@Override
public void checkForDriverUpdate() {
System.out.println("Checking driver update for BrightnessController .... Done");
}
}
class ColourControllerV4 extends ControllerV4 {
private int defaultValue = 40;
private int value;
@Override
int get() {
return value;
}
void set(int value) {
System.out.println("Old value of ColourController \t"+this.value);
this.value = value;
System.out.println("New value of ColourController \t"+this.value);
}
@Override
public void setDefault() {
set(defaultValue);
}
@Override
public void checkForDriverUpdate() {
System.out.println("Checking driver update for ColourController .... Done");
}
}
class ResetFunctionV4 {
private List<OnReset> controllers = null;
ResetFunctionV4(List<OnReset> controllers) {
this.controllers = controllers;
}
void onReset() {
for (OnReset onreset :this.controllers) {
onreset.setDefault();
}
}
}
class InitializeDeviceV4 {
private List<OnStart> controllers = null;
InitializeDeviceV4(List<OnStart> controllers) {
this.controllers = controllers;
}
void initialize() {
for (OnStart onStart :this.controllers) {
onStart.checkForDriverUpdate();
}
}
}
/*
* so on
* There can be n number of controllers
*
* */
public class TvApplicationV4 {
public static void main(String[] args) {
VolumeControllerV4 volumeControllerV4 = new VolumeControllerV4();
BrightnessControllerV4 brightnessControllerV4 = new BrightnessControllerV4();
ColourControllerV4 colourControllerV4 = new ColourControllerV4();
List<ControllerV4> controllerV4s = new ArrayList<>();
controllerV4s.add(brightnessControllerV4);
controllerV4s.add(volumeControllerV4);
controllerV4s.add(colourControllerV4);
List<OnStart> controllersToInitialize = new ArrayList<>();
controllersToInitialize.addAll(controllerV4s);
InitializeDeviceV4 initializeDeviceV4 = new InitializeDeviceV4(controllersToInitialize);
initializeDeviceV4.initialize();
List<OnReset> controllersToReset = new ArrayList<>();
controllersToReset.addAll(controllerV4s);
ResetFunctionV4 resetFunctionV4 = new ResetFunctionV4(controllersToReset);
OUTER: while(true) {
Scanner sc=new Scanner(System.in);
System.out.println(" Enter your option \n Press 1 to increase volume \n Press 2 to decrease volume");
System.out.println(" Press 3 to increase brightness \n Press 4 to decrease brightness");
System.out.println(" Press 5 to increase color \n Press 6 to decrease color");
System.out.println(" Press 7 to reset TV \n Press any other Button to shutdown");
int button = sc.nextInt();
switch (button) {
case 1: {
volumeControllerV4.adjust(5);
break;