大数据JAVA基础第十三天 2.抽象类作为返回值 返回值类型:抽象类:返回的是该抽象类的实现子类对象 3.package:包 4.包的定义及注意事项 6.不同包下类之间的访问 7.容易出现的问题: 8.类及其成员可以用的修饰符 10.内部类概述 12.外界如何创建内部类对象 13.成员内部类 局部内部类 匿名内部类对象 匿名内部类的应用

1.类名作为返回值

返回值类型

       基本类型:

       引用类型:

           类:返回的是该类的实例对象

返回值类型:抽象类:返回的是该抽象类的实现子类对象

3.package:包

引入包的原因:

为了避免同名类太多而产生的混乱,在类前加上额外的限定

 

其实就是一种目录结构,在类的外边加上一些路径,使用的时候,需要指定路径才能找到相应的类,之前写的类没有加任何包,所以,可以直接使用

 

作用:对类进行分类管理

包的定义:通常是公司域名倒写,在后面加上项目名等,例如

com.it18zhang.packtest;

4.包的定义及注意事项

定义包的格式

  • package 包名;
  • 包名只要是有效的标识符即可,通常的做法是使用小写字母。多级包用.分开即可,一个圆点代表一个文件夹,内容通常是公司域名的倒序,后面还可以再继续用项目名进行区分

