Java 在OOP中,在编写子类时,是否要更改原始的主方法代码?怎么办?

Java 在OOP中,在编写子类时,是否要更改原始的主方法代码?怎么办?,java,class,oop,object,encryption,Java,Class,Oop,Object,Encryption,我知道OOP的全部意义在于不必重写代码 我有一个类(我们称之为E)和一个主类(我们称之为main),其中有一个main方法,该方法验证一些输入,然后将它们馈送到类E(对输入进行加密)中,以获得一个结果输出给用户(加密的输入) 现在,我正在编写一个子类,从我是其他人改进程序的角度出发。我有一个encryption类的子类,它使用类似的原理,但有一个改进的加密方法(我们称之为类ImprovedE) 作为我冒充的新开发人员,我是否会编写子类,然后从原始程序重写main方法,将输入输入输入到改进的E而不

我知道OOP的全部意义在于不必重写代码

我有一个类(我们称之为E)和一个主类(我们称之为main),其中有一个main方法,该方法验证一些输入,然后将它们馈送到类E(对输入进行加密)中,以获得一个结果输出给用户(加密的输入)

现在,我正在编写一个子类,从我是其他人改进程序的角度出发。我有一个encryption类的子类,它使用类似的原理,但有一个改进的加密方法(我们称之为类ImprovedE)

作为我冒充的新开发人员,我是否会编写子类,然后从原始程序重写main方法,将输入输入输入到改进的E而不是E中

我知道我不能重写main方法,但我认为我也不应该更改原始代码。任何帮助都会得到报答

这是我忘记添加的代码(编辑)

package encryption;

import java.util.Scanner;
import static encryption.encryptionChoice.*;

public class main {

//These are all the reusable variables created to temporarily store information before pushing it to the Encryption class

//This is a simple starter message to inform the user of how to use the program
private String initialDisplayInformation = "Message Encryption/Decryption program for use with letters and spaces only. \nPress any key to continue...";

//These are the "scope" input and output variables visible to the user
private String inputString;
private String outputString;
//This creates the encryption class
private Encryption myEncryption = new Encryption();
//These are used to later create two loops that only break when an acceptable input has been input for the values
private Boolean inputValidated = false;
private Boolean cypherValidated = false;
private Boolean choiceValidated = false;

private void initialInfo() {
    //These 2 lines make the user have to hit any key before continuing after reading the info
    System.out.println(initialDisplayInformation);
    String pressAnyKey = new Scanner(System.in).nextLine();
}

private void inputValidation(){    
    //This loop attepts to validate the message input and uses the boolean returned fromthe Encryption.setInput class to see the success
    //It prints a detailed error and repeats if unsuccessful
    do {
        System.out.println("\nEnter your message: "); 
        try {
            inputValidated = myEncryption.setInput(new Scanner(System.in).nextLine());
        } catch(NotACharacterException e) {
            System.out.println(e.errorMessage());
        }
    } while(!inputValidated); 
}

private void cypherValidation(){
    //This repeats the exact process as the previous loop, but for the cypher length
    do {
        System.out.println("\nEnter your cypher length (How much the message will be/was offset by: ");  
        try {
            cypherValidated = myEncryption.setCypher(new Scanner(System.in).nextInt());
            if(!cypherValidated) {
                System.out.println("That is not an acceptable integer, please try again... ");
            }
        }catch(Exception e){
            System.out.println("That is not a valid input, please try again... ");
        }

    } while(!cypherValidated);
}

private void encryptionDecision(){
    do {
        System.out.println("\nWould you like to 1)Encrypt 2)Decrypt the message: ");  
        String choiceString = new Scanner(System.in).nextLine();
        encryptionChoice choice = ERROR;

        if(choiceString.equalsIgnoreCase("Encrypt")|| choiceString.equalsIgnoreCase("1")){
            choice = ENCRYPT;
        }


        if(choiceString.equalsIgnoreCase("Decrypt") || choiceString.equalsIgnoreCase("2")){
            choice = DECRYPT;
        }

        try {
            System.out.println(myEncryption.getInput());
            System.out.println(myEncryption.EncryptionDecryption(choice));
            choiceValidated = true;

        } catch(IllegalArgumentException e) {
            System.out.println("Please only enter: Encrypt, Decrypt, 1 or 2. Please try again... ");
        }
    } while(!choiceValidated);
}


public static void main(String[] args) {
    boolean runProgram = true;
    while(runProgram){
        main thread = new main();
        thread.initialInfo();
        thread.inputValidation();
        thread.cypherValidation();
        thread.encryptionDecision();

        runProgram=false;

        Scanner keyboard = new Scanner(System.in);
        System.out.println("\nPress 'r' to restart or 'enter' to exit");
         if(new Scanner(System.in).nextLine().equals("r")) {
            runProgram=true;
         }
    }
}
}

/*
*要更改此许可证标题,请在“项目属性”中选择“许可证标题”。
*要更改此模板文件,请选择工具|模板
*然后在编辑器中打开模板。
*/
包加密;
/**
*
*@作者亚历克斯
*/
公共类SingleKeywordEncryption扩展了加密{
受保护字符串关键字字符串;
受保护的整数getKeywordCypher(字符串关键字,整数项){
字符letterInKeyword=0;
整数密码长度;
if(term=keyword.length()){
letterInKeyword=keyword.charAt(术语%keyword.length());
}
cypherLength=termOf(letterInKeyword);
返回密码长度;
}
@凌驾
公共字符串加密解密(encryptionChoice){
字符串outputString=“”;
开关(选择){
大小写加密:

对于(int i=0;i无论如何,您都必须在代码中的某个地方进行更改,以便main使用您的ImprovedE类而不是E类。否则,程序将无法自行知道您是要使用E还是ImprovedE

如果您不在E中使用加密方法,并且始终使用ImprovedE,那么最好将E中的所有方法都包含在ImprovedE中。这样,您就不必决定使用哪个类

如果您仍然希望能够在这两个类之间切换,我建议使用设计模式。您可以在这两个类之间放置任何共享的方法(例如
termOf(Character letter)
lettof(int inputTerm)
setInput(String inputLoadd)
)在一个可以通过两种策略访问的类中,您将有两种具体的策略:E和ImprovedE

通过这种方式,您可以在两种策略之间快速切换,只需更改具体策略(在您的情况下,如果您想使用旧的或新的加密方法),您还可以提示用户知道他想要哪种加密方法,如果这是一个有效的用例

我知道OOP的全部要点是这样代码就不必重写

实际上,OOP的目的是使代码的组织更易于概念化。
extends
被许多人认为是一个概念


考虑在抽象基类上使用
实现
来定义接口,并让未来的开发人员担心“改进”。

在Java中,
方法是静态的,这意味着它不能被重写。这是通过设计实现的,但不一定是优化设计的。没有通用的理由不能在原则,但Java不这样做

问题是:你不应该一开始就需要它。你以前的开发人员把所有这些加密方法和状态信息放在同一个类中,这代表了计算本身:你的
main
类,这就混合了你的职责


因此,你必须要做的是将这些事情解耦,因为主要方法必须非常小和狭隘。当这种情况发生时,你不会觉得有太多的重复。如果有,总是有更多的重构空间。

我可能已经回答了我自己的问题,我刚刚意识到我的主要方法不是直接的y调用E类,它只调用主类中的一个方法,该方法调用E类。我建议在E类中更改此方法,改为只指向改进的E类,对吗?因此,在我的代码中-更改EncryptionDecryptionDecision方法,以获得singleKeyEncryption而不是EnryptionDecryption的输出在类上?(通过重写EncryptioNDecryptionDecision方法,该方法当然不是chanignt eh原始代码)我说得对吗?“我知道OOP的全部要点是不必重写代码……”事实上,OOP的目的是使代码的组织更易于概念化。
extends
被许多人认为是一个。你的主程序(不应称为“main”)应该只处理获取输入和写入输出,并将所有与加密有关的内容交给“加密机”-这可能是一个
接口
而不是一个类。然后您有两个Encryptor接口的实现;您最初的简单
公共类加密实现Encryptor
,而您改进的
公共类改进加密实现Encryptor
…改进的类并没有扩展原始的实际上,它将重新使用(而不是替换)一些原始的方法。我希望从Encryptor类恢复的唯一方法是设置和获取输入变量,以及termof()和lettermof()方法,这些方法很容易在字母表中找到实数词或字母。如果我使用了实现,它们还会被重用吗?您正在寻找依赖项注入,也称为控制反转。由于improvedE与E共享许多类,因此我制作了c
/*
 * To change this license header, choose License Headers in Project     Properties.
 * To change this template file, choose Tools | Templates
  * and open the template in the editor.
  */
package encryption;

 /**
 *
  * @author Alex
 */
public class SingleKeywordEncryption extends Encryption {
protected String keywordString;

protected Integer getKeywordCypher(String keyword, Integer term){
    Character letterInKeyword = 0;
    Integer cypherLength;

    if(term<keyword.length()){
        letterInKeyword = keyword.charAt(term);
    }
    else if(term>=keyword.length()) {
        letterInKeyword = keyword.charAt(term%keyword.length());
    }


    cypherLength = termOf(letterInKeyword);
    return cypherLength;
}

@Override
public String EncryptionDecryption(encryptionChoice choice) {
    String outputString = "";

    switch(choice){
        case ENCRYPT:
            for(int i=0;i<inputString.length();i++) {
                outputString = outputString + letterOf(termOf(inputString.charAt(i)) + getKeywordCypher(keywordString, i)); 

            }
            break;

        case DECRYPT:
            for(int i=0;i<inputString.length();i++) {
                outputString = outputString + letterOf(termOf(inputString.charAt(i)) - getKeywordCypher(keywordString, i)); 
            }
            break;   
        default:
           throw new IllegalArgumentException();


    };
        return outputString;
}
     package encryption;//Includes the class int he encryption package of classes     for my project
//This creates a class called Encryption where the majority of my project is      stored
 public class Encryption {
     //These create the variables needed throughout the class
    //This is final so that it is immutable and usable in all the methods
     //I made it a Character array to save memory use and to allow simpler comparison methods in other areas of the program
    private final Character[] alphabet = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
     //These are private for good coding practice, so that they can only be modified from within the class
     private Integer cypher;
     protected String inputString;


public String getInput() {
    return inputString;
}

//This class simply validates and saves the cypher length to its variable and returns a boolean of its success
public boolean setCypher(Integer cypherToAdd) {
    while(cypherToAdd>26 || cypherToAdd<0){
        return false;
    }
//It tries to save it and returns false if it cannot be saved as an integer
    try {
        cypher = cypherToAdd;
    } 
    catch (Exception e) {
        return false;
    }
    return true;
}

//This class validates andsaves the input to its variable and removes any whitespace from it
public boolean setInput(String inputToAdd) throws NotACharacterException {
    //This uses replaceAll to remove whitespace and saves the object that is rejurned from the method to String input
    String input = inputToAdd.replaceAll("\\s","");
    //This iterates through every character in the input and checks that it is a letter
    for (int term=0; term<input.length();term++) {
        //If a term is not a letter, it throws the custom NotACharacterException and passes information of which non-letter character caused it
        if(!Character.isLetter(input.charAt(term))){
            throw new NotACharacterException("'" + String.valueOf(input.charAt(term)) + "' This character can not be used in this program...\nStick to letters and spaces only please."); 
        }
    }
    inputString = input;
    return true;
}

//This class returns the term of a passed letter in the alphabet
protected int termOf(Character letter) {
    //The term variable to be returned is initialised immediately
    int term =0;

    //The for loop iterates through every letter in the alphabet and compares it with the letter passed to the method to find its term
    for (int currentTerm=0; currentTerm<alphabet.length;currentTerm++) {
        //When the letters match, the term is returned to where the method is called
        if(letter.toLowerCase(letter)==alphabet[currentTerm]){
            term = currentTerm;
        }
    }
    return term;
}

//This class returns the letter of a passed term in the alphabet
protected Character letterOf(int inputTerm) { 

    if(inputTerm>25){
        return alphabet[inputTerm-26];
    } else if (inputTerm<0) {
        return alphabet[inputTerm+26];
    }
    else {
    //It recieves the character by gathering the character in the inputTerm's place in the array, and returns it
    return alphabet[inputTerm];
    }
}

public String EncryptionDecryption(encryptionChoice choice){
    String outputString = "";

    switch(choice){
        case ENCRYPT:
            for(int i=0;i<inputString.length();i++) {
                outputString = outputString + letterOf(termOf(inputString.charAt(i))+ cypher); 
            }
            break;

        case DECRYPT:
            for(int i=0;i<inputString.length();i++) {
                outputString = outputString + letterOf(termOf(inputString.charAt(i))- cypher); 
            }
            break;   
        default:
           throw new IllegalArgumentException();


    };
        return outputString;
}