《Java程序设计基础》 第8章手记Part 1

时间:2022-04-26
本文章向大家介绍《Java程序设计基础》 第8章手记Part 1,主要内容包括本章主要内容 Part 1、子类的创建、覆盖、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。

本章主要内容 Part 1

- 子类的创建 - 在子类中访问父类的成员 - 覆盖父类的方法 - ……

本章主要讲继承、抽象类和接口,这篇博客讲的是继承这一部分。使用实验的代码做例子来说明。

类的继承

类的继承是面向对象的程序设计的一个重要特点,通过继承实现代码的复用,被继承的类称为父类或超类(superclass),由继承得到的类称为子类(subclass)

子类继承父类成员变量方法,同时可以修改父类的成员变量或重写父类的方法,还可以添加新的成员变量和方法。 Ps:C语言通过函数实现代码复用,但是函数一经写好,它的功能就已经确定,你修改这个函数会影响到所有已经使用这个函数的代码。了解这点,你就能理解继承这种代码复用机制的优点——可以修改,并且不会影响之前使用该功能的旧代码。

使用继承来组织、设计系统中的类,可以提高程序的抽象程度,使之更能接近人类的思维方式,同时继承也能较好的实现代码复用,提升程序开发效率,降低维护工作量。

Java中有一个名为java.lang.Object的特殊类,所有的类都是直接或间接继承得到的。如果没有指明子类所继承的父类,则默认继承这个特殊的类。

子类的创建

子类的创建方法

Java通过关键字extends实现继承,格式如下:

//Java继承示例
class SubClass extends SuperClass
{
...
}

C#实现继承的方式则没有使用任何关键字,而是通过英文分号实现的。

//C#继承示例
public class SubClass : SuperClass
{
}

实验8-1

class PersonB {
    String name;
    int age;

    PersonB() {
        name = "Steve Wang";
        age  = 20;
    }
    PersonB(String name, int age) {
        this.name = name;
        this.age = age;
    }
    void show() {
        System.out.println(name+ " " +age);
    }
}

class StudentB extends PersonB {
    StudentB() {
        name = "Zark Berg";
        age = 23;
    }
    StudentB(String name, int age){
        this.name = name;
        this.age = age;
    }
    void show(){
        System.out.println(name+ " " +age);
    }
}

class Inherite {
    public static void main(String[] args) {
        PersonB a = new PersonB("apple",18);
        StudentB b = new StudentB("pear",16);

        a.show();
        b.show();
    }
}

说明: 1. 通过extends关键字,可将父类的成员继承给子类,在使用这些继承过来的成员时,可利用过去的语法即可。 2. Java程序在执行子类的构造方法之前,会先调用父类中没有参数的构造方法,其目的是为了帮助父类继承自父类的成员做初始化操作。

调用父类中特定的构造方法

即使程序中没有指明子类调用父类的构造方法,运行时也会默认代用父类中没有参数的构造方法。如果父类中有多个构造方法,则使用super关键字来调用特定的构造方法。this这里指代的是父类构造方法名称。

例: super(String a, int b)将调用父类中有2个参数,并且第一个是字符串类型,第二个是整型的构造方法。

你需要阅读原书p123页到p123页的内容来具体了解super及super和this的关系。

在子类中访问父类的成员 也是使用super关键字,格式如下

super.变量名
super.方法名

需要说明的是,父类中的成员必须不是private,才能被子类访问,建议使用protected,使用public会降低封装性。

覆盖

覆盖(Overriding)的概念与重载类似,都是Java“多态”的实现方法。覆盖是指在子类中,定义名称、参数个数和类型均与父类完全相同的方法,用来重写父类中同名方法的操作。C#的覆盖是通过虚方法实现的,具体参见之前的博文《C#多态》。

覆盖父类的方法

实验8-2

class Animal {
    String name;
    Animal() {
        name = "Animal";
    }
    void play() {
        System.out.println(name);
    }
}

class Bird extends Animal {
    String name;
    Bird() {
        name = "Bird";
    }
    void play() {
        System.out.println(name);
    }
}

class Fish extends Animal {
    Fish() {
        name = "Fish";
    }
    void play() {
        System.out.println(name);
    }
}

class Override {
    public static void main(String[] args) {
        Animal a = new Animal();
        Bird b = new Bird();
        Fish c = new Fish();

        a.play();
        b.play();
        c.play();

        Animal a1 = new Bird();
        Animal a2 = new Fish();

        a1.play();
        a2.play();
    }
}

用父类的对象访问子类的成员

Java中可以用父类的对象访问子类的成员,这体现了“父亲的行为像儿子,而不是儿子的行为像父亲”这种面向对象编的程思想。 注意: 父类的对象访问子类的成员仅限于“覆盖”发生时,如果子类没有覆盖父类的方法,则不能父类对象不能访问子类成员。

不可被继承的成员或最终类

默认情况下所有的成员变量和方法都可以被覆盖,如果不希望被覆盖,则需加final关键字做声明。

例:static final double PI = 3.1415926 例:public final void show()

final修饰成员变量,则说明该成员变量是最终量,即常量,程序的其他部分可以访问但不能修改。

final修饰成员方法,则该方法为最终方法,不能被子类所覆盖。

知乎:Solo | 微博@从流域到海域