[Java] 编程思想 - 复用类

avatarplhDigital nomad

Protect 关键字

当使用protected 关键字的时候,允许子类访问(跨包也行),且同一包内的类也可以访问。

class Villain {
    private String name;
    protected void set(String nm) {
        name = nm;
    }
    public String toString() {
        return "I am a Villain and my name is " + name;
    }
}

public class Orc extends Villain {
    private int orcNumber;
    public Orc(String name, int orcNumber) {
        set(name); // Available because it's protected
        this.orcNumber = orcNumber;
    }
    public void change(String name, int orcNumber) {
        set(name); // Available because it's protected
        this.orcNumber = orcNumber;
    }
    public String toString() {
        return "I am an Orc and my name is " + super.toString() +
                " and my number is " + orcNumber;
    }
    public static void main(String[] args) {
        Orc orc = new Orc("Limburger", 12);
        System.out.println(orc);
        orc.change("Bob", 19);
        System.out.println(orc);
    }
    
}

final Key Word

一个永不改变的字段

class Value {
    int i;
    public Value(int i) {
        this.i = i;
    }
}

public class FinalData {
    private static Random rand = new Random(47);
    private String id;
    public FinalData(String id) { this.id = id; }
    // Can be compile-time constants
    private final int valueOne = 9;
    private static final int VALUE_TWO = 99;
    // Typical public constant:
    public static final int VALUE_THREE = 39;
    // Cannot be compile-time constants:
    private final int i4 = rand.nextInt(20);
    static final int INT_5 = rand.nextInt(20);
    private Value v1 = new Value(11);
    private final Value v2 = new Value(22);
    private static final Value VAL_3 = new Value(33);
    // Arrays:
    private final int[] a = {1, 2, 3, 4, 5, 6};
    public String toString() {
        return id + ": " + "i4 = " + i4 + ", INT_5 = " + INT_5;
    }
    public static void main(String[] args) {
        FinalData fd1 = new FinalData("fd1");
        // fd1.valueOne++; // Error: can't change value
        fd1.v2.i++; // Object isn't constant
        fd1.v1 = new Value(9); // OK -- not final
        for(int i = 0; i < fd1.a.length; i++)
            fd1.a[i]++; // Object isn't constant
        // fd1.v2 = new Value(0); // Error: Can't
        // fd1.VAL_3 = new Value(1); // Error: can't change reference
        // fd1.a = new int[3]; // Error: can't change reference
        System.out.println(fd1);
        System.out.println("Creating new FinalData");
        FinalData fd2 = new FinalData("fd2");
        System.out.println(fd1);
        System.out.println(fd2);
    }
}

final and private key word

some time if method private, cannot call

class WithFinals {
    private final void f() {
        System.out.println("WithFinals.f()");
    }

    private void g() {
        System.out.println("WithFinals.g()");
    }
}

class OverridingPrivate extends WithFinals {
    // Attempting to override the private method f() from WithFinals
    // This is not actually overriding, but defining a new method
    private final void f() {
        System.out.println("OverridingPrivate.f()");
    }

    // This is also not overriding, but defining a new method
    private void g() {
        System.out.println("OverridingPrivate.g()");
    }
}

class OverridingPrivate2 extends OverridingPrivate {
    public final void f() {
        System.out.println("OverridingPrivate2.f()");
    }

    public void g() {
        System.out.println("OverridingPrivate2.g()");
    }
}

public class FinialOverridingIllusion {
    public static void main(String[] args) {
        OverridingPrivate2 op2 = new OverridingPrivate2();
        op2.f(); // Calls OverridingPrivate2's f()
        op2.g(); // Calls OverridingPrivate2's g()
        OverridingPrivate op = op2;
        // op.f(); // Calls OverridingPrivate2's f()
        // op.g(); // Calls OverridingPrivate2's g()
        WithFinals wf = op2;
        // wf.g(); // Calls OverridingPrivate2's g()
        // wf.f(); // Error: f() is not visible
    }
}

继承和初始化

了解包括继承在内的初始化过程,对全局性的把我很有益。

class Insect {
    private int i = 9;
    protected int j;
    Insect() {
        System.out.println("i = " + i + ", j = " + j);
        j = 39;
    }
    private static int x1 = printInit("static Insect.x1 initialized");
    static int printInit(String s) {
        System.out.println(s);
        return 47; 
    }
}

public class Beetle extends Insect {
    private int k = printInit("Beetle.k initialized");
    public Beetle() {
        System.out.println("k = " + k);
        System.out.println("j = " + j);
    }
    private static int x2 = printInit("static Beetle.x2 initialized");
    public static void main(String[] args) {
        System.out.println("Beetle constructor");
        Beetle b = new Beetle();
    }
}

总结

继承和组合都能生成新的类型,组合是将新类型重新实现一次,而继承是复用的接口。尽管继承很被强调,但是优先选择组合模式,因为控制力度更强更灵活