注意事项

  • package语句必须是程序的第一条可执行的代码,前面有注释语句没有影响,注释语句不是可执行语句
  • package语句在一个java文件中只能有一个
  • 如果没有package,则表示无包名
  • 5.总结:带包类的编译和运行
  • 如果在源文件中指定了类的包,则对带包类的编译和运行有两种方法:

  • 手动式

    • a:javac编译当前类文件。不用-d指定生成的目录位置
    • b:手动建立包对应的文件夹。
    • c:把a步骤的class文件放到b步骤的最终文件夹下。
    • d:通过java命令执行。注意:需要带包名称执行

        java com.test.pack.HelloWorld

    自动式

    • a:javac编译的时候带上-d指定生成的完整类路径对应的文件夹(即包名中最顶层所在的目录,-d . 表明在当前目录生成完整类名对应的文件夹结构)

       javac -d . HelloWorld.java

    • b:通过java命令执行。和手动式一样,需要使用完整类名

        java com.test.pack.HelloWorld

        由于生成的完整包名的最顶层在当前目录下,所以可以直接访问,如果在其他路径下的话,需要使用-cp参数来指定类路径,也就是包全名对应的路径的父目录

        java -cp e: est11 com.test.pack.HelloWorld

     

    总结:

        一旦定义了包,则类在使用的时候就用包名.类名的方式,也叫完整类名

        完整类名就是带着包的类名(包名+类名)

    6.不同包下类之间的访问

    使用到import关键字,将需要使用的类导入到文件中

    回想前面使用过的Scanner类

     

    如果不用导包的话,每次使用不同包下的类的时候,都需要加上包的全路径。比较麻烦。

    比如:

    com.it18zhang.Demo d = new com.it18zhang.Demo();

    使用import导入包之后,就可以省去类前面的包名,直接使用类名了

     

    导包格式

    import 包名.类名;

     

    7.容易出现的问题:

    第一个问题:找不到Demo

     

    原因:

        在导入的包中没有这样的类定义,有可能是类名写错

    第二个问题:被导入的程序包com.test不存在

     

    原因:

        在编译的时候没有指定生成的完整类的父目录位置,导致了生成的.class文件就放在当前文件夹下,并没有生成和类名对应的文件夹结构,导致找不到包。解决的办法是在编译时,每个带包的类都需要用-d 指明生成的位置

     

    第三个问题: Demo在com.test中不是公共的; 无法从外部程序包中对其进行访问

     

    原因:在导入的包中,类没有定义为public类,导致在外包无法访问。将被导入的包中的类定义为public的即可。

     

    如果定义的类不是public的,说明它的访问权限是默认,默认的访问权限是包访问权限,即:只有两个类在同一个包中时,才能通过导入来使用,如果在不同的包中的话,即使导入了这个包,也不能使用,因为不是public的。

     

    所以,以后建议每个类都单独定义在一个文件中,并且定义成public的。

    8.类及其成员可以用的修饰符

    类:

    • 四种权限中可以使用两种(默认的,public),final,abstract
    • 我们自己定义:public居多

    成员变量

    • 四种权限修饰符均可,final,static
    • 我们自己定义:private居多

    构造方法:

    • 四种权限修饰符均可,其他(final,static)不可
    • 我们自己定义:public 居多

    成员方法:

    • 四种权限修饰符均可,fianl,static,abstract
    • 我们自己定义:public居多

     

    9.修饰符使用规则总结:

        修饰符分类:

           权限修饰符:private,默认的,protected,public

           状态修饰符:static,final

           抽象修饰符:abstract

        类:

           权限修饰符:默认修饰符,public

           状态修饰符:final

           抽象修饰符:abstract

           用的最多的就是:public

        成员变量:

           权限修饰符:private,默认的,protected,public

           状态修饰符:static,final

           用的最多的就是:private

        构造方法:

           权限修饰符:private,默认的,protected,public

           用的最多的就是:public

        成员方法:

           权限修饰符:private,默认的,protected,public

           状态修饰符:static,final

           抽象修饰符:abstract

           用的最多的就是:public

        除此以外的组合规则:

           成员变量:public static final

           成员方法:public static

                     public abstract

                    public final

    10.内部类概述

    把类定义在其他类的内部,这个在其他类里面的类就被称为内部类。

    比如:在类A中定义了一个类B,类B就是内部类。

     

    内部类的访问特点:

    • 内部类可以直接访问外部类的成员,包括私有
    • 外部类要访问内部类的成员,必须创建对象(即使用new 类名)    
    • 11.内部类位置
    • 按照内部类在类中定义的位置不同,可以分为如下两种格式

      • 成员位置(成员内部类)
      • 局部位置(局部内部类)

      (和变量非常类似,变量分为成员变量和局部变量)

      12.外界如何创建内部类对象

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

      Outer.Inner oi = new Outer().new Inner();

      成员内部类:

             外界如何直接访问内部类的成员。

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

      13.成员内部类

      刚才我们讲解过了,成员内部类的使用,但是一般来说,在实际开发中是不会这样使用的。因为一般内部类就是不让外界直接访问的。成员内部类设计的目的是让外部类使用的。

       

      举例讲解这个问题:

      • 电脑和CPU,CPU就相当于一个内部类,它被电脑的其他部分使用,作为电脑的使用者来说,并不能单独使用CPU,只能通过操作系统来操作
      • 汽车和发动机,司机不能单独操作发动机,只能通过汽车上的钥匙,油门,离合器等装置来操作发动机

       

      成员内部类的常见修饰符

      • private 私有成员内部类

      为了保证数据的安全性,只能通过外部类的其他可访问方法间接访问私有的成员内部类

      • static 静态成员内部类

      为了让数据访问更方便,直接通过外部类名.内部类名来访问

      静态成员内部类

      被静态修饰的成员内部类只能访问外部类的静态成员

      • 只能使用外部类的静态成员

      int num = 10;

      static int num2 = 20;

      public static class Heart {

          // int a = num;   //外部类的非静态成员不能访问

             int b = num2;     //OK,只能访问外部类的静态成员

          }

       

      内部类被静态修饰后的方法

      静态内部类可以有静态和非静态方法,但都只能访问外部类的静态成员

       

      静态内部类中只能访问外部类的静态成员,不能访问非静态成员(编译报错)

       

       

      从外界访问静态内部类的方式

          Outer.Inner ii = new Outer.Inner();

          ii.func1();

      不能用:

          Outer.Inner oi = new Outter().new Inner();

      非静态成员内部类

      非静态内部类只能定义非静态方法,非静态变量,可以访问外部类的静态和非静态成员

      私有成员内部类

      外界想要直接访问私有成员内部类,只能在外部类中定义公共方法对私有内部类进行访问

      否则外界不能直接访问私有的成员内部类

      局部内部类

      可以直接访问外部类的成员

      可以创建内部类对象,通过对象调用内部类方法,来使用局部内部类功能

      匿名内部类对象

      就是内部类的简化写法

      前提:存在一个类或者接口

      这里的类可以是具体类也可以是抽象类

       

      • 成员内部类只不过是在类成员的位置上定义了一个类,不管是静态也好,非静态也好,都必须实例化之后才能使用,也就是说,最终我们要使用的,还是一个类的对象
      • 那么这个对象能不能是一个类的子类,或者是抽象类,接口的实现类呢?
      • 完全可以,只要把这个子类(实现类)的对象放在类成员的位置,它就是一个内部类的对象,只不过,在这个子类(实现类)实例化的时候,我们完全可以使用匿名的方式进行,这样这个实例化的对象就是一个匿名的内部类对象

       

       

      格式:

        new 类名或者接口名() {重写(实现)方法;}

      本质:

        是一个继承了类或者实现了接口的子类匿名对象

      匿名内部类的应用

      当形参是一个接口时,在调用方法时可以直接将一个实现类对象传入

    • 匿名内部类对象