Java - 回到静态方法的继承

Posted

技术标签:

【中文标题】Java - 回到静态方法的继承【英文标题】:Java - Back to inheritance of static methods 【发布时间】:2014-03-03 17:21:44 【问题描述】:

我阅读了很多帖子和文章,现在明白了静态方法不能被继承。为了解释我的问题,您可以查看以下代码:

主类:

public class DataTable 
public String id;
public String date;

public String reserve() throws SQLException 
    ......
    String query="insert into `" + this.getClass().getSimpleName() +"`() values ()";
    ........
    String key = ......
    .......
    return key;


其中一个子类:

public class Contact extends DataTable
public String firstName;
public String lastName;
public String phoneNumber;
    ...........

有了这个,如果我需要在某个时间点预订联系人,我需要写:

Contact contact=new Contact();
String id = contact.reserve();

这行得通。但我发现它不是最优的。对我来说,第一行完全没用。我更喜欢写作:

String id = Contact.reserve();

代码会更简洁,我猜它会在运行时使用更少的资源,因为它不必创建我们真正不需要的 Contact 实例。但为此,我应该:

在每个子类中创建一个特定的reserve() 静态方法并将其从主类中移除。我真的不认为它更好,因为我会在大量类中拥有完全相同的代码; 或在主类中将reserve()设为静态,并允许它访问调用它的类名,这在java中似乎不可行。

我希望我的问题足够清楚。关于如何处理的任何想法?还是我应该保持原样?

【问题讨论】:

我真的不明白为什么你觉得它不是最优的:代码很干净,如果需要特定的reserve 实现,你可以创建Contact 的子类。甚至更好:将其作为实用方法并传递所需的参数,而不是进行这样的 static 继承 【参考方案1】:

不要将更少的代码行误认为是“更干净”。

代码会更简洁,我猜它会在运行时使用更少的资源,因为它不必创建我们真正不需要的 Contact 实例。

我不同意。您显然是在保留联系人object,而不是类,因此在该类的实例上调用reserve 更有意义。当然,如果您想将其缩小到一行,您可以这样做:

new Contact().reserve();

...这可能会或可能不会更清楚,具体取决于您是否需要重用联系人对象。在这种情况下不要陷入创建对象的开销中——好的风格更重要。除非您注意到这种方式不够快,否则您没有遇到问题。

简而言之,从上面的代码来看,在我看来事情就像现在这样完美无缺。

【讨论】:

【参考方案2】:

如果都是多余的代码行,那么有什么问题:

String id = new Contact().reserve();

当然,每次调用都会创建一个 Contact 对象。如果这不可接受,那么为什么不使用单例:

String id = Contact.instance.reserve();

这只会创建一个联系人实例,并且具有保留不是静态的优点。

【讨论】:

【参考方案3】:
public class DataTable 
    //...

    public static String reserve(Class clazz) throws SQLException     
        ......
        String query="insert into `" + clazz.getSimpleName() +"`() values ()";
        ........
        String key = ......
        .......
        return key;
    

那么你可以这样称呼它DataTable.reserve(Contact.class);

【讨论】:

【参考方案4】:

您的联系人已经扩展了 DataTable,因此您在联系人中已经有了一个保留方法。您现在可以覆盖该方法,甚至可以编写新方法

public class Contact extends DataTable 

   public String reserve() throws SQLException 
       super.reserve();
       System.out.println("I override the super class");
   


如果您不扩展 DataTable,那么您实际上将其视为实用程序,因此您的 DataTable 具有类似于

的签名
public class DataTable 
     public static String doReserve(String id, Date date) 
         // do your logic
     

并简单地从 Contact 静态调用 DataTable.doReserve 方法。

【讨论】:

以上是关于Java - 回到静态方法的继承的主要内容,如果未能解决你的问题,请参考以下文章

java中静态变量与静态方法的继承(转)

Java中静态变量与静态方法的继承

Java静态属性静态方法非静态属性非静态方法的继承问题简单了解

java中私有的属性、静态成员可以被子类继承吗?

Java中静态变量与静态方法的继承

Java中的静态方法是继承的吗?