【Big Java学习笔记】Chapter 9:Inheritance and Interfaces 继承和接口

学习目标:

1)学习继承并实现子类override方法

2)理解多态polymorphism的概念

3)熟悉common superclass Object 和它的 methods

4)学习interface types

Chapter 9.1 Inheritance Hierarchies

来自相关类的对象通常具有共同的行为。例如,铲子、耙子和剪刀都执行园艺任务。 在本章中,您将学习继承的概念如何表达专用类和通用类之间的关系。通过使用继承,您将能够在类之间共享代码并提供可供多个类使用的服务。

在面向对象的设计中,继承是更通用的类(称为超类)和更专业的类(称为子类)之间的关系。子类 subclass 从超类 superclass. 继承数据和行为。

假设我们有一个操作 Vehicle 对象的算法。因为汽车是一种特殊的交通工具,我们可以在这样的算法中使用 Car 对象,它会正常工作。 替换原则指出,当需要超类对象时,您始终可以使用子类对象。 例如,考虑一个采用 Vehicle 类型参数的方法:

void processVehicle(Vehicle v)

因为 Car 是 Vehicle 的子类,所以您可以使用 Car 对象调用该方法:

     Car myCar = new Car(. . .);

processVehicle(myCar);

为什么要提供一种处理 Vehicle 对象而不是 Car 对象的方法? 该方法更有用,因为它可以处理任何类型的车辆(包括卡车和摩托车对象)。通常,当我们将类分组到继承层次结构中时,我们可以在类之间共享公共代码。

代码实例:

在本章中,我们将考虑一个简单的类层次结构。 假设您参加了计算机分级测验,测验由不同类型问题组成:填空,选择(单选或多选),数字填空,简答题。

此层次结构的根 root 是Question。 Question可以显示其题目内容,并且可以检查输入的回答是否是正确答案。

为了打代码熟练点我手打了一下书上代码(

package chapter9;

public class Question {
    private String text;
    private String answer;

    public Question(){
        text = "";
        answer = "";
    }

    public void setText(String questionText){
        text = questionText;
    }

    public void setAnswer(String correctResponse){
        answer = correctResponse;
    }

    public boolean checkAnswer(String response){
        return response.equals(answer);
    }
    public void display(){
        System.out.println(text);
    }
}

Question类比较基础,不处理多项选择题、数字题等,下面附了一个 Question 类的简单测试程序。

package chapter9;

import java.util.Scanner;

public class QuestionTester {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        Question q = new Question();
        q.setText("Who's the inventor of Java?");
        q.setAnswer("James Gosling");

        q.display();
        System.out.println("Your answer:");
        String response = in.nextLine();
        System.out.println(q.checkAnswer(response));
    }
}

运行结果是这样的:

tips:使用单个类来改变值,使用继承来改变行为。

Chapter 9.2 Implementing Subclasses

how to form a subclass and how a subclass automatically inherits functionality from its superclass.

在9.1的Question类基础上实现 ChoiceQuestion 类,其中包含设置问题、显示问题和检查答案的方法。子类对象自动具有在超类中声明的实例变量,只需要声明不属于超类对象的实例变量。

子类继承了超类的所有 public 方法。 可以声明子类的任何新方法,如果继承的 method 不合适,则更改继承 method 的实现。 当您为继承的方法提供新的实现时,您将override该方法。

ChoiceQuestion 对象在三个方面与 Question 对象不同:1) 需要存储题目的各种选择。2) 需要一种添加题目选项的方法。3) ChoiceQuestion 类的 display 方法需要显示这些选项,以便 visitor 可以选择其中之一。

保留字 extends 表示继承。

但是,超类的 provate 实例变量是不可访问的。因为这些变量是超类的私有数据,所以只有超类可以访问它们。子类没有比任何其他类更多的访问权限。特别是,ChoiceQuestion 方法不能直接访问实例变量 answer。 这些方法必须使用 Question 类的公共接口来访问其私有数据,就像所有其他方法一样。 

package chapter9;

import java.util.ArrayList;

public class ChoiceQuestion extends Question{
    private ArrayList<String> choices;
    public void addChoice(String choice, boolean correct){
        choices.add(choice);
        if(correct){
            String choiceString = "" + choices.size();
            setAnswer(choiceString);
        }
    }
    public void display(){
    // 还没写
    }
}

您不能只访问超类中的 answer 变量。 幸运的是, Question 类有一个 setAnswer 方法。 你可以调用那个方法。

Chapter 9.3 Overriding Methods

子类继承了超类的 method。 如果您对继承的 method 不满意,您可以通过在子类中覆盖重写(override)它。

ChoiceQuestion 类的 display method 需要被重写覆盖,扩展超类的功能。该 method 需要显示题干和显示答案选项两项功能。

但是如何获得题干:不能直接访问超类的 text 变量,因为它是 private 的。但可以使用保留字 super 调用超类的 display 方法。如果省略保留字 super,则该 method 将无法按预期工作。

    public void display(){
        // question text
        super.display();
        // question choices
        for(int i = 0; i < choices.size(); i++){
            int choiceNumber = i + 1;
            System.out.println(choiceNumber + ":" + choices.get(i));
        }
    }

附上一个Test程序:

package chapter9;

import java.util.ArrayList;

public class ChoiceQuestion extends Question{
    private ArrayList<String> choices;
    public ChoiceQuestion(){
        choices = new ArrayList<>();
    }
    public void addChoice(String choice, boolean correct){
        choices.add(choice);
        if(correct){
            String choiceString = "" + choices.size();
            setAnswer(choiceString);
        }
    }
    public void display(){
        // question text
        super.display();
        // question choices
        for(int i = 0; i < choices.size(); i++){
            int choiceNumber = i + 1;
            System.out.println(choiceNumber + ":" + choices.get(i));
        }
    }
}

​​​​​​​

package chapter9;

import java.util.Scanner;

public class QuestionTester2 {
    public static void main(String[] args) {
        ChoiceQuestion first = new ChoiceQuestion();
        first.setText("What was the original name of the Java language?");
        first.addChoice("*7", false);
        first.addChoice("Duke",false);
        first.addChoice("Oak", true);
        first.addChoice("Gosling", false);

        presentQuestion(first);
    }
    public static void presentQuestion(ChoiceQuestion q){
        q.display();
        System.out.println("Your answer:");
        Scanner in = new Scanner(System.in);
        String response = in.nextLine();
        System.out.println(q.checkAnswer(response));
    }
}

运行结果如下:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值