How can I implement abstract static methods in Jav

2019-03-18 06:22发布

There are numerous questions about the impossibility of including static abstract Java methods. There are also quite a lot about workarounds for this (design flaw/design strength). But I can't find any for the specific problem I'm going to state shortly.

It seems to me that the people who made Java, and quite a lot of the people who use it, don't think of static methods the way I, and many others, do - as class functions, or methods that belong to the class and not to any object. So is there some other way of implementing a class function?

Here is my example: in mathematics, a group is a set of objects that can be composed with each other using some operation * in some sensible way - for example, the positive real numbers form a group under normal multiplication (x * y = x × y), and the set of integers form a group, where the 'multiplication' operation is is addition (m * n = m + n).

A natural way to model this in Java is to define an interface (or an abstract class) for groups:

public interface GroupElement
{
  /**
  /* Composes with a new group element.
  /* @param elementToComposeWith - the new group element to compose with.
  /* @return The composition of the two elements.
   */
  public GroupElement compose(GroupElement elementToComposeWith)
}

We can implement this interface for the two examples I gave above:

public class PosReal implements GroupElement
{
  private double value;

  // getter and setter for this field

  public PosReal(double value)
  {
    setValue(value);
  }

  @Override
  public PosReal compose(PosReal multiplier)
  {
    return new PosReal(value * multiplier.getValue());
  }
}

and

public class GInteger implements GroupElement
{
  private int value;

  // getter and setter for this field

  public GInteger(double value)
  {
    setValue(value);
  }

  @Override
  public GInteger compose(GInteger addend)
  {
    return new GInteger(value + addend.getValue());
  }
}

However, there's one other important property that a group has: every group has an identity element - an element e such that x * e = x for all x in the group. For example, the identity element for positive reals under multiplication is 1, and the identity element for integers under addition is 0. In that case, it makes sense to have a method for each implementing class like the following:

public PosReal getIdentity()
{
  return new PosReal(1);
}

public GInteger getIdentity()
{
  return new GInteger(0);
}

But here we run into problems - the method getIdentity doesn't depend on any instance of the object, and should therefore be declared static (indeed, we may wish to refer to it from a static context). But if we put the getIdentity method into the interface then we can't declare it static in the interface, so it can't be static in any implementing class.

Is there any way of implementing this getIdentity method that:

  1. Forces consistency over all implementations of GroupElement, so that every implementation of GroupElement is forced to include a getIdentity function.
  2. Behaves statically; i.e., we can get the identity element for a given implementation of GroupElement without instantiating an object for that implementation.

Condition (1) is essentially saying 'is abstract' and condition (2) is saying 'is static', and I know that static and abstract are incompatible in Java. So are there some related concepts in the language that can be used to do this?

7条回答
甜甜的少女心
2楼-- · 2019-03-18 06:44

" the method getIdentity doesn't dependonany instance of the object, and should therefore be declared static"

Actually, if it does not depend on any instance, it can just return some constant value, it does not have to be static.

Just because a static method does not depend on an instance, it does not mean you should use it always for this kind of situation.

查看更多
登录 后发表回答