10.2 protected关键字

继承有如下特点:
1.一个类只能继承一个类,不支持多继承。例如A extends B,C这样是非法的。
2.子类对象能访问父类的带protected修饰符的属性和方法,protected意味着这个属性或方法可以被子类对象直接使用。
3.子类会继承父类的所有非private(protected和public)的属性和方法,这些属性也是子类的属性和方法。
例如下面的代码,Square是子类,于是Square继承了父类Rectangle的两个属性:length,height。
public class Rectangle{
    protected double length;
    protected double height;
    public double sqr(){
        return length*height;
    }
    public double cc(){
        return 2*(length+height);
    }
}
public class Square extends Rectangle{
    public Square(double length){
        this.height=length;
        this.length=length;
    }
}
public static void main(String[]args){
    Square s=new Square(4);
    System.out.println(s.sqr());
}
最终会打印16.这里Square定义了一个构造方法,接受一个参数,把这个参数赋值给父类Rectangle的length和height(长和高)的值,长和高的值一样,也就是正方形了。
在这里子类就是使用了父类的protected属性length和height,在Square里面是没有这两个属性的,但是Square仍然可以使用。 s.sqr()调用的是父类Rectangle的sqr方法,由于s是Square(正方形),也是Rectangle(矩形)的一种,所以s也是Rectangle,由此s可以调用Rectangle内所有方法。
这就是继承关系:Square是Rectangle的一种,Square的对象s也是Recangle对象!那么这个对象s当然可以调用Rectangle的方法了。事实上,可以这样写:
public static void main(String[]args){
    Rectangle sq=new Square(4);
    System.out.println(sq.cc());
}
这看上去非常奇怪,sq声明类型是Rectangle,实际调用的构造函数却是Square!sq是一个Rectangle(矩形),实际类型是Square(正方形)。反过来的话,会出语法错误。
public static void main(String[]args){
    //语法错误!
    Square sq=new Rectangle();
}

最后是关于protected的访问控制的,一个对象是否能直接访问它的protected属性,取决于这个对象的位置,例如下面的代码:
public static void main(String[]args){
    Rectangle s=new Rectangle();
    s.height=4;
    s.lenght=5;
    System.out.println(s.sqr());
}
这个main函数里面的s是一个Rectangle对象,直接修改了s的height和length值。这段代码只能在Rectangle类同一个包(package)内才不会有语法错误
因为这个Test在abcd包,而Rectangle在abc包,所以Rectangel的对象s不能直接访问protected属性length和height,假如Test类在abc包里,这段代码就没有语法错误。