我目前在一个项目中,我有3个用户类,可以说是UserA,UserB,UserC,它们是从抽象User类继承的。

该程序应该模拟一个希望用户登录和注销的系统。

这些用户的实例存储在3个单独的列表中。

任何时候只有一个用户被“记录”,所以我有一个User currentUser变量。

当我想调用特定于UserA,B或C的方法时,我进行了强制转换。
在保持代码优美的同时,如何避免进行这种转换?

代码示例:

public abstract class User {
}

public class UserA extends User {
    public void clearAgenda();
}

public class UserB extends User {
}

public class UserC extends User {
}

public class System {
    private User loggedUser;

    public void clearUserAgenda() {
        ((UserA) loggedUser).clearAgenda();
    }
}


注意:
我事先知道,如果正在使用某项操作,则当前用户支持该操作。 (例如:如果调用System.clearUserAgenda(),则该用户是UserA的实例)

最佳答案

这是多态的明确案例。您可以在User中声明该方法(如Baalthasarr所说),然后根据需要在子类型(UserA,UserB等)中覆盖该方法。然后,您只需使用loggedUser.clearAgenda(),JRE就会确定在运行时自动使用哪种方法。

public abstract class User {
    public void clearAgenda() {} // do nothing (or or something if you want)
}

public class UserA extends User {
    @Override public void clearAgenda() { ... } // do stuff specific to A
}

public class UserB extends User {
    @Override public void clearAgenda() { ... } // do stuff specific to B
}

public class UserC extends User {
}

public class System {
    private User loggedUser;

    public void clearUserAgenda() {
        // This will use the most appropriate method. If the type is
        // UserA, UserA's `clearAgenda` method will be used. Similar
        // for UserB. For UserC, The abstract User class's `clearAgenda`
        // method is used, because it was not overridden in UserC.
        loggedUser.clearAgenda();
    }
}


如果您想做的事情对于所有User子类都是通用的,则可以将其放在User中,即使您重写该方法,也可以继续运行它。例如:

public class UserA extends User {
    @Override public void clearAgenda() {
        super.clearAgenda(); // do the stuff common to all User subclasses
        ... // do stuff specific to A
    }
}

10-06 05:17