Lecture 3 继承与接口使用

  1. 继承:

    • 继承是类之间的一种抽象层次关系
    • 继承让子类获得父类的属性和方法,实现复用和扩展
    • 继承可以把多个类中的重复内容提取出来形成父类,减少冗余和增强可维护性
  2. 继承在Java中的语法:

    (1)extends关键词:Java通过关键字extends来定义继承关系

    (2)super关键词:子类通过super.attribute引用父类的非私有属性,通过super.methodName()调用父类实现的方法

    (3)父类中public和protected类型的成员可以被子类直接访问,private成员需要通过方法访问

    (4)Java仅支持单继承,即一个类最多只能有一个父类

  3. 方法重写:

    (1)子类重新实现父类已有的方法被称为方法重写(override),重写要求方法名称,参数(个数,顺序,类型)和返回类型均保持一致,这样既保持了类的抽象层次,又实现了子类的独有行为

    (2)方法重写的访问权限:

    • 重写方法的visibility范围必须大于等于父类的方法

    (3)方法重写的返回类型:

    • 若父类方法返回基本类型,则重写方法只能与其保持一致
    • 若父类方法返回AClass,则子类方法只能返回AClass或者其子类
  4. 子类对父类方法的调用:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    class Animal {
    void eat() {
    System.out.println("animal : eat");
    }
    }

    class Dog extends Animal {
    @override
    void eat() {
    System.out.println("dog : eat");
    }
    void eatTest() {
    this.eat(); // this 调用自己的方法
    super.eat(); // super 调用父类方法
    }
    }
  5. final关键字:

    • 使用 final 关键字声明类,就是把类定义定义为最终类,不能被继承
    • 用于修饰方法,则该方法不能被子类重写
  6. 接口:

    • 接口(interface)是一种定义方法和常量的抽象类型,不提供实现方法
    • 利用接口定义程序所需的行为可消除类之间的依赖关系
    • 一个接口可以由多个类实现,一个类可以实现多个接口
  7. 接口在Java中的语法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    public interface MyInterface {
    // 抽象方法声明
    void myMethod1();
    void myMethod2();
    void myMethod3();
    }
    public class MyClass implements MyInterface {
    //利用override实现接口定义中的所有方法
    @Override
    public void myMethod1() {
    System.out.println("Implementation of myMethod1");
    }
    @Override
    public void myMethod2() {
    System.out.println("Implementation of myMethod2");
    }
    @Override
    public void myMethod3() {
    System.out.println("Implementation of myMethod3");
    }
    }

    //继承父类并实现多个接口
    public class MyClass extends fatherClass implements MyInterface1 ,MyInterface2 {

    }
    • 抽象方法的声明不需要public或 private等修饰,规定方法名, 参数及返回类型即可
    • 使用implements 关键字来实现接口,要求实现接口中定义的所有方法
    • @Override表示对抽象方法的重写(即提供具体实现)
  8. 实例化问题:

    • 接口无法被实例化
    • 实现了接口的类可以实例化,且实例化对象可以通过接口来引用和访问
    • 接口也是一种类型,可以用obj instance of A判断对象obj是否实现了接口A,即是否为接口类型A的实例
  9. 接口并不是必须的,那我们自然要问接口有什么意义,或者什么时候实现接口?考虑OOpre_hw3作业中的情形:

    (1)Adventurer,Bottle,Equipment三类均具有战斗力,属于战斗单元类(CombatUnits);其中Bottle和Equipment又是物品,属于物品类(Goods);而Bottle又可具体分为HpBottle AtkBottle DefBottle三种。如果我们仅考虑使用类的继承关系来实现上述关系,这会带来两个问题:

    • CombatUnits类几乎没有业务功能(事实上它的属性只有ID,name,CE),各个子类需要加入大量拓展
    • 建立了比较深的继承层次

    为了规避上述两个问题,考虑使用接口的方案:

    CombatUnits定义为接口,该接口实现以下功能:

    • get ID,name,CE
    • set ID,name,CE

    让Bottle,Equipment,Adventurer都实现该接口,三种具体的Bottle仍继承自Bottle,这样同样建立了行为上的抽象层次,并且消除了类之间的依赖关系

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class Bottle implements CombatUnits {
    // Bottle的属性和方法
    }
    public class Equipment implements CombatUnits {
    // Equipment的属性和方法
    }
    public class Adventurer implements CombatUnits {
    //combatunits统一管理所有价值体
    private ArrayList<CombatUnits> combatunits;
    //Adventurer的其它属性和方法
    }
  10. 接口和继承的区别:

    (1)继承:

    • 一个类只能有一个父类
    • 子类继承了父类的所有属性和方法
    • 建立了数据抽象层次

    (2)接口:

    • 一个类可以实现多个接口
    • 实现接口中所定义的全部方法
    • 建立了行为抽象层次