第5章 继承、接口和泛型

子类和父类

在继承关系中,有关的类的定义:

  • 父类:定义成抽象类 ,在子类中会产生“多态”的方法定义成抽象方法。
  • 子类:按子类具体情况, 实现父类的抽象方法。
  • 使用extends来体现继承关系

“多态”如何在对象的使用中体现:

  • 创建各子类对象
  • 用父类的引用去使用子类对象

子类的继承性

  • 继承的定义“子类的成员中有一部分是子类自己声明定义的,另一部分是从它的父类继承的。
  • 子类和父类在同一包中的继承性:子类和父类在同一包中,子类自然地继承其父类中不是private的成员变量和方法作为自己的成员变和方法。子类不能继承父类的构造方法。
  • 子类和父类不在同一包中的继承性:子类可以继承父类的protected、public成员变量和方法,不能继承友好变量和友好方法。

成员变量隐藏和方法重写

成员变量的隐藏

在子类中定义的成员变量只要与父类中的成员变量同名(不必类型相同),则子类隐藏了继承的成员变量,即子类重新定义了这个成员变量。

方法重写

  • 子类中定义一个方法,并且这个方法的名字、返回类型、参数个数和类型与从父类继承的方法完全相同,子类就通过方法的重写隐藏了继承的方法。
  • 如果子类直接调用的方法一定是重写的方法,需要使用被隐藏的父类方法需要使用关键字super

关键字super

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

  • 子类不继承父类的构造方法,因此子类想要使用父类的构造方法,必须在子类的构造方法中使用super来表示,而且super必须是子类构造方法中的第一条语句
  • 子类在创建对象时,子类的构造方法总是先调 用父类的某个构造方法,没有明确指明的就调用不带参数的构造方法。super(),super(x,y)

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

super.x=100; super.play();使用关键字super操作的是被子类隐藏的父类成员变量x和方法play()

final类和final方法

  • final类不能被继承,即不能有子类
  • 如果一个方法被修饰为final方法,则这个方法不能被重写,即不允许子类重写隐藏继承的final方法,final方法的行为不允许子类窜改。

对象的上转型对象

假设BA的子类或间接子类,用子类B创建一个对象,并把这个对象的引用放到类A声明的对象中:

A a;

B b=new B();

a=n;//称对象a是子类对象b的上转型对象,它不关心子类新增的功能,只关心子类继承和重写的功能。

  • 上转型对象不能操作子类声明定义的成员变量,不能使用子类声明定义的方法。
  • 上转型对象可以代替子类对象去调用子类重写的实例方法。
  • 上转型对象可以调用子类继承的成员变量和隐藏的成员变量

继承和多态

  • 与继承有关的多态性是指父类的某个实例方法被其子类重写时,可以各自产生自己的功能行为,指同一个操作被不同类型对象调用时可能产生不同的行为。
  • 不同对象的上转型对象调用同一方法可能产生不同的行为。

抽象类

用关键字abstract修饰的类称为抽象类。

  • 抽象类中可以有抽象方法抽象方法只允许声明,不允许实现。
  • 抽象类不能用new运算创建对象:如果一个非抽象类是某个抽象类的子类,那么它必须重写父类的抽象方法,给出方法体
  • 做上转型对象:抽象类声明的对象成为其子类对象的上转型对象,并调用子类重写的方法。

面向对象

  • 抽象细节面向抽象的第一步就是将经常需要变化的部分分割出来,将其作为abstract类的中的abstract方法。
  • 面向抽象设计类:面向抽象编程的第二步就是面向抽象类来设计一个新的Pillar类。Geometry的子类Lader和Cirlce重写了Geometry类的getArea()方法,给出了各自计算面积的算法细节。

接口

Java规定一个类只能有一个父类。但是Java使用了接口,一个类可以实现多个接口。接口分为接口声明和接口体。

1.接口声明

接口通过使用关键字interface来声明,格式:interface 接口的名字

2.接口体

接口体中包含常量定义和方法定义两部分。接口体中只进行方法的声明,不许提供方法的实现,所以方法的定义没有方法体,且用分号“;”结尾 。
 interface Printable{
    final int MAX=100;
    void add();
    float sum(float x ,float y);
 }

3.接口的使用

一个类通过使用关键字implements声明自己实现一个或多个接口。如果实现多个接口,用逗号隔开接口名,如:class A implements Printable,Addable

4.接口的规则

  • 如果一个类实现某个接口,那么这个类必须实现该接口的所有方法,即为这些方法提供方法体。
  • 接口中的方法被默认是publicabstract的,接口在声明方法时可以省略方法前面的publicabstract关键字,但是,类在实现接口方法时,一定要用public来修饰。
  • 类实现的接口方法以及接口中的常量可以被类的对象调用。
  • 如果父类实现了某个接口,则其子类也就自然实现这个接口。
  • 接口也可以被继承,即可以通过关键字extends声明一个接口是另一个接口的子接口。

接口的回调

1.接口回调

可以把使用某一接口的类创建的对象的引用赋给该接口声明的接口变量中,那么该接口变量就可以调用被类实现的接口中的方法,当接口变量调用被类实现的接口中的方法时,就是通知相应的对象调用接口的方法,这一过程称作对象功能的接口回调。接口回调可能产生不同的行为。

2.接口做参数

当一个方法的参数是一个接口类型时,如果一个类实现了该接口,那么就可以把该类的实例的引用传值给该参数,参数可以回调类实现的接口方法。

面向接口

  • 可以通过在接口中声明若干个abstract方法,方法体的内容细节由实现接口的类去完成。
  • 使用接口回调,即接口变量存放实现该接口的类的对象的引用,从而接口变量就可以回调类实现的接口方法。
  • 面向接口也可以体现程序设计的“开-闭”原理Open-Closed Principle),即对扩展开放,对修改关闭。

抽象类和接口的对比

  1. 抽象类和接口都可以有抽象类方法。
  2. 接口中只可以有常量,不能有变量;而抽象类中即可以有常量也可以有变量。
  3. 抽象类中也可以有非抽象类方法,接口不可以。

内部类

  • 内部类:在一个类中声明的另一个类,而包含内部类的类成为外嵌类
  • 内部类同类中声明的方法或成员变量一样,一个类把内部类看作是自己的成员。
  • 内部类可以随意使用外部类的成员变量(包括私有)而不用生成外部类的对象。
  • 内部类的类体中不可以声明类变量和类方法static声明)。外嵌类可以用内部类声明对象,作为外嵌类的成员

使用内部类创建对象

  • 创建内部类对象时,必须先创建外部类对象,再使用外部类对象调用内部类方法创建内部类对象
  • Out out =new Out();Out.In in=out.new In();====Out.In in=new Out().new In()

访问内部类变量

  • 内部类在没有同名成员变量局部变量的情况下,内部类访问外部类的成员变量,可以直接使用“属性名”访问;
  • 如果有同名局部变量情况下,直接使用“属性名”访问的是内部类的局部变量;
  • 访问内部类本身的成员变量可用this.属性名”访问外部类的成员变量用“外部类名.this.属性名”

私有内部类

  • 如果一个内部类只希望被外部类中的方法操作,那么可以使用private声明内部类,此时的内部类只有外部类可控制
  • Out类里面生成In类的对象进行操作new Int.print(),而无法再使用Out.In in = new Out().new In()生成内部类的对象

匿名类

  • 是一个没有名字的内部类
  • 是一个子类(或实现了接口)
  • 声明的同时创建了该匿名类的对象

       匿名内部类                               在接口使用匿名类   

         

异常类

  • 当程序运行出现异常时,Java运行环境就用异常类Exception的相应子类创建一个异常对象,并等待处理Java使用try~catch语句来处理异常;
  • 将可能出现的异常操作放在try~catch语句的try部分,当try部分中的某个语句发生异常后,try部分将立刻结束执行,而转向执行相应的catch部分。

try-catch语句

  try{

       包含可能发生异常的语句
       }
     catch(ExceptionSubClass1  e){}///异常对象e是由Exception的子类
     catch(ExceptionSubClass2  e){
}

各个catch参数中的异常类都是Exception的某个子类,表明try部分可能发生的异常,这些子类之间不能有父子关系,否则保留一个含有父类参数的catch即可。

自定义异常类

  • 一个方法在声明时使用关键字throws声明抛出所要产生的若干异常,并在该方法的方法体中给出产生异常的操作;
  • 即用相应的异常类创建对象,这将导致该方法结束执行并使用throw抛出所创建的异常对象,使用try…catch语句处理。

class A{

  public void f(int n)throws MyException{

    if(n<0){

      MyException ex=new MyExcepetion(n);///创建异常类对象,并抛出异常对象

      throw(ex);

    }}}

try { //执行的代码,其中可能有异常。一旦发现异常,则立即跳到catch执行。否则不会执行catch里面的内容 }

catch {//除非try里面执行代码发生了异常,否则这里的代码不会执行 }

finally { //不管什么情况都会执行,包括try catch 里面用了return ,可以理解为只要执行了try或者catch,就一定会执行 finally}

posted @ 2020-08-14 16:54  Littlejiajia  阅读(153)  评论(0编辑  收藏  举报