• 访问控制符


    1 查看下列代码

     
    1. abstract class Vehicle {
    2.     public int speed() {
    3.         return 0;
    4.     }
    5. }
    6. class Car extends Vehicle {
    7.     public int speed() {
    8.         return 60;
    9.     }
    10. }
    11. class RaceCar extends Car {
    12.     public int speed() {
    13.         return 150;
    14.     }
    15. }
    16. public class TestCar {
    17.     public static void main(String[] args) {
    18.         RaceCar racer = new RaceCar();
    19.         Car car = new RaceCar();
    20.         Vehicle vehicle = new RaceCar();
    21.         System.out.println(racer.speed() + ", " + car.speed() + ", "
    22.      + vehicle.speed());
    23.     }
    24. }

    上述代码运行的结果是

    A. 0,0,0

    B. 150,60,0

    C. 150,150,150

    D. 抛出运行时异常

    参考答案

    C 选项正确。

    这是因为,子类可以重写(覆盖)继承自父类的方法,即方法名和参数列表与父类的方法相同,但方法的实现不同。当子类对象的重写方法被调用时(无论是通过子类的引用调用还是通过父类的引用调用),运行的是子类的重写后的版本。因此,本题的正确答案为选项 C。

    2 编写正六边形类继承Shape,实现其area方法

    在课上案例“根据周长计算不同形状图形的面积”基础上,编写正六边形类继承Shape,实现其area方法。

    注:正六边形的面积计算公式为:0.0721 * c * c,其中c为周长。

    参考答案:

    实现此案例需要按照如下步骤进行。

    步骤一:定义类Hexagon

    定义名为Hexagon的类,表示正六边形,使该类继承自Shape类,代码如下所示:

     
    1. public class Hexagon extends Shape {
    2. }

    步骤二:实现 area方法

    在area方法中,根据正六边形的面积公式计算面积,代码如下所示:

    1. public class Hexagon extends Shape {
    2.     public Hexagon(double c) {
    3.         this.c = c;
    4.     }
    5.     /**
    6.      * 计算正六边形的面积
    7.      */
    8. public double area() {
    9. return 0.0721 * c * c;
    10. }
    11. }

    步骤三:在测试类TestShape类中添加测试代码

    在TestShape类中,构造Hexagon类型的对象,并将其放入数组中,代码如下所示:

     
    1. public class TestShape {
    2.     public static void main(String[] args) {
    3.         Shape[] shapes = new Shape[3];
    4.         shapes[0] = new Circle(4);//数组中的第一个元素为圆形对象
    5.         shapes[1] = new Square(4);//数组中的第二个元素为正方形对象
    6.         shapes[2] = new Hexagon(4);//数组中的第三个元素为正六边形对象
    7.         maxArea(shapes);
    8.     }
    9. public static void maxArea(Shape[] shapes) {
    10.         double max = shapes[0].area();
    11.         int maxIndex = 0;
    12.         for (int i = 1; i < shapes.length; i++) {
    13.             double area = shapes[i].area();
    14.             if (area > max) {
    15.                 max = area;
    16.                 maxIndex = i;
    17.             }
    18.         }
    19.         System.out.println("数组中索引为"+maxIndex+"的图形的面积最大,面积为:"+max);
    20.     }
    21. }

    步骤四:运行

    运行TestShape类,控制台输出结果如下所示:

     
    1. 数组中索引为0的图形的面积大,面积为:1.2736

    观察上述输出结果,可以看出,shapes[0]表示的是圆形,周长相同的情况下,圆形的面积更大些。

    本案例中,Hexagon类的完整代码如下所示:

    1. public class Hexagon extends Shape {
    2.     public Hexagon(double c) {
    3.         this.c = c;
    4.     }
    5.     /**
    6.      * 计算正六边形的面积
    7.      */
    8. public double area() {
    9. return 0.0721 * c * c;
    10. }
    11. }

    TestShape类的完整代码如下所示:

     
    1. public class TestShape {
    2.     public static void main(String[] args) {
    3.         Shape[] shapes = new Shape[3];
    4.         shapes[0] = new Circle(4);//数组中的第一个元素为圆形对象
    5.         shapes[1] = new Square(4);//数组中的第二个元素为正方形对象
    6.         shapes[2] = new Hexagon(4);//数组中的第三个元素为正六边形对象
    7.         maxArea(shapes);
    8.     }
    9. public static void maxArea(Shape[] shapes) {
    10.         double max = shapes[0].area();
    11.         int maxIndex = 0;
    12.         for (int i = 1; i < shapes.length; i++) {
    13.             double area = shapes[i].area();
    14.             if (area > max) {
    15.                 max = area;
    16.                 maxIndex = i;
    17.             }
    18.         }
    19.         System.out.println("数组中索引为"+maxIndex+"的图形的面积最大,面积为:"+max);
    20.     }
    21. }

    3 简述抽象类的意义

    参考答案:

    抽象类的意义在于:

    1. 为其子类提供一个公共的父类型,避免该类被实例化;

    2. 封装子类中的重复内容(成员变量和方法);

    3. 定义公共抽象方法,由子类提供不同的实现。

    4 编写建设银行接口CCB继承银联接口,并实现该接口

    在课上案例“银行卡系统(实现银联接口)”的基础上,编写建设银行接口CCB。建设银行接口,用于描述中国建设银行发行的卡片功能,在满足银联接口的规则基础上,增加了支付燃气费的功能。

    参考答案

    实现此案例需要按照如下步骤进行。

    步骤一: 定义建设银行接口

    定义名为CCB的接口表示建设银行接口,用于描述中国建设银行发行的卡片功能,该接口需要满足银联接口的功能,因此,继承银联接口;该接口在具备银联接口的功能基础上,要求增加支付燃气费的功能,所以,在该接口中定义payGasBill方法,表示此功能,代码如下所示:

     
    1. /**
    2. * 接口:用于描述建设银行发行的卡片功能,在满足
    3. * 银联的规则基础上,添加自己特有的功能
    4. */
    5. public interface CCB extends UnionPay {
    6.     /**增加的支付燃气费功能*/
    7.     public void payGasBill(double number);
    8. }

    步骤二:定义建设银行接口的实现类

    首先,定义名为CCBImpl的类 ,该类实现CCB接口;另外,分析问题中的取钱功能,需要对余额信息进行存储,插入卡片以后需要输入密码后才能进行取钱,因此,在CCBImpl类中定义double类型属性money表示账户余额以及String类型属性pwd表示卡片的密码,代码如下所示:

     
    1. /**
    2. * 类:用于描述建设银行实际发行的卡片
    3. * 该卡片具有的功能来自于继承的已经符合银联规范的CCB接口
    4. */
    5. public class CCBImpl implements CCB {
    6.     private double money;
    7.     private String pwd;
    8.     
    9.     public CCBImpl(double money,String pwd){
    10.         this.money = money;
    11.         this.pwd = pwd;
    12.     }
    13. }

    步骤三:实现检查密码、获取余额、取款、支付燃气费功能

    在CCBImpl类实现checkPwd方法、getBalance方法、drawMoney方法以及payGasBill方法,代码如下所示:

     
    1. /**
    2. * 类:用于描述建设银行实际发行的卡片
    3. * 该卡片具有的功能来自于继承的已经符合银联规范的CCB接口
    4. */
    5. public class CCBImpl implements CCB {
    6.     private double money;
    7.     private String pwd;
    8.     
    9.     public CCBImpl(double money,String pwd){
    10.         this.money = money;
    11.         this.pwd = pwd;
    12.     }
    13.     
    14.     @Override
    15.     public double getBalance() {        
    16.         return money;
    17.     }
    18.     @Override
    19.     public boolean drawMoney(double number) {
    20.         if(number <= money){
    21.             money -=number;
    22.             return true;
    23.         }
    24.         return false;
    25.     }
    26.     @Override
    27.     public void payGasBill(double number) {
    28.         if(number < money){
    29.             money-=number;
    30.         }
    31.     }
    32.     @Override
    33.     public boolean checkPwd(String input) {
    34.         if(pwd.equals(input))
    35.             return true;
    36.         else
    37.             return false;
    38.     }
    39. }

    以上四个方法的实现逻辑为:

    取钱功能的实现为在当前余额的基础上减去要取的金额,如drawMoney方法的实现。

    支付燃气费功能的实现为当前余额的基础上减去要支付的金额,如payGasBill方法的实现。

    检查密码功能的实现为检查卡的密码与用户输入的密码是否相等,如果相等返回true,否则返回false,如checkPwd方法的实现。

    获取余额功能的实现为类CCBImpl中的money属性即表示余额,将其返回即可,如getBalance方法的实现。

    步骤四:测试

    在TestUnionPay类中,测试银联接口提供的方法,是否成功实现,代码如下所示:

     
    1. import java.util.Scanner;
    2. /**
    3. * 测试实现接口后的类的方法调用
    4. */
    5. public class TestUnionPay {
    6.     public static void main(String[] args) {
    7.         //ICBCImpl icbc = new ICBCImpl(2000,"123456");
    8.         //ICBC icbc = new ICBCImpl(2000,"123456");
    9.         //UnionPay icbc = new ICBCImpl(2000,"123456");
    10.         //UnionPay icbc = new ABCImpl(2000,"123456");
    11.         UnionPay ccb = new CCBImpl(2000,"123456");
    12.         Scanner input = new Scanner(System.in);
    13.         System.out.println("请输入密码:");
    14.         if(ccb.checkPwd(input.next())){
    15.             System.out.println("请输入金额:");
    16.             double num = Double.parseDouble(input.next());
    17.             if(ccb.drawMoney(num)){
    18.                 System.out.println("取钱成功,卡余额为:"+icbc.getBalance());
    19.             }
    20.             else{
    21.                 System.out.println("取钱失败");
    22.             }
    23.         }else{
    24.             System.out.println("密码错误");
    25.         }
    26.     }
    27. }

    查看上述代码,可以看出上述代码是采用CCBImpl类来实例化银联接口UnionPay的,运行后,实现了取款功能。

    本案例中,UnionPay接口的完整代码如下所示:

     
    1. /**
    2. * 接口:用于描述银联统一制定的规则
    3. */
    4. public interface UnionPay {
    5.     /**查看余额*/
    6.     public double getBalance();    
    7.     /**取钱*/
    8.     public boolean drawMoney(double number);
    9.     /**检查密码*/
    10.     public boolean checkPwd(String input);
    11. }
     

    CCB接口的完整代码如下所示:

     
    1. /**
    2. * 接口:用于描述建设银行发行的卡片功能,在满足
    3. * 银联的规则基础上,添加自己特有的功能
    4. */
    5. public interface CCB extends UnionPay {
    6.     /**增加的支付燃气费功能*/
    7.     public void payGasBill(double number);
    8. }
     

    CCBImpl类的完整代码如下所示:

     
    1. /**
    2. * 类:用于描述建设银行实际发行的卡片
    3. * 该卡片具有的功能来自于继承的已经符合银联规范的CCB接口
    4. */
    5. public class CCBImpl implements CCB {
    6.     private double money;
    7.     private String pwd;
    8.     
    9.     public CCBImpl(double money,String pwd){
    10.         this.money = money;
    11.         this.pwd = pwd;
    12.     }
    13.     
    14.     @Override
    15.     public double getBalance() {        
    16.         return money;
    17.     }
    18.     @Override
    19.     public boolean drawMoney(double number) {
    20.         if(number <= money){
    21.             money -=number;
    22.             return true;
    23.         }
    24.         return false;
    25.     }
    26.     @Override
    27.     public void payGasBill(double number) {
    28.         if(number < money){
    29.             money-=number;
    30.         }
    31.     }
    32.     @Override
    33.     public boolean checkPwd(String input) {
    34.         if(pwd.equals(input))
    35.             return true;
    36.         else
    37.             return false;
    38.     }
    39. }

    TestUnionPay类的完整代码如下所示:

     
    1. import java.util.Scanner;
    2. /**
    3. * 测试实现接口后的类的方法调用
    4. */
    5. public class TestUnionPay {
    6.     public static void main(String[] args) {
    7.         //ICBCImpl icbc = new ICBCImpl(2000,"123456");
    8.         //ICBC icbc = new ICBCImpl(2000,"123456");
    9.         //UnionPay icbc = new ICBCImpl(2000,"123456");
    10.         //UnionPay icbc = new ABCImpl(2000,"123456");
    11.         UnionPay ccb = new CCBImpl(2000,"123456");
    12.         Scanner input = new Scanner(System.in);
    13.         System.out.println("请输入密码:");
    14.         if(ccb.checkPwd(input.next())){
    15.             System.out.println("请输入金额:");
    16.             double num = Double.parseDouble(input.next());
    17.             if(ccb.drawMoney(num)){
    18.                 System.out.println("取钱成功,卡余额为:"+icbc.getBalance());
    19.             }
    20.             else{
    21.                 System.out.println("取钱失败");
    22.             }
    23.         }else{
    24.             System.out.println("密码错误");
    25.         }
    26.     }
    27. }
     

    5 关于接口和抽象类,下列说法正确的是

    A. 抽象类和接口都不能实例化。

    B. 接口里只能包含抽象方法,抽象类则可以包含普通方法。

    C. 接口里不包含构造器,抽象类里可以包含构造器。

    D. 一个类只能实现一个接口

    参考答案:

    选项ABC是正确的。

    选项A,抽象类和接口都不能实例化对象,用于被其他类继承和实现。

    选项B,接口里只能包含抽象方法,抽象类则可以包含普通方法和抽象方法。

    选项C,接口里不包含构造器;抽象类里可以包含构造器,抽象类里的构造器并不是用于创建对象,而是让其子类调用这些构造器来完成属于抽象类的初始化操作。

    选项D,一个类只能有一个直接父类;但一个类可以直接实现多个接口,实现多继承。

  • 相关阅读:
    C++计算器项目的初始部分
    视频教程自学计划
    1001.A+B Format (20)解题描述
    成为理想的自己
    Sample Join Analysis
    Sample MultipleFileWordcount CombineFileInputFormat
    FileOutputFormat
    Combine small files to Sequence file
    FileInputFormat
    Sample: Write And Read data from HDFS with java API
  • 原文地址:https://www.cnblogs.com/xyk1987/p/8329862.html
Copyright © 2020-2023  润新知