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包里,这段代码就没有语法错误。
练习题
-
完成下面的练习1.已知两个类,然后Apple类里面的main函数运行后,会: (2分) [选择]A.
B. 打印我是Apple
C. 打印我是Fruit
D. 语法错误
E. 什么都不打印
public class Fruit{ public void print(){ System.out.println( "我是Fruit");}} public class Apple extends Fruit{ public static void main(String[]args){ Apple b=new Apple(); b.print();}}2.关于子类和父类的属性问题,以下哪个说法是正确的 (2分) [选择]A.
B. 子类可以使用父类的protected属性
C. 子类只可以使用父类的public属性
D. 子类可以使用父类的private属性
E. 子类可以使用父类的所有属性
3.子类是父类的扩展 [阅读]子类可能会有父类没有的属性和方法,而父类并不是子类的一种,此时父类的对象是不可能知道子类增加的属性和方法的。
假如Square的代码如下,它增加了一个size属性。代码里面s1.size=4;是正确的,s2.size=5;会有语法错误!因为s2的声明类型是Rectangle,Rectangle是没有size这个属性的。public class Square extends Recangle{ private double size; public static void main(String[]args){ Square s1=new Square(); Recangle s2=new Square(); s1.size=4; s2.size=5;}} -
判断题1.已知Square继承Rectangle,语句Rectangle s2=new Square();会导致语法错误 (2分) [判断]2.已知Square继承Rectangle,语句Square s2=new Rectangle();会导致语法错误 (2分) [判断]3.已知Square继承Rectangle,Square可以使用Rectangle的所有属性 (2分) [判断]4.已知Square继承Rectangle,Square可以使用Rectangle的所有protected属性 (2分) [判断]5.已知Square继承Rectangle,Rectangle可以使用Square的所有protected属性 (2分) [判断]
-
编程题,需要写两个类(一个父类一个子类)1.设计下面的继承类 (10分) [Java多类]父类汽车类Vehicle,有一个double类型的属性speed代表最高速度。Vehicle类还需要有设置speed值的public方法setSpeed供子类调用
子类轿车类Car,它没有属性,它将使用父类的属性speed,Car有一个方法showSpeed,没有参数,没有返回值,打印这样一句话“本车的最高速度是X”,这个X就是speed属性值。
这是使用两个类的测试代码public static void main(String[]args){ Car car=new Car(); car.setSpeed(160); car.showSpeed();}