多vs压倒一切的vs超载
-
03-07-2019 - |
题
在爪哇,当有人问:
什么是多?
会 超载 或 压倒一切的 是一个可接受的回答?
我认为还有更多一点的还不止这一点。
如果你有一个抽象的基类定义的一个方法没有执行,并定义,方法是在子级,仍然overridding?
我认为 超载 不是正确答案是肯定的。
解决方案
表达多态性的最清晰方式是通过抽象基类(或接口)
public abstract class Human{
...
public abstract void goPee();
}
这个类是抽象的,因为 goPee()
方法不适用于人类。它只适用于男性和女性的子类。此外,人类是一个抽象概念—你不能创造一个既不是男性也不是女性的人。它必须是一个或另一个。
所以我们通过使用抽象类来推迟实现。
public class Male extends Human{
...
@Override
public void goPee(){
System.out.println("Stand Up");
}
}
和
public class Female extends Human{
...
@Override
public void goPee(){
System.out.println("Sit Down");
}
}
现在我们可以告诉整个房间里满是人类去撒尿。
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();
}
运行它会产生:
Stand Up
Sit Down
...
其他提示
多态性是类实例的行为能力,就好像它是其继承树中另一个类的实例,通常是其祖先类之一。例如,在Java中,所有类都继承自Object。因此,您可以创建一个Object类型的变量,并为其分配任何类的实例。
覆盖是一种函数,它发生在继承自另一个类的类中。覆盖功能“替换”功能从基类继承的函数,但这样做的方式是,即使它的类的实例假装通过多态而成为不同的类型,也会调用它。参考前面的示例,您可以定义自己的类并覆盖toString()函数。因为此函数是从Object继承的,所以如果将此类的实例复制到Object类型变量中,它仍然可用。通常,如果在假装是Object时调用类上的toString(),实际触发的toString版本就是在Object本身定义的版本。但是,因为函数是覆盖,所以即使类实例的真实类型隐藏在多态性之后,也会使用类中toString()的定义。
重载是定义具有相同名称但具有不同参数的多个方法的操作。它与重写或多态无关。
以下是伪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()方法的特定实现的行为。
编辑:看起来Brian打败了我。有趣的是我们使用相同的例子。但上述代码应该有助于澄清这些概念。
多态性是指多种形式,同一对象根据需要执行不同的操作。
多态性可以通过两种方式实现,即
- 方法覆盖
- 方法重载 醇>
方法重载意味着使用相同的方法名称在同一个类中编写两个或多个方法,但传递的参数不同。
方法覆盖意味着我们在不同的类中使用方法名称,这意味着在子类中使用了父类方法。
在Java中实现多态,超类引用变量可以保存子类对象。
要实现多态,每个开发人员必须在项目中使用相同的方法名称。
覆盖和重载都用于实现多态性。
你可以在课堂上有一个方法 在一个或中重写 更多的子类。该方法 不同的东西取决于哪个 class用于实例化一个对象。
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);
}
}
你知道重载不是答案。
两者都没有超越。覆盖是获得多态性的手段。多态性是对象根据其类型改变行为的能力。当展示多态性的对象的调用者不知道该对象的特定类型时,最好地证明这一点。
具体说超载或覆盖不能全面展示。多态性只是一个对象根据其类型专门化其行为的能力。
我不同意这里的一些答案,因为在具有相同名称的方法可以表现不同的情况下,重载是多态(参数多态)的一种形式,给出不同的参数类型。一个很好的例子是运算符重载。您可以定义“+”接受不同类型的参数 - 比如字符串或整数 - 并且基于这些类型,“+”表现不同。
多态性还包括继承和重写方法,尽管它们可以是基本类型中的抽象或虚拟。就基于继承的多态性而言,Java仅支持单类继承,将其多态行为限制为单个基类型链的行为。 Java确实支持多接口的实现,这是多态行为的另一种形式。
多态性仅仅意味着“多种形式”。
它不需要继承来实现...因为接口实现根本不是继承,它满足多态需求。可以说,界面实现服务于多态需求“更好”。而不是继承。
例如,你会创建一个超类来描述所有可以飞行的东西吗?我不应该想。您最好能够创建一个描述航班的界面并将其留在那里。
因此,由于接口描述了行为,并且方法名称描述了行为(对于程序员),因此将方法重载视为较小形式的多态性并不是一件容易的事。
调用代码不必知道它们是什么特定的动物。
这就是我认为的多态性。
多态性是对象以多种形式出现的能力。这涉及使用继承和虚函数来构建可以互换的对象族。基类包含虚函数的原型,可能是未实现的,或者是应用程序所指示的默认实现,并且各种派生类都以不同方式实现它们以影响不同的行为。
既不:
重载是指具有不同参数的相同函数名称。
覆盖是指子类用自己的方法替换父方法(这在迭代中不构成多态)。
多态性是晚期结合,例如正在调用基类(父)方法,但直到运行时,应用程序才知道实际对象是什么 - 它可能是一个子类,其方法不同。这是因为任何子类都可以在定义基类的地方使用。
在Java中,您会看到集合库中的多态性:
int countStuff(List stuff) {
return stuff.size();
}
List是基类,如果你计算链表,向量,数组或自定义列表实现,编译器就没有线索,只要它像List一样:
List myStuff = new MyTotallyAwesomeList();
int result = countStuff(myStuff);
如果你超负荷,你就有:
int countStuff(LinkedList stuff) {...}
int countStuff(ArrayList stuff) {...}
int countStuff(MyTotallyAwesomeList stuff) {...}
etc...
并且编译器将选择正确版本的countStuff()以匹配参数。
术语重载是指具有相同名称的多个版本,通常是具有不同参数列表的方法
public int DoSomething(int objectId) { ... }
public int DoSomething(string objectName) { ... }
因此,这些函数可能会执行相同的操作,但您可以选择使用ID或名称来调用它。与继承,抽象类等无关。
覆盖通常是指多态性,正如您在问题中描述的那样
重载是指定义2个具有相同名称但参数不同的方法
overriding是通过子类中具有相同名称的函数更改基类行为的地方。
因此,多态性与覆盖有关,但并非真正超载。
但是如果有人给我一个简单的回答“覆盖”的话。对于问题“什么是多态性?”我会要求进一步解释。
覆盖更像是通过声明与上层方法(超级方法)具有相同名称和签名的方法来隐藏继承方法,这会向类添加多态行为。 换句话说,选择要调用的级别方法的决定将在运行时而不是在编译时进行。 这导致了界面和实现的概念。
什么是多态?
来自java 教程
多态性的字典定义是指生物学中的原理,其中生物体或物种可以具有许多不同的形式或阶段。这个原则也可以应用于面向对象的编程和Java语言之类的语言。 类的子类可以定义自己的独特行为,但可以共享父类的一些相同功能。
通过考虑示例和定义,应接受 重写 。
关于你的第二个问题:
如果你有一个抽象基类定义了一个没有实现的方法,并且你在子类中定义了那个方法,那还是会覆盖吗?
应该称为覆盖。
查看此示例以了解不同类型的覆盖。
- 基类不提供实现,子类必须覆盖完整方法 - (摘要)
- 基类提供默认实现,子类可以改变行为
- 子类通过调用
super.methodName()
作为第一个语句,为基类实现添加扩展 - 基类定义算法的结构(模板方法),子类将覆盖算法的一部分 醇>
代码段:
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:
我认为你们都是混合的概念。 多态性 是的能力的一个对象不同的行为在运行时间。为实现这一目标,需要两个条件:
- 迟到结合
- 继承。
具有说 超载 意味着不同的东西 压倒一切的 根据语言的使用。例如在Java不存在 压倒一切的 但 超载. 超载 方法与不同签名,其基类都可以在子类。否则他们将被 重写 (请参阅我的意思是现在的事实是没有办法叫你的基类方法从外部对象)。
但是用C++,是不是这样。任何 超载 方法、独立的签名是否是同样的或不(diffrrent量,不同类型),以及 重写.这就是一天,基类的方法是不再提供类的时候被称为从外的子类目,很明显。
所以答案是在谈Java使用 超载.在其他任何语言可能是不同的,因为它发生在c++
虽然,多态性,是已经说的很详细,在这个职位,但是我希望把更多的重视,为什么它的一部分。
为什么多态性是如此的重要,在任何面向对象的语言。
让我们试图建立一个简单的应用程序,用于电视和无继承权/多态性。后各个版本的应用程序,我们做一个小小的回顾展。
假设你是个软件工程师在一个电视公司和你被要求编写的软件量,亮光和色彩的控制器的增加和减少他们的价值观上的用户的命令。
你开始写作课程的每一个这些功能通过增加
- 设置:-设置一个值的一个控制器。(假设这个具有控制特定的代码)
- 获得:-得到一个值的一个控制器。(假设这个具有控制特定的代码)
- 调整:到验证的输入以及设定一个控制器。(泛验证..独立的控制器)
- 用户输入的映射控制器:-让用户输入和调控制器相应。
应用版本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;
}
}
}
}
现在你有我们的第一个版本的工作申请准备进行部署。时间分析工作完成为止。
问题在电视应用的版本1
- 调整(int值)的代码是重复在所有三个课程。你想尽量减少代码口是心非。(但你没想到的共同的代码和移动一些超类,以避免重复代码)
你决定要住在一起只要你的应用程序的工作,如预期的那样。
之后有的时候,你的老板回来给你,并要求你加重功能的现有应用程序。重置将所有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;
}
}
}
}
所以,你有你的应用程序准备与重置的特征。但是,现在你开始意识到
问题在电视应用的版本2
- 如果一个新的控制器被引入到产品,你必须改变重置特代码。
- 如果计数器生长得很高,就会有问题保持的参考文献的管制。
- 重功能码是紧密结合起的所有控制器类代码(获取和设定缺省值)。
- 重功能类(ResetFunctionV2)可以访问其他的方法控制器类(调整),这是不可取的。
在同一时间,你听从你的老板,你可能必须添加一个功能,其中的每一个控制器上启动,需要检查最新的版本的驱动,从公司的托管的驱动器的存储库,通过互联网。
现在你开始思考,这个新的要素以添加类似于与重置的特征和问题的应用程序(V2)将乘以如果你不再因素应用程序。
你开始思考的使用继承所以,你可以利用从多态性能力的JAVA和添加一个新的抽象类(ControllerV3)来
- 声明签名的获得和设置的方法。
- 包含的调整方法执行其早些时候之间复制的所有控制器。
- 宣布setDefault方法,以便复功能可以很容易地实现充分利用多态性。
与这些改进,你有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;
}
}
}
}
虽然大多数问题列在问题清单的V2得到解决除了
问题在电视应用第3版
- 重功能类(ResetFunctionV3)可以访问其他的方法控制器类(调整),这是不可取的。
再次,你想解决这个问题,因为现在你有了另一个特征(更新的驱动程序启动时)来实现。如果你没修复它,它就会得到复制到新的功能。
所以你把合同定义在抽象的类和编写2个接口
- 重功能。
- 驱动程序更新。
和你的的第1次具体类实现他们作为下
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;
}
case 2: {
volumeControllerV4.adjust(-5);
break;
}
case 3: {
brightnessControllerV4.adjust(5);
break;
}
case 4: {
brightnessControllerV4.adjust(-5);
break;
}
case 5: {
colourControllerV4.adjust(5);
break;
}
case 6: {
colourControllerV4.adjust(-5);
break;
}
case 7: {
resetFunctionV4.onReset();
break;
}
default:
System.out.println("Shutting down...........");
break OUTER;
}
}
}
}
现在所有的面对的问题你得到了处理和你意识到与使用的遗产和多态性的,你可以
- 让各个部分应用程序松散耦合。(Reset或更新功能部件不需要了解为实际控制的课程(卷,明度和颜色),任何类实现OnReset或不可或缺的训将接受重新设置或更新的驱动程序的功能组件分别)。
- 应用程序强化变得更加容易。(新加控制器不会影响重新设置或更新功能部件,并且它现在真的很容易添加新的)
- 保持层的抽象概念。(现在的重置功能可以只看到setDefault方法的控制器和复功能可以只看到checkForDriverUpdate方法的控制器)
希望这有助于:-)
多态性更有可能就意义而言......在java中的OVERRIDING
所有关于SAME对象在不同情况下的不同行为(编程方式......你可以调用不同的ARGUMENTS)
我认为以下示例将帮助您理解......虽然它不是纯粹的Java代码......
public void See(Friend)
{
System.out.println("Talk");
}
但如果我们更改ARGUMENT ......行为将会改变......
public void See(Enemy)
{
System.out.println("Run");
}
Person(此处为“Object”)相同......
多态性是对象的多个实现,或者您可以说对象的多种形式。假设您将类 Animals
作为抽象基类,它有一个名为 movement()
的方法,它定义了动物移动的方式。现在实际上我们有不同种类的动物,它们的移动也不同,其中一些有两条腿,有些有4条腿,有些没有腿等等。定义每只动物的不同 movement()
在地球上,我们需要应用多态性。但是,您需要定义更多类,即类 Dogs
Cats
Fish
等。然后您需要从基类扩展这些类动物
并使用基于您拥有的每只动物的新移动功能覆盖其方法 movement()
。您还可以使用 Interfaces
来实现这一目标。这里的关键字是重写,重载是不同的,不被视为多态。通过重载,您可以定义多个方法“具有相同的名称”但是在同一个对象或类上使用不同的参数。
多态性与语言通过使用单个接口统一处理不同对象的能力有关;因此它与覆盖有关,所以接口(或基类)是多态的,实现者是覆盖的对象(同一个勋章的两个面)
无论如何,使用其他语言(例如c ++)可以更好地解释这两个术语之间的差异:如果基本函数是虚拟的,则c ++中的多态对象表现为java对应物,但如果该方法不是虚拟的,则代码跳转是解析静态,并且在运行时没有检查真实类型,因此,多态性包括对象根据用于访问它的接口而表现不同的能力;让我举一个伪代码的例子:
class animal {
public void makeRumor(){
print("thump");
}
}
class dog extends animal {
public void makeRumor(){
print("woff");
}
}
animal a = new dog();
dog b = new dog();
a.makeRumor() -> prints thump
b.makeRumor() -> prints woff
(假设makeRumor不是虚拟的)
java并不真正提供这种级别的多态性(也称为对象切片)。
动物a =新狗(); 狗b =新狗();
a.makeRumor() -> prints thump
b.makeRumor() -> prints woff
在这两种情况下它只会打印woff .. 因为a和b指的是类狗
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());
}
}