#Thinking in Java阅读笔记# 第七章 复用类

组合

在新类中直接使用一个现有类

继承

分为子类和超类,单线继承
当子类初始化时,子类的构造器会调用超类的构造器来进行初始化:
1.当超类构造器是默认构造器时,java会自动调用超类构造器,不需要显式,且初始化顺序是按照继承链从上至下的
2.当超类构造器需要传递参数时,则需要显示调用超类构造器(super),且超类初始化要放在子类构造器的最前端
3.在子类中重载某方法(即方法名相同、参数不同)时,其超类的重载方法不会被屏蔽。所以子类打算覆盖超类的方法时,最好使用@Override,从而避免出现重载而不是覆盖
4.组合是新类使用现有类的功能,如car类含有wheel类、engine类,是has-a关系
而继承是子类着重使用超类的接口,即将超类具象化,如car类继承于交通工具类,是is-a关系

protected关键词

标注的方法或域可以被包类成员或子类成员直接访问

class car{
    private String name;
    public car(String name) {this.name = name;}
    protected void print() {
        System.out.println("This car is "+name);
    }
}
public class TestJava extends car {
    public TestJava() {
        super("cargo");
    }
    public static void main(String[] args) {
        TestJava t = new TestJava();
        t.print();
    }
}

向上转型

向上转型是较专用的类转换为较通用的类,是安全的,因为超类的方法一定会出现在子类中。反之向下转型则不一定。

class car{
    private String name;
    public car(String name) {this.name = name;}
    static void print(car car) {
        System.out.println("Upcasting "+ car.name);
    }
}
public class TestJava extends car {
    public TestJava() {
        super("testJava");
    }
    public static void main(String[] args) {
        TestJava t = new TestJava();
        print(t);
    }
}
TestJava类可以向上转型为car类,从而使用car的print()

如果需要使用到向上转型,则考虑使用继承,否则不能滥用

final关键字

final常量
编译时常量:必须是基本数据类型,且用final表示,其常数值不改变,在定义时必须进行赋值
final+对象变量:即引用不变,不能再指向其他的对象,但是对象本身是可以改变的
static final和final的区别:

public class TestJava{
    private final double v1 = Math.random();
    private static final double V2 = Math.random();
    public TestJava() {
        System.out.println("v1 = "+ v1+" v2 ="+V2);
    }
    public static void main(String[] args) {
        TestJava t1 = new TestJava();
        TestJava t2 = new TestJava();
    }
}
运行结果:
v1 = 0.7564865351250981 v2 =0.17331080339009453
v1 = 0.32456387882746096 v2 =0.17331080339009453

即v1在不同的对象中是不同的,即对象初始化时v1也会初始化,但是V2是在装载时已经被初始化的,不会随着创建新对象而改变。
空白final:即指定为final但是未给定初值的域,这样会有更大的灵活性。需要保证在final域使用前初始化,即定义时或者在构造函数中给final域赋值

public class TestJava{
    private final int v1 = 1;//定义时初始化
    private final int v2;//空白final
    public TestJava() {
        v2 = 2;
    }
    public TestJava(int i) {
        v2 = i;
    }
    public void print() {
        System.out.println("v1 = "+v1+",v2 = "+v2);
    }
    public static void main(String[] args) {
        TestJava t1 = new TestJava();
        t1.print();
        TestJava t2 = new TestJava(4);
        t2.print();
    }
}
运行结果为:
v1 = 1,v2 = 2
v1 = 1,v2 = 4

final方法
final方法是为了防止其子类覆盖该方法。private方法隐式的制定为final
final类
final类不能被继承,其所有方法都被默认为final的,但是其域不一定

猜你喜欢

转载自blog.csdn.net/zhou373986278/article/details/78399465