黑马程序员——java基础--抽象类、接口、多态、内部类、异常、包

时间:2022-06-20 00:48:07
------ Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------


1、抽象类(abstract)

   特点:

1)抽象方法一定在抽象类中;

2)抽象方法和抽象类都必须被abstract关键字修饰;

3)抽象类不可以用new创建对象,调用抽象方法没有意义;

4)抽象类中的抽象方法要被使用,必须由子类复写所有的抽象方法后,建立子类对象调用;如果子类只覆盖了部分抽象方法,那么该子类还是一个抽象类。

2、接口(interface)

   格式:interface{ }

1)接口中成员修饰符是固定的:

成员常量:public  static  final

成员函数:public  abstract

2)接口的出现将“多继承”通过另外一种形式体现了出来,即“多实现”。

3)当抽象类中的方法都是抽象的,那么该类可以通过接口的形式表示。

4)接口是不可以创建对象的,因为有抽象方法;需要被子类实现,子类对接口中的抽象方法全部覆盖后,子类才可以实例化,否则子类是一个抽象类。

5)一个类可以同时实现多个接口。

3、多态

  1)多态的体现

       父类的引用指向了自己子类的对象,父类的引用也可以接收自己的子类对象。

      如: Animal  a = new  Cat();   

  2)多态的前提

      类与类之间必须有关系,要么继承,要么实现。通常还有一个前提:存在覆盖,父类中有方法被子类重写。

  3)多态的利处与弊端

        利处:提高了程序的可扩展性和后期可以维护性。

        弊端:只能使用父类的引用访问父类中的成员。父类型的引用在使用时,不能直接调用子类中的特有方法。子类对象可以向父类类型提升,可以强制将父类的引用转成子类类型,即向下转型;但千万不要将父类对象转成子类类型。多态自始至终都是子类对象在做着变化。

    如:Animal  a  =  new  Cat(); 类型提升了,向上转型。

      Cat  c  =  (Cat)  a;强制将父类的引用转成子类类型,向下转型。如果父类创建了对象Animala = new Animal(),则就不能将父类对象转成子类类型。 

  4)多态的特点

    A、成员函数在多态调用时,编译看左边,运行看右边。

B、多态中成员变量是无论编译和运行,都参考左边。

4、内部类

   将一个类定义在另一个类的里面,对里面那个类就称为内部类(内置类,嵌套类)。

 1)内部类的访问特点:

A、内部类可以直接访问外部类中的成员(包括私有),因为内部类中持有了一个外部类的引用( 外部类名.this)。

B、外部类要访问内部类,必须建立内部类对象。
  2)格式:

    外部类名.内部类名  变量名 =外部类对象.内部类对象;

    如: Outer.Inner  in  = new  Outer().newInner();

  3)当内部类在外部类中的成员位置上时,可以被成员修饰符所修饰。比如:

  private:将内部类在外部类中进行封装。 

  static:内部类就具有static的特性。

    内部类被static修饰后,只能直接访问外部类中的static成员。出现了访问局限。

    外部类如何直接访问static内部类的非静态成员呢?

         格式:new  外部类名.内部类名( ).方法名( );

     如:new  Outer.Inner().function();

    注意:

   A、当内部类中定义了静态成员时,则该内部类必须是static的;

   B、当外部类中的静态方法访问内部类时,内部类也必须是static的。

   C、在实际应用中,内部类通常被定义为private,而很少定义为public。

  4)内部类定义在局部

        1)不可以被成员修饰符修饰。如public、private、static等修饰符修饰。它的作用域被限定在了这个局部类的代码块中。

        2)可以直接访问外部类中的成员,因为还持有外部类中的引用。不可以访问它所在的局部中的变量,只能访问被final修饰的局部变量。

  5)匿名内部类

        A、匿名内部类其实就是内部类的简写格式;

B、内部类必须是继承一个类或者实现接口,用Object定义例外;

C、匿名内部类的格式: new 父类或者接口(){定义子类的内容};

D、其实匿名内部类就是一个匿名子类对象,可以理解为带内容的对象;

E、匿名内部类中定义的方法最好不要超过3个,不然如果继承的父类或接口中有很多方法时,使用匿名内部类阅读性会非常差,而且调用会很麻烦。

5、异常

    异常就是程序在运行时出现不正常情况。

  1)由来:问题也是现实生活中一个具体的事物,也可以通过java的类的形式进行描述并封装成对象,java对不正常情况进行描述后的对象体现。

  2)有两种对问题的划分方式: 严重的和非严重的。

        对于严重的问题,java通过Error类进行描述,一般不编写针对性的代码对其进行处理。

        对于非严重的,java通过Exception类进行描述,可以使用针对性的处理方式进行处理。

  3)异常体系的特点:

异常体系中的所有类以及建立的对象都具备可抛性,也就是说可以被throw和throws关键字所操作,只有异常体系具备这个特点。

  4)异常分两种:编译时异常和运行时异常。

  编译时异常如果编译时没有处理,则编译失败,若异常被标识,代表可以被处理;运行时异常,若发生了建议不处理,直接让程序停止,需要对代码修改。

 

 5)异常的处理:     

  try

  {

    需要被检测的代码。

   }

  catch(异常类 变量)

   {

    处理方式;

   }

   finally

   {

    一定会执行的语句;

   }

另外还有两个格式:try{}和catch(){},try{}和finally{}。

注意:finally中定义的通常是关闭资源代码,因为资源必须释放;或者在一个功能中定义了一些必须要执行的代码,可以功过try{}finally{}的方式实现。Finally只有一种情况不会执行,那就是执行到System.exit(0)。

 

6)throw和throws的用法:

  throw定义在函数内,用于抛出异常对象;

 throws定义在函数上,用于抛出异常类,可以抛出多个用逗号隔开。

  当函数内容有throw抛出异常对象(RuntimeException除外),并未进行try处理,则必须要在函数上声明,否则编译失败。

 

7)对捕获到的异常对象常见方法操作:

   String  getMessage() 获取异常的信息,返回字符串。

   toString() 获取异常类名和异常信息,返回字符串。

   printStackTrace()  获取异常类名和异常信息,以及程序中的位置。

 

8)自定义异常

   将项目中出现的特有的并且java中没有进行描述封装的问题,可以进行自定义异常封装,定义类继承Exception或者RuntimeException。

   如何定义异常信息呢?

   因为父类中已经把异常信息的操作都完成了,所以子类只要在构造时,将异常信息传递给父类,通过super()语句就可以直接通过getMessage方法获取自定义异常信息。

   继承Exception的原因:

   因为异常体系有一个特点:异常类和异常对象都被抛出。他们具备可抛性,这个是Throwable体系中独有的特点。只有这个体系中的类和对象才可以被throw和throws操作。

 

 9)异常在子父类覆盖中的体现

  子类在覆盖父类时,如果父类的方法抛出异常,那么子类覆盖方法,只能抛出父类的异常或者该异常的子类,或者不抛;

  如果父类方法抛出多个异常,那么子类在覆盖该方法时,只能抛出父类异常的子集;

  如果父类或者接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常。如果子类方法发生了异常,就必须要进行try处理,绝对不能抛。

 

 10)异常的好处和原则

  好处:将问题进行封装,让正常流程代码和问题代码相分离,方便于阅读。

  原则:处理方式有两种:try和throws;调用到抛出异常的功能时,抛出几个则就要处理几个,一个try可以对应多个catch;多个catch时,父类的catch放到最下面,否则编译出错,因为其下面的catch语句执行不到。

 如果捕获到的异常,本功能处理不了,可以继续在catch中抛出;如果问题处理不了,但并不属于该功能出现的异常,或者异常可以处理,当需要将异常产生的和本功能相关的问题提供出去。     

6、包(package)

  1)关键字:import(导入)

    导入是包中的类,要用到包中的哪个类就导入那个类,尽量不写通配符,因为将不需要使用的类导入后,会占用内存空间。

    一个程序可以有多个import,注意不导入包中的包。

    导入的不同包中有相同类时,必须写类的全名以区分,否则将会报错。

2)包(package)

    包是对文件进行分类管理,给类提供多层命名空间,包也是一种封装形式,在包中可以有很多类文件,但只提供一个类文件供使用。

  规则:

  A、包必须写在程序的第一行,因为要先有包,才知道类文件的存放地方。

 B、类的全称:包名.类名。

 C、编译定义了包的程序文件时,在编译时要指定包的存储目录。

3)包之间的访问

  A、要访问其他包中的类,需要定义类的全称:包名.类名;

  B、包如果不在当前路径,需要使用classpath设置环境变量,指定路径;

  C、被访问的包中的类权限必须是共有的,public修饰;

  D、不同包中的子类可以直接访问父类中被protected权限修饰的成员,包与包之间可以使用的权限只有两种:public和protected。

四种访问权限:  

 

public

protected

default

private

同一类中

可以

可以

可以

可以

同一包中

可以

可以

可以

不可以

子类

可以

可以

不可以

不可以

不同包中

可以

不可以

不可以

不可以

  注意:一个java文件不能出现两个以上的共有类或者接口。被public修饰的类名必须与java文件名相同。