【问题标题】:Is it possible to override a method of one class, in another class?是否可以在另一个类中覆盖一个类的方法?
【发布时间】:2019-03-17 20:57:51
【问题描述】:

是否可以通过另一个类重写另一个类中的 toString() 方法,这样您就不必重写整个类就可以重写一个方法?比如我想用这段代码重写Calendar类中的toString()方法:

public String toString() {
    Date date = getTime();
    DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
    return dateFormat.format(date);
}

这样它会返回类似的东西,

17/03/2019

而不是像几乎不可读的字符串,

java.util.GregorianCalendar[time=1552855726815,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="America/New_York",offset=-18000000,dstSavings=3600000,useDaylight=true,transitions=235,lastRule=java.util.SimpleTimeZone[id=America/New_York,offset=-18000000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=3,startMonth=2,startDay=8,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=3,endMonth=10,endDay=1,endDayOfWeek=1,endTime=7200000,endTimeMode=0]],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2019,MONTH=2,WEEK_OF_YEAR=12,WEEK_OF_MONTH=4,DAY_OF_MONTH=17,DAY_OF_YEAR=76,DAY_OF_WEEK=1,DAY_OF_WEEK_IN_MONTH=3,AM_PM=1,HOUR=4,HOUR_OF_DAY=16,MINUTE=48,SECOND=46,MILLISECOND=815,ZONE_OFFSET=-18000000,DST_OFFSET=3600000]

如果没有,我能否就如何编写一个方法来完成类似的事情提出一些建议?

【问题讨论】:

  • 您不必为了重写一个方法而重写整个类。但是为什么你需要覆盖toString()?为什么不采用一种新方法来满足您的需求? Java 中toString() 方法的目的是提供一种以文本方式表示对象的方法。如果你覆盖它,你将消除它的预期目的。
  • 只需扩展所需的类即可。但是这样做只是为了覆盖像toString() 这样的辅助方法可能没有必要。我怀疑有更好的方法来完成你想要做的事情。为什么不直接写一个把字符串转换成你想要的格式的方法呢?
  • 在 toString() 方法中添加一个 Calendar 参数,并在此 Calendar 上调用 getTime。 docs.oracle.com/javase/tutorial/java/javaOO/arguments.html。另外,请停止使用日历和日期。它们已经过时了。使用 java.time 包中的类。
  • 看起来像XY problem。什么是上下文以及您真正想要完成什么?
  • 另一个问题,bob larry,你已经问了 6 个关于 Stack Overflow 的问题,谢谢你,并收到了其中 5 个的答案。是时候学会接受答案了吗?请阅读What should I do when someone answers my question?(并获得徽章)。

标签: java string oop calendar tostring


【解决方案1】:

请允许我提出不同的方法。

将您的模型和业务逻辑与您的用户界面分开。日期属于您的模型。日期的字符串表示属于接口。

在您的模型中,使用 LocalDate 作为日期。在任何情况下都不要使用旧的CalendarDateSimpleDateFormat。这些类设计不佳且早已过时。

在您的界面中,使用DateTimeFormatter 将模型中的LocalDate 格式化为适合用户的字符串。更喜欢使用内置的本地化格式,而不是从格式模式字符串构建您自己的格式。

有时最好有一个带有toString 方法的对象,该方法可以提供适合表示的字符串。例如,如果我们想在JList 中呈现我们的对象,就可能出现这种情况。在这种情况下,将您的业务对象包装在 UI 对象中,例如:

public class PresentableDate {

    private static final DateTimeFormatter dateFormatter = DateTimeFormatter
            .ofLocalizedDate(FormatStyle.SHORT)
            .withLocale(Locale.CANADA_FRENCH);

    LocalDate date;

    public PresentableDate(LocalDate date) {
        this.date = date;
    }

    @Override
    public String toString() {
        return date.format(dateFormatter);
    }

}

请仅将此类保留在您的 UI 代码中。例如,如果模型需要选定日期,则将 LocalDatePresentableDate 中取出,然后仅将 LocalDate 传递回模型。 PresentableDate类似于 Louis Wasserman 建议的 decorator in a comment。它遵循组合优于继承的原则。

只是为了证明toString方法有效:

    System.out.println(new PresentableDate(LocalDate.now(ZoneId.of("America/Toronto"))));

输出:

19-03-18

链接

【讨论】:

    【解决方案2】:

    是的,您可以通过在名为 CoolGregorianCalendar 的子类中扩展 GregorianCalendar.java 来为 GregorianCalendar 完成不同的“toString”函数。

    扩展类将允许您覆盖 Object#toString 方法并提供您想要的任何字符串。

    Object#toString 通常用于以易于阅读的方式简洁、信息丰富地表示对象。建议“所有子类都覆盖这个方法”。

    这是 CoolGregorianCalendar.java 的代码

    import java.text.DateFormat;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.GregorianCalendar;
    
    public class CoolGregorianCalendar extends GregorianCalendar {
    
        @Override
        public String toString() {
            Date date = getTime();
            DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
            return dateFormat.format(date);
        }
    
    }
    

    基于它旨在唯一标识该对象这一事实,可以同时创建两个对象并产生相同的 toString 表示 - 但这是你要追求的问题:)

    您可以通过 @https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html 进一步阅读 oracle 文档中的继承

    您还可以阅读更多关于在以下位置覆盖 Object#toString 的信息
    - https://docs.oracle.com/javase/6/docs/api/java/lang/Object.html#toString%28%29

    【讨论】:

    • @boblarry 不,这不是一个好主意或好习惯。
    • @Zephyr 我欢迎另一种解决方案,让一个类的方法在不使用继承的情况下执行其他操作,而不是使用单独的名称,这并不是 OP 所要求的。
    • 请不要使用“dd/MM/yyyy”,因为它是模棱两可的,因此并不比“勉强可读”的原版好多少。如果您要使用数字表示法,请遵循 ISO-8601 标准,并将较大的单位保留在左侧,就像使用其他数字表示法一样。
    • @nathan3882 试图修改其他类的行为通常不是一个好习惯,不管你怎么做。它可能满足 OP 的指定约束,但可能任何满足这些约束的答案仍然是“养成的坏习惯”。 (就良好的编码实践而言,单独的装饰器类或 static String dateToString(Date) 可能是更好的解决方案。)
    猜你喜欢
    • 2020-11-16
    • 2011-09-11
    • 1970-01-01
    • 2017-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-21
    相关资源
    最近更新 更多