第四章类和接口

2020-03-11  本文已影响0人  后来丶_a24d

目录


类和接口

使类和成员的可访问性最小化

在公共类中使用访问方法而不是公共属性

// 错误eg
class Point {
    public double x;
    public double y;
}
// 正确eg
class Point {
    private double x;
    private double y;

    public Point(double x, double y) {
        this.x = x;
        this.y = y;
    }

    public double getX() { return x; }

    public double getY() { return y; }

    public void setX(double x) { this.x = x; }

    public void setY(double y) { this.y = y; }

}

最小化可变性

  1. 不要提供修改对象状态的方法
  2. 确保这个类不能被继承
  3. 把所有属性设置为final,private
  4. 确保对任何可变组件的互斥访问(返回new对象)
  5. 有关序列化,如果让自己的不可变类实现序列化,就必须显式提供 readObject 或者 readResolve,否则反序列化可能会产生新的实例
public final class Complex {

    private final double re;

    private final double im;

    private Complex(double re, double im) {

        this.re = re;

        this.im = im;

    }
// 将构造函数改为私有的,并添加静态工厂来替代公有构造器
public static Complex valueOf(double re, double im) {
        return new Complex(re, im);
    }

    public double realPart() {

        return re;

    }

    public double imaginaryPart() {

        return im;

    }

    public Complex plus(Complex c) {

        return new Complex(re + c.re, im + c.im);

    }

    public Complex minus(Complex c) {

        return new Complex(re - c.re, im - c.im);

    }

    public Complex times(Complex c) {

        return new Complex(re * c.re - im * c.im,

                re * c.im + im * c.re);

    }

    public Complex dividedBy(Complex c) {

        double tmp = c.re * c.re + c.im * c.im;

        return new Complex((re * c.re + im * c.im) / tmp,

                (im * c.re - re * c.im) / tmp);

    }

    @Override

    public boolean equals(Object o) {

        if (o == this) {

            return true;

        }

        if (!(o instanceof Complex)) {

            return false;

        }

        Complex c = (Complex) o;

        // See page 47 to find out why we use compare instead of ==

        return Double.compare(c.re, re) == 0

                && Double.compare(c.im, im) == 0;

    }

    @Override

    public int hashCode() {

        return 31 * Double.hashCode(re) + Double.hashCode(im);

    }

    @Override

    public String toString() {

        return "(" + re + " + " + im + "i)";

    }
}

组合优于继承

public class InstrumentedHashSet<E> extends HashSet<E> {
    // The number of attempted element insertions
    private int addCount = 0;

    public InstrumentedHashSet() {
    }

    public InstrumentedHashSet(int initCap, float loadFactor) {
        super(initCap, loadFactor);
    }
    @Override public boolean add(E e) {
        addCount++;
        return super.add(e);
    }
    @Override public boolean addAll(Collection<? extends E> c) {
        addCount += c.size();
        return super.addAll(c);
    }
    public int getAddCount() {
        return addCount;
    }
}
public class ForwardingSet<E> implements Set<E> {

    private final Set<E> s;

    public ForwardingSet(Set<E> s) {
        this.s = s;
    }

    public void clear() {
        s.clear();
    }

    public boolean contains(Object o) {
        return s.contains(o);
    }

    public boolean isEmpty() {
        return s.isEmpty();
    }

    public int size() {
        return s.size();
    }

    public Iterator<E> iterator() {
        return s.iterator();
    }

    public boolean add(E e) {
        return s.add(e);
    }

    public boolean remove(Object o) {
        return s.remove(o);
    }

    public boolean containsAll(Collection<?> c) {
        return s.containsAll(c);
    }

    public boolean addAll(Collection<? extends E> c) {
        return s.addAll(c);
    }

    public boolean removeAll(Collection<?> c) {
        return s.removeAll(c);
    }

    public boolean retainAll(Collection<?> c) {
        return s.retainAll(c);
    }

    public Object[] toArray() {
        return s.toArray();
    }

    public <T> T[] toArray(T[] a) {
        return s.toArray(a);
    }

    @Override
    public boolean equals(Object o) {
        return s.equals(o);
    }

    @Override
    public int hashCode() {
        return s.hashCode();
    }

    @Override
    public String toString() {
        return s.toString();
    }
}

public class InstrumentedSet<E> extends ForwardingSet<E> {

    private int addCount = 0;

    public InstrumentedSet(Set<E> s) {
        super(s);
    }
    
    @Override public boolean add(E e) {
        addCount++;
        return super.add(e);
    }

    @Override public boolean addAll(Collection<? extends E> c) {
        addCount += c.size();
        return super.addAll(c);
    }

    public int getAddCount() {
        return addCount;
    }
}

如果使用继承则设计,并文档说明,否则不该使用

接口优于抽象类

为后代设计接口

接口仅用来定义类型

优先使用类层次而不是标签类

优先考虑静态成员类

将源文件限制为单个顶级类

public class Test {

    public static void main(String[] args) {

        System.out.println(Utensil.NAME + [Dessert.NAME](http://Dessert.NAME));

    }

    private static class Utensil {

        static final String NAME = "pan";

    }

    private static class Dessert {

        static final String NAME = "cake";

    }

}

参考文章

上一篇下一篇

猜你喜欢

热点阅读