简体   繁体   中英

Is it possible to override a method of one class, in another class?

Is it possible to override a toString() method in another class through another class, so you don't have to rewrite a whole class just so you can rewrite one method? For example, I want to rewrite the toString() method in the Calendar class with this segment of code:

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

so that it will return something like,

17/03/2019

instead of a barely readable String like,

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]

If not, can I have some suggestions on how I can write a method to accomplish something similar to this?

Allow me to suggest a different approach.

Separate your model and business logic from your user interface. Dates belong in your model. String representations of dates belong in the interface.

In your model use LocalDate for dates. Under no circumstances resort to the old Calendar , Date and SimpleDateFormat . Those classes are poorly designed and long outdated.

In your interface use a DateTimeFormatter for formatting the LocalDate from the model into a string suitable for the user. Prefer to use the built-in localized formats rather than building your own from a format pattern string.

Sometimes it's good to have an object with a toString method that gives a string suitable for presentation. This could for example be the case if we want to present our objects in a JList . In this case wrap your business objects in UI objects, for example like this:

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);
    }

}

Only please keep this class in your UI code. If for example the model needs a selected date, take the LocalDate out of the PresentableDate and pass only the LocalDate back to the model. PresentableDate is akin to the decorator that Louis Wasserman suggested in a comment . It follows the Composition over inheritance principle.

And just to demonstrate that the toString method works:

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

Output:

19-03-18

Links

Yes, you could accomplish a different 'toString' function for the GregorianCalendar by extending GregorianCalendar.java in a subclass called, in this example, CoolGregorianCalendar.

Extending the class will allow you to Override the Object#toString method and supply whatever String you want.

Object#toString is conventionally used to concisely and informatively represent an object in an easy to read fashion. It's recommended that "all subclasses override this method."

Here's the code for the 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);
    }

}

Based on the fact that it's meant to uniquely identify that object, two objects could be created at the same time and yield the same toString representation - but that's an issue for you to pursue :)

You can read up further on inheritance from oracle's documentation over @ https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html

and you can also read further about overriding Object#toString over at
- https://docs.oracle.com/javase/6/docs/api/java/lang/Object.html#toString%28%29

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM