Полиморфизм против переопределения против перегрузки - PullRequest
327 голосов
/ 30 сентября 2008

С точки зрения Java, когда кто-то спрашивает:

что такое полиморфизм?

Будет ли перегрузка или переопределением приемлемым ответом?

Я думаю, в этом есть нечто большее.

ЕСЛИ у вас был абстрактный базовый класс, который определил метод без реализации, и вы определили этот метод в подклассе, он все еще переопределяется? Я думаю, перегрузка - это не правильный ответ.

Ответы [ 21 ]

4 голосов
/ 30 сентября 2008

Полиморфизм - это способность объекта появляться в нескольких формах. Это предполагает использование наследования и виртуальных функций для создания семейства объектов, которые можно взаимозаменять. Базовый класс содержит прототипы виртуальных функций, возможно, не реализованные или с реализациями по умолчанию, как диктует приложение, и каждый из производных классов реализует их по-разному, чтобы влиять на различные поведения.

3 голосов
/ 30 сентября 2008

Термин «перегрузка» относится к наличию нескольких версий чего-либо с одним и тем же именем, обычно это методы с разными списками параметров.

public int DoSomething(int objectId) { ... }
public int DoSomething(string objectName) { ... }

Так что эти функции могут делать то же самое, но у вас есть возможность вызвать его с помощью идентификатора или имени. Не имеет ничего общего с наследованием, абстрактными классами и т. Д.

Переопределение обычно относится к полиморфизму, как вы описали в своем вопросе

2 голосов
/ 16 сентября 2016

что такое полиморфизм?

Из Java учебник

Словарное определение полиморфизма относится к принципу в биологии, в котором организм или вид могут иметь много различных форм или стадий. Этот принцип также может быть применен к объектно-ориентированному программированию и таким языкам, как язык Java. Подклассы класса могут определять свое собственное уникальное поведение и, тем не менее, совместно использовать некоторые из тех же функций родительского класса.

Рассматривая примеры и определения, overriding должен быть принят ответ.

Относительно вашего второго запроса:

Если у вас был абстрактный базовый класс, который определил метод без реализации, и вы определили этот метод в подклассе, он все еще переопределяется?

Это должно называться переопределением.

Посмотрите на этот пример, чтобы понять различные типы переопределения.

  1. Базовый класс не обеспечивает реализацию, а подкласс должен переопределять завершенный метод - (аннотация)
  2. Базовый класс обеспечивает реализацию по умолчанию, а подкласс может изменить поведение
  3. Подкласс добавляет расширение к реализации базового класса, вызывая super.methodName() в качестве первого оператора
  4. Базовый класс определяет структуру алгоритма (метод 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:
2 голосов
/ 06 мая 2018

Хотя Полиморфизм уже подробно описан в этом посте, но я бы хотел больше подчеркнуть, почему его часть.

Почему полиморфизм так важен в любом языке ООП.

Давайте попробуем создать простое приложение для телевизора с наследованием / полиморфизмом и без него. Размещая каждую версию приложения, мы делаем небольшую ретроспективу.

Предположим, вы инженер по программному обеспечению в телекомпании, и вас просят написать программное обеспечение для контроллеров громкости, яркости и цвета для увеличения и уменьшения их значений по команде пользователя.

Вы начинаете с написания классов для каждой из этих функций, добавляя

  1. set: - Для установки значения контроллера. (Предположим, это имеет специальный код контроллера)
  2. get: - Чтобы получить значение контроллера. (Предположим, это имеет специальный код контроллера)
  3. настроить: - Для проверки входа и настройки контроллера. (Общая проверка ... независимо от контроллеров)
  4. Отображение пользовательского ввода с контроллерами: - Чтобы получить пользовательский ввод и соответственно вызывать контроллеры.

Версия приложения 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;
        }

    }
    }
}

Теперь у вас есть первая версия рабочего приложения, готовая к развертыванию. Время проанализировать проделанную работу.

Проблемы в приложении TV версии 1

  1. Код корректировки (int value) дублируется во всех трех классах. Вы хотели бы минимизировать дублирование кода. (Но вы не думали об общем коде и перемещении его в какой-то суперкласс, чтобы избежать дублирования кода)

Вы решаете жить с этим, пока ваше приложение работает должным образом.

Через некоторое время ваш босс возвращается к вам и просит добавить функцию сброса в существующее приложение. Сброс установит все три контроллера на их соответствующие значения по умолчанию.

Вы начинаете писать новый класс (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;
            }

        }
    }
}

Итак, ваше приложение готово с функцией сброса. Но теперь вы начинаете понимать, что

Проблемы в приложении TV версии 2

  1. Если в продукт введен новый контроллер, необходимо изменить код функции сброса.
  2. Если счетчик контроллера вырастет очень высоко, у вас возникнет проблема с удержанием ссылок на контроллеры.
  3. Сброс кода функции тесно связан со всем кодом класса контроллеров (для получения и установки значений по умолчанию).
  4. Сбросить класс пространственных объектов (ResetFunctionV2) может получить доступ к другому методу класса Controller (настроить), что нежелательно.

В то же время вы слышите от своего босса, что вам, возможно, придется добавить функцию, при которой каждому контроллеру при запуске необходимо проверять наличие последней версии драйвера из хранилища драйверов компании через Интернет.

Теперь вы начинаете думать, что эта новая функция, которая будет добавлена, похожа на функцию сброса, и проблемы приложения (V2) будут умножены, если вы не будете повторно учитывать свое приложение.

Вы начинаете думать об использовании наследования, чтобы воспользоваться преимуществами полиморфной способности JAVA, и добавляете новый абстрактный класс (ControllerV3) к

  1. Объявите подпись метода get и set.
  2. Содержит реализацию метода настройки, которая ранее была реплицирована среди всех контроллеров.
  3. Объявите метод 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, были устранены, кроме

Проблемы в приложении TV версии 3

  1. ResEКласс пространственных объектов (ResetFunctionV3) может обращаться к другому методу класса Controller (настроить), что нежелательно.

Опять же, вы думаете о решении этой проблемы, так как теперь у вас есть еще одна функция (обновление драйвера при запуске), которая также будет реализована. Если вы не исправите это, он также будет перенесен на новые функции.

Таким образом, вы разделяете контракт, определенный в абстрактном классе, и пишете 2 интерфейса для

  1. Функция сброса.
  2. Обновление драйвера.

И пусть ваш первый конкретный класс реализует их, как показано ниже

Версия приложения 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;
            }

        }
    }
}

Теперь все проблемы, с которыми вы столкнулись, были решены, и вы поняли, что с помощью Наследования и Полиморфизма вы можете

  1. Сохраняйте слабую связь между различными частями приложения. (Компонентам «Сброс» или «Обновление драйвера» не нужно знать о фактических классах контроллера (Громкость, Яркость и Цвет)), любой класс, реализующий OnReset или OnStart, будет приемлем для Сброса или Компоненты функции обновления драйверов соответственно).
  2. Улучшение приложения становится проще. (Новое добавление контроллера не влияет на сброс или компонент обновления драйверов, и теперь вам действительно легко добавлять новые)
  3. Сохранить уровень абстракции. (Теперь функция Reset может видеть только метод контроллеров setDefault, а функция Reset может видеть только метод контроллеров checkForDriverUpdate)

Надеюсь, это поможет: -)

2 голосов
/ 26 апреля 2013
Переопределение

больше похоже на сокрытие унаследованного метода, объявляя метод с тем же именем и сигнатурой, что и метод верхнего уровня (супер метод), это добавляет полиморфное поведение к классу. другими словами, решение о выборе метода уровня, который будет вызываться, будет приниматься во время выполнения, а не во время компиляции. это приводит к концепции интерфейса и реализации.

2 голосов
/ 30 сентября 2008

перегрузка - это когда вы определяете 2 метода с одинаковым именем, но разными параметрами

Переопределение - это когда вы изменяете поведение базового класса с помощью функции с тем же именем в подклассе.

Итак, полиморфизм связан с переопределением, но не с перегрузкой.

Однако, если бы кто-то дал мне простой ответ «переопределения» на вопрос «Что такое полиморфизм?» Я бы попросил дальнейших объяснений.

2 голосов
/ 24 февраля 2012

Я думаю, ребята, вы смешиваете понятия. Полиморфизм - это способность объекта вести себя по-разному во время выполнения. Для этого вам понадобятся два реквизита:

  1. Позднее связывание
  2. Наследование.

Сказав, что перегрузка означает нечто отличное от переопределение в зависимости от используемого вами языка. Например, в Java не существует переопределения , но перегрузки . Перегруженные методы с различными сигнатурами для своего базового класса доступны в подклассе. В противном случае они будут переопределены (пожалуйста, обратите внимание, что я имею в виду тот факт, что теперь нет способа вызвать метод базового класса извне объекта).

Однако в C ++ это не так. Любой перегруженный метод, независимо от того, является ли сигнатура одинаковой или нет (разная сумма, другой тип), также переопределяется . То есть сегодня метод базового класса больше не доступен в подклассе при вызове извне объекта подкласса, очевидно.

Таким образом, ответ на вопрос об использовании Java перегрузка . В любом другом языке может отличаться, как это происходит в C ++

1 голос
/ 16 сентября 2013

Полиморфизм - это множественные реализации объекта, или вы можете сказать несколько форм объекта. Допустим, у вас есть класс Animals в качестве абстрактного базового класса, и у него есть метод с именем movement(), который определяет способ движения животного. Теперь в действительности у нас есть разные виды животных, и они движутся по-разному, а некоторые из них с двумя ногами, другие с четырьмя, а некоторые без ног и т. Д. Чтобы определить различные movement() каждого животного на земле, нам нужно применить полиморфизм. Однако вам нужно определить больше классов, например, класс Dogs Cats Fish и т. Д. Затем вам нужно расширить эти классы из базового класса Animals и переопределить его метод movement() новыми функциональными возможностями перемещения, основанными на каждом животное у вас есть. Вы также можете использовать Interfaces для достижения этой цели. Ключевое слово здесь переопределено, перегрузка отличается и не рассматривается как полиморфизм. с перегрузкой вы можете определить несколько методов «с одинаковым именем», но с разными параметрами для одного и того же объекта или класса.

1 голос
/ 11 сентября 2012

Полиморфизм более вероятен, поскольку он означает, что касается ... ПЕРЕГРУЗКИ в java

Все дело в разном поведении одного и того же объекта в разных ситуациях (программированием ... вы можете вызывать разные аргументы)

Я думаю, что приведенный ниже пример поможет вам понять ... Хотя это не ЧИСТЫЙ Java-код ...

     public void See(Friend)
     {
        System.out.println("Talk");
     }

Но если мы изменим АРГУМЕНТ ... ПОВЕДЕНИЕ будет изменено ...

     public void See(Enemy)
     {
        System.out.println("Run");
     }

Человек (здесь «Объект») тот же ...

0 голосов
/ 16 июля 2015
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());

    }
}
...