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