代码无法编译:
Test.java:8:Bar 中的 method() 不能覆盖 Foo 中的 method();被覆盖的方法是 static final public static void method() {
该消息具有误导性,因为根据定义,静态方法永远不会被覆盖。
我在编码时执行以下操作(不是一直 100%,但这里没有什么是“错误的”:
(第一组“规则”适用于大多数事情——之后会涉及一些特殊情况)
- 创建接口
- 创建一个实现接口的抽象类
- 创建扩展抽象类的具体类
- 创建实现接口但不扩展抽象类的具体类
- 如果可能,总是使接口的所有变量/常量/参数
由于接口不能具有静态方法,因此您不会遇到问题。如果要在抽象类或具体类中创建静态方法,它们必须是私有的,那么就无法尝试覆盖它们。
特别案例:
实用程序类(具有所有静态方法的类):
- 将类声明为 final
- 给它一个私有构造函数以防止意外创建
如果您想在非私有的具体或抽象类中拥有一个静态方法,您可能希望改为创建一个实用程序类。
值类(一个非常专门用于保存数据的类,例如 java.awt.Point,它几乎保存了 x 和 y 值):
- 无需创建接口
- 无需创建抽象类
- 类应该是最终的
- 非私有静态方法是可以的,特别是对于您可能想要执行缓存的构造。
如果您遵循上述建议,您将获得非常灵活的代码,并且具有相当清晰的职责分离。
一个示例值类是这个 Location 类:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public final class Location
implements Comparable<Location>
{
// should really use weak references here to help out with garbage collection
private static final Map<Integer, Map<Integer, Location>> locations;
private final int row;
private final int col;
static
{
locations = new HashMap<Integer, Map<Integer, Location>>();
}
private Location(final int r,
final int c)
{
if(r < 0)
{
throw new IllegalArgumentException("r must be >= 0, was: " + r);
}
if(c < 0)
{
throw new IllegalArgumentException("c must be >= 0, was: " + c);
}
row = r;
col = c;
}
public int getRow()
{
return (row);
}
public int getCol()
{
return (col);
}
// this ensures that only one location is created for each row/col pair... could not
// do that if the constructor was not private.
public static Location fromRowCol(final int row,
final int col)
{
Location location;
Map<Integer, Location> forRow;
if(row < 0)
{
throw new IllegalArgumentException("row must be >= 0, was: " + row);
}
if(col < 0)
{
throw new IllegalArgumentException("col must be >= 0, was: " + col);
}
forRow = locations.get(row);
if(forRow == null)
{
forRow = new HashMap<Integer, Location>(col);
locations.put(row, forRow);
}
location = forRow.get(col);
if(location == null)
{
location = new Location(row, col);
forRow.put(col, location);
}
return (location);
}
private static void ensureCapacity(final List<?> list,
final int size)
{
while(list.size() <= size)
{
list.add(null);
}
}
@Override
public int hashCode()
{
// should think up a better way to do this...
return (row * col);
}
@Override
public boolean equals(final Object obj)
{
final Location other;
if(obj == null)
{
return false;
}
if(getClass() != obj.getClass())
{
return false;
}
other = (Location)obj;
if(row != other.row)
{
return false;
}
if(col != other.col)
{
return false;
}
return true;
}
@Override
public String toString()
{
return ("[" + row + ", " + col + "]");
}
public int compareTo(final Location other)
{
final int val;
if(row == other.row)
{
val = col - other.col;
}
else
{
val = row - other.row;
}
return (val);
}
}