Java2实用教程(第五版)第五章笔记

第五章 子类与继承

5.1 子类与父类

所有类的祖先类都是Object

extends关键字来定义一个类的子类,如:

class A {
    ...
}
class B extends A {
    ...
}

5.2 子类的继承性

  • 同一包当中的继承性:继承父类当中不是private的方法和变量

  • 不同包的继承性:只能继承protected类和public类,不继承友好类和private类

5.3 子类和对象

5.3.1 子类对象的特点

子类在继承时,也同样为private的方法和变量分配了空间,虽然分配了内存空间但是其并非子类对象的变量,或者说,获取了相应的值和函数,但是并没有直接访问和调用他们的权力。当然,子类可以通过其他的方法来操作这些没有访问权限的变量,例如

class A {
    private int x;
    public int getX() {
        return x;
    }
}
class B extends A {
    ...
}

显然B的对象没有权利直接访问x的值

B b = new B();
int i = b.x // 非法
int j = b.getX() // 合法,因为getX方法类型为public,能够被B类继承

5.3.2 关于instanceod运算符

instanceod运算符是Java独有的双目运算符

该左面的操作元是对象,右面的操作元是类,当左边的操作元是右侧的类或者其子类创建的对象时,instanceod运算符的结果为true, 否则是false,参考5.3.1的代码:

boolean x;
x = b boolean A; // true

5.4 成员变量的方法与重写

5.4.1 成员变量的隐藏

  • 对于子类从父类继承的成员变量,只要子类声明的成员变量和父类继承的成员变量同名,则子类就会将继承的成员变量隐藏
  • 子类中操作这个同名变量时,子类中的方法操作的是子类的变量,继承自父类的方法操作的是隐藏的父类的变量
class A {
    int x  = 10;
    int getX() {
        return x;
    }
}
class B extends A {
    int x; // 子类又声明了一个x,父类的x被隐藏
    setX(int i) {
        x = i;
    }
}

现在进行这些操作

B b = new B();
b.setX(100); // 此时对象b中B新建立的x值是100
int a = b.getX(); // a的值还是10

5.4.2 方法重写

  • 重写的语法规则:如果子类可以继承父类的某一个方法,那么就有权利重写它。重写的方法与父类的方法一致,且名字、参数个数、参数类型与父类完全相同
class A {
    int x = 10, sum;
    int getSum(int a) {
        sum = x + a;
        return sum;
    }
}
class B extends A {
    int sum;
    int  getSum(int a) { // 重写了方法int getSum(int a)
        sum = x + x + a;
        return sum;
    }
}
  • 重写的目的:隐藏继承的方法
  • 特别注意:重载和重写的区别,在习题中经常出现需要分辨重载和重写的情况
  • 重写父类方法时,不允许降低方法的访问权限,访问权限由高到低为:public > protected > 友好 > private
class A {
    protected int getSum(int a, int b) {
        return a + b;
    }
}
class B extends A {
    int getSum(int a, int b) { // 非法,降低了访问权限
        return (a + b)*2;
    }
}
class C extends A {
    public int getSum(int a, int b) { // 合法
        return a + a + b;
    }
}

5.5 Super关键字

5.5.1 用super操作被隐藏的成员变量和方法

使用super关键字可以访问和调用被子类隐藏的成员变量和方法

super关键字实例如下:

class A {
    int n = 100;
}
class B extends A {
    int n = 10;
    int g() {
        return n;
    }
    int f() {
        return super.n;
    }
}

主程序中执行:

int i, j;
B b = new B();
i = b.g() // i = 10
j = b.f() // b = 100

5.5.2 使用super调用父类构造方法

  • 需要复习“构造方法”部分内容

5.6 final关键字

final关键字可以修饰类,成员变量和方法当中的局部变量

  • final类:final类不能被继承,即不能有子类
  • final方法:如果父类当中存在final方法,那么这个方法不允许子类重写
  • 常量:用final声明的变量不允许任何修改,所以在声明常量时必须给出ta的值,如:
final double PI = 3.14;

5.7 对象的上转型对象

class A {
    private int a = 100;
    static void f() {
        System.out.println("Well done!");
    }
    void outPut() {
        System.out.println(a);
    }
    void print() {
        System.out.println("Hello Word!");
    }
}
class B extends A {
    static void f() {
        System.out.println("Go for it!");
    }
    void print() {
        System.out.println("This is a Java program");
    }
    void compute(int a, int b) {
        System.out.println("两数相加的结果是:"+ a + b);
    }
}

显然A是B的父类

下面用子类B创建一个对象

A a; // 将对象的引用放到父类当中
a = new B(); //用子类创建了一个对象

或者写作

Animal a;
Tiger b = new Tiger();
a = b;

此时称 a 是对象 b 的上转型对象

上转型对象会失去子类对象的一些特点

1.上转型对象不能操作子类新增的变量和方法

a.compute(10, 20); // 非法,a作为上转型对象不能操作子类新增的compute方法

2.上转型对象能访问子类继承和隐藏的变量、方法

a.outPut(); // 合法,a作为上转型对像可以调用子类继承的方法

3.上转型对象能操作子类继承或者重写的方法,但是如果子类重写了父类的静态方法,那么它只能调用父类的静态方法而不能调用子类重写的静态方法

a.print(); // 合法,输出This is a Java program"

4.如果子类重写父类的静态方法,那么子类的上转型对象不能调用子类重写的静态方法,只能调用父类的静态方法

a.f(); // 合法,输出"Well done",因为上转型对象只能调用父类的静态方法

5.8 继承与多态

一个类的各个子类如果都重写了父类中的同一个方法,而且这些子类创建的对象都定义为子类的上转型对象,那么各个子类就会产生各自的功能行为,我们称次现象为“多态”

5.9 abstract类和abstract方法

抽象方法和抽象类用abstract关键字修饰

  • 对于abstract方法,只允许声明,不允许实现(没有方法体),不允许final和abstract同时修饰同一个方法或类,也不允许static修饰abstract方法

  • 对于abstract类

    1. abstract类当中可以有abstract方法,也可以有非abstract方法
    abstract Class A {
        abstract void a(); // abstract方法
        void b(); // 非abstract方法
        }
    
    1. abstract类不能使用new创建该类的对象实体;如果某个非抽象类是抽象类的子类,那么如果它继承的方法中有抽象方法,则必须将其重写,这样才能创建该子类的实体
    // 代码接1
    class B extends A {
        void a() { // 必须重写abstract方法
            ...
        }
    }
    

你可能感兴趣的:(Java学习)