从超类中的子类访问 Scanner 对象?
Accessing Scanner objects from subclass in a superclass?
我是一个新手,相对缺乏经验 Java 程序员。我正在做的项目只是对我目前技能的考验,我的目标是编写尽可能高效的程序。
本质上,我有三个类:A、B和C。B扩展A,C扩展B,但我想在C中的一个Scanner对象用于switch语句(部分更大的方法)在 A.
我之所以要这个是因为我不想重载A中的方法(复制粘贴不同参数的相同代码是不理想的),我不想把我所有的类合二为一(代码很简单,可以做到这一点,但我想测试一下我对对象创建和使用的了解)。
下面是部分代码:
import java.time.LocalDateTime;
public class WatchFace {
// MASTER TIME
LocalDateTime dateTimeObject = LocalDateTime.now();
int hour = dateTimeObject.getHour();
int minute = dateTimeObject.getMinute();
// WATCH FACE METHOD
public void watchFaceMethod() {
// Code I'd like to utilize; this is my question for Whosebug
// switch (userInput) {
// case 1:
// // Intentionally do nothing
// break;
//
// case 2:
// // Change minute and hour to some values obtained by timezone stuff
// break;
//
// case 3:
// // Change both minute and hour to -1
// break;
// }
// Basically, the rest of this code just prints something different to the Windows CLI depending on the
// hour and minute variables' current values (i.e. beyond the intended switch statement).
}
}
import java.time.format.DateTimeFormatter;
public class Watch extends WatchFace {
static void watchMethod() {
// Code printing some Strings is here.
WatchFace watchFaceObject = new WatchFace();
watchFaceObject.watchFaceMethod();
// Code printing some more Strings is here.
DateTimeFormatter dateTimeFormat = DateTimeFormatter.ofPattern("hh:mm a 'on' EEEE, MMMM dd, yyyy");
String dateTimeDisplay = watchFaceObject.dateTimeObject.format(dateTimeFormat);
System.out.print("\nIt is currently " + dateTimeDisplay + "\n");
if (watchFaceObject.hour == 11 && watchFaceObject.minute == 11) {
System.out.println("Make a wish!");
}
}
}
import java.util.Scanner;
public class InteractiveWatch extends Watch {
public static void main(String[] args) {
// WATCH OBJECT
Watch watchObject = new Watch();
// STARTUP
System.out.println("Welcome to Interactive Watch!\n");
System.out.println("What would you like to do?");
System.out.println("[1] See local time.");
System.out.println("[2] See local time in a particular place.");
System.out.println("[3] See something special.\n");
Scanner scannerObject = new Scanner(System.in);
// INPUT
boolean loopBreak = true;
while (loopBreak) {
loopBreak = false; // loopBreak set to false
String userInput = scannerObject.nextLine(); // User inputs some string
switch(userInput) {
case "1":
watchObject.watchMethod(); // watchFaceMethod ideally detects userInput == 1
break;
case "2":
watchObject.watchMethod(); // watchFaceMethod ideally detects userInput == 2
break;
case "3":
watchObject.watchMethod(); // watchFaceMethod ideally detects userInput == 3
break;
default:
loopBreak = true; // loopBreak set to true; while loop reinitiates
System.out.println("\nPlease enter a valid key.\n");
break;
}
}
}
}
我从 w3schools 的 Java 课程中学到了我所拥有的一切,但我还有很多东西要学。让我知道我想要的是否有可能,或者其他任何可以使这段代码更有效率的事情。谢谢!
不,这不可能。
超类无权访问其在 Java 中的子类的成员。但是子类可以访问其超类的所有非私有成员。
简短的回答是否。您无法访问属于子类型的对象。
长答案:watchFaceMethod
不知道呼叫来自 InteractiveWatch
。这样想;如果我们创建一个新的 class OtherWatch
,它也扩展了 Watch
会怎么样?假设 OtherWatch
没有 Scanner 对象。现在,当它被告知调用 Scanner 对象的方法时,watchFaceMethod()
会做什么?它什么也做不了,因为 Scanner 对象不存在。不过,我不确定我是否理解您为什么首先要尝试访问 watchFaceMethod
中的 Scanner 对象。您已经获得了用户的输入。您不想获得更多输入,所以您确实想要访问 nextLine()
方法 return 编辑的字符串。我将通过简单地将字符串作为参数向上传递给 watchMethod()
和 watchFaceMethod()
方法来解决这个问题。将参数传递给另一个方法并不是“低效”的。你最终会得到这样的方法:
public void watchMethod(String userInput) {
...
WatchFace watchFaceObject = new WatchFace();
watchFaceObject.watchFaceMethod(userInput);
...
}
和
public void watchFaceMethod(String userInput) {
switch (userInput) {
case "1":
...
break;
case "2":
...
break;
case "3":
...
break;
}
...
}
另一种选择是使 userInput
成为 public 静态变量,然后仅从 watchFaceMethod()
引用它,但我建议不要这样做,因为您可能很快就会忘记哪些方法正在访问和改变该变量。
关于您的代码,我还注意到了一件小事;您使用 \n
作为行分隔符,它会产生一个换行符。这是 UNIX 系统上的标准行分隔符,但是 Windows 使用回车 return 和换行符,而 OSX 只使用回车 return,所以如果您想要returns 显示在所有平台上,您应该使用 %n
,它会生成正确的特定于平台的行分隔符。
我是一个新手,相对缺乏经验 Java 程序员。我正在做的项目只是对我目前技能的考验,我的目标是编写尽可能高效的程序。
本质上,我有三个类:A、B和C。B扩展A,C扩展B,但我想在C中的一个Scanner对象用于switch语句(部分更大的方法)在 A.
我之所以要这个是因为我不想重载A中的方法(复制粘贴不同参数的相同代码是不理想的),我不想把我所有的类合二为一(代码很简单,可以做到这一点,但我想测试一下我对对象创建和使用的了解)。
下面是部分代码:
import java.time.LocalDateTime;
public class WatchFace {
// MASTER TIME
LocalDateTime dateTimeObject = LocalDateTime.now();
int hour = dateTimeObject.getHour();
int minute = dateTimeObject.getMinute();
// WATCH FACE METHOD
public void watchFaceMethod() {
// Code I'd like to utilize; this is my question for Whosebug
// switch (userInput) {
// case 1:
// // Intentionally do nothing
// break;
//
// case 2:
// // Change minute and hour to some values obtained by timezone stuff
// break;
//
// case 3:
// // Change both minute and hour to -1
// break;
// }
// Basically, the rest of this code just prints something different to the Windows CLI depending on the
// hour and minute variables' current values (i.e. beyond the intended switch statement).
}
}
import java.time.format.DateTimeFormatter;
public class Watch extends WatchFace {
static void watchMethod() {
// Code printing some Strings is here.
WatchFace watchFaceObject = new WatchFace();
watchFaceObject.watchFaceMethod();
// Code printing some more Strings is here.
DateTimeFormatter dateTimeFormat = DateTimeFormatter.ofPattern("hh:mm a 'on' EEEE, MMMM dd, yyyy");
String dateTimeDisplay = watchFaceObject.dateTimeObject.format(dateTimeFormat);
System.out.print("\nIt is currently " + dateTimeDisplay + "\n");
if (watchFaceObject.hour == 11 && watchFaceObject.minute == 11) {
System.out.println("Make a wish!");
}
}
}
import java.util.Scanner;
public class InteractiveWatch extends Watch {
public static void main(String[] args) {
// WATCH OBJECT
Watch watchObject = new Watch();
// STARTUP
System.out.println("Welcome to Interactive Watch!\n");
System.out.println("What would you like to do?");
System.out.println("[1] See local time.");
System.out.println("[2] See local time in a particular place.");
System.out.println("[3] See something special.\n");
Scanner scannerObject = new Scanner(System.in);
// INPUT
boolean loopBreak = true;
while (loopBreak) {
loopBreak = false; // loopBreak set to false
String userInput = scannerObject.nextLine(); // User inputs some string
switch(userInput) {
case "1":
watchObject.watchMethod(); // watchFaceMethod ideally detects userInput == 1
break;
case "2":
watchObject.watchMethod(); // watchFaceMethod ideally detects userInput == 2
break;
case "3":
watchObject.watchMethod(); // watchFaceMethod ideally detects userInput == 3
break;
default:
loopBreak = true; // loopBreak set to true; while loop reinitiates
System.out.println("\nPlease enter a valid key.\n");
break;
}
}
}
}
我从 w3schools 的 Java 课程中学到了我所拥有的一切,但我还有很多东西要学。让我知道我想要的是否有可能,或者其他任何可以使这段代码更有效率的事情。谢谢!
不,这不可能。
超类无权访问其在 Java 中的子类的成员。但是子类可以访问其超类的所有非私有成员。
简短的回答是否。您无法访问属于子类型的对象。
长答案:watchFaceMethod
不知道呼叫来自 InteractiveWatch
。这样想;如果我们创建一个新的 class OtherWatch
,它也扩展了 Watch
会怎么样?假设 OtherWatch
没有 Scanner 对象。现在,当它被告知调用 Scanner 对象的方法时,watchFaceMethod()
会做什么?它什么也做不了,因为 Scanner 对象不存在。不过,我不确定我是否理解您为什么首先要尝试访问 watchFaceMethod
中的 Scanner 对象。您已经获得了用户的输入。您不想获得更多输入,所以您确实想要访问 nextLine()
方法 return 编辑的字符串。我将通过简单地将字符串作为参数向上传递给 watchMethod()
和 watchFaceMethod()
方法来解决这个问题。将参数传递给另一个方法并不是“低效”的。你最终会得到这样的方法:
public void watchMethod(String userInput) {
...
WatchFace watchFaceObject = new WatchFace();
watchFaceObject.watchFaceMethod(userInput);
...
}
和
public void watchFaceMethod(String userInput) {
switch (userInput) {
case "1":
...
break;
case "2":
...
break;
case "3":
...
break;
}
...
}
另一种选择是使 userInput
成为 public 静态变量,然后仅从 watchFaceMethod()
引用它,但我建议不要这样做,因为您可能很快就会忘记哪些方法正在访问和改变该变量。
关于您的代码,我还注意到了一件小事;您使用 \n
作为行分隔符,它会产生一个换行符。这是 UNIX 系统上的标准行分隔符,但是 Windows 使用回车 return 和换行符,而 OSX 只使用回车 return,所以如果您想要returns 显示在所有平台上,您应该使用 %n
,它会生成正确的特定于平台的行分隔符。