从超类的子类访问Scanner对象? [英] Accessing Scanner objects from subclass in a superclass?

查看:60
本文介绍了从超类的子类访问Scanner对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是一个非常新的,相对缺乏经验的Java程序员.我正在从事的项目只是对我当前技能的考验,我的目标是编写尽可能高效的程序.

从本质上讲,我具有三个类:A,B和C.B扩展了A,C扩展了B,但是我希望C中的Scanner对象在A中的switch语句(较大方法的一部分)中使用

我想要这样做的原因是因为我不想重载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 StackOverflow
        // 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课程中学到了所有东西,但是我还有很多东西要学习.让我知道我想要的是什至是可能的,或者是任何其他可以使此代码更高效的东西.谢谢!

解决方案

简短的回答是.您不能访问属于子类型的对象.

长答案:watchFaceMethod不知道呼叫来自InteractiveWatch.这样想吧;如果我们创建了一个新类OtherWatch,该类也扩展了Watch,该怎么办?假设OtherWatch没有扫描仪对象.现在,当watchFaceMethod()被告知调用您的Scanner对象的方法时,该怎么办?它无能为力,因为Scanner对象不存在.我不确定我是否理解为什么您首先尝试访问watchFaceMethod中的Scanner对象.您已经从用户那里得到了输入.您不想获得更多输入,因此您确实希望访问nextLine()方法返回的字符串.我可以通过简单地将字符串作为参数传递给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设为公共的静态变量,然后仅从watchFaceMethod()引用它,但是我建议您这样做,因为您可能会很快失去对访问和更改该变量的方法的了解. /p>

我注意到了有关您的代码的另一件事;您将\n用于换行符,这将产生换行符.这是UNIX系统上的标准行分隔符,但是Windows使用回车符和换行符,而OSX仅使用回车符,因此,如果希望在所有平台上都显示回车符,则应使用%n,产生正确的平台特定的行分隔符.

I am a very new, relatively inexperienced Java programmer. The project I am working is just a test of my current skills, and my goal is to write as efficient a program as possible.

In essence, I have three classes: A, B, and C. B extends A and C extends B, but I want a Scanner object in C to be used in a switch statement (part of a larger method) in A.

The reason I want this is because I do not want to overload the method in A (copy-pasting the same code with different parameters is not ideal), and I do not want to combine all of my classes into one (the code is simple enough to do this, but I want to test my knowledge of object creation and use).

Here is some of the code:

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 StackOverflow
        // 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;
            }
        }
    }
}

I learned everything I have from w3schools' Java course, but I still have much more to learn. Let me know if what I want is even possible, or anything else that would make this code more efficient. Thank you!

解决方案

The short answer is no. You cannot access an object belonging to a subtype.

The long answer: The watchFaceMethod does not know that the call came from an InteractiveWatch. Think about it this way; what if we made a new class OtherWatch, which also extends Watch. Suppose OtherWatch does not have a Scanner object. Now what is watchFaceMethod() going to do when it's told to invoke a method of your Scanner object? It can't do anything, because the Scanner object does not exist. I'm not sure I understand why you're trying to access the Scanner object in watchFaceMethod in the first place, though. You already got the input from the user. You don't want to get more input, so you really want access to the string that the nextLine() method returned. I would approach this by simply passing the string up the hierarchy as a parameter to the watchMethod() and watchFaceMethod() methods. It's not "inefficient" to pass parameters to another method. You would end up with methods something like these:

public void watchMethod(String userInput) {
    ...
    WatchFace watchFaceObject = new WatchFace();
    watchFaceObject.watchFaceMethod(userInput);
    ...
}

and

public void watchFaceMethod(String userInput) {
    switch (userInput) {
        case "1":
            ...
            break;
        case "2":
            ...
            break;
        case "3":
            ...
            break;
    }
    ...
}

Another option is to make userInput a public, static variable, and then just reference it from watchFaceMethod(), but I would advise against this as you could quickly lose track of what methods are accessing and mutating that variable.

One more little thing I noticed about your code; you use \n for your line separators, which produces a linefeed character. This is the standard line separator on UNIX systems, but Windows uses a carriage return together with a linefeed, and OSX uses just the carriage return, so if you want your returns to show up on all platforms, you should use %n, which produces the correct platform-specific line separator.

这篇关于从超类的子类访问Scanner对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