包(package)的作用

Java包机制可以将处理同一问题的类存放在同一个目录下,以便于管理。

包可以提供以下的3个作用:

  1. 区分相同名称的类。
  2. 能够较好地管理大量的类。
  3. 控制访问范围。

JDK中主要的包

Java中的常用包 说明
java.lang 包含一些Java语言的核心类,如String、Math、Integer、System和Thread,提供常用功能,Java会默认导入java.lang包下所有的类
java.awt 包含了构成抽象窗口工具集(abstract window toolkits)的多个类,这些类被用来构建和管理应用程序的图形用户界面(GUI)。
java.net 包含执行与网络相关的操作的类。
java.io 包含能提供多种输入/输出功能的类。
java.util 包含一些实用工具类,如定义系统特性、使用与日期日历相关的函数。

包的命名规范

Java包的命名规范可以参考如下:

  1. indi:个体项目,指个人发起,但非自己独自完成的项目,可公开或私有项目,copyright主要属于发起者。包名为“indi.发起者名.项目名.模块名.……”。
  2. pers:个人项目,指个人发起,独自完成,可分享的项目,copyright主要属于个人。包名为“pers.个人名.项目名.模块名.……”。
  3. priv:私有项目,指个人发起,独自完成,非公开的私人使用的项目,copyright属于个人。包名为“priv.个人名.项目名.模块名.……”。
  4. onem:与“indi”相同,推荐使用“indi”。另外,我为了区分团队项目和前面所说项目的区分,还有了一下扩展:
  5. team:团队项目,指由团队发起,并由该团队开发的项目,copyright属于该团队所有。包名为“team.团队名.项目名.模块名.……”。
  6. com:公司项目,copyright由项目发起的公司所有。包名为“com.公司名.项目名.模块名.……”。
  7. 另外:我们还可以使用域名倒着写,比如我的域名是hhcy.vip,则我的包名可以为"vip.hhcy.项目名.模块名.……”。

注意事项:

  1. 写项目的时候我们都应该加上包,不要使用默认包。
  2. vip.hhcy和vip.hhcy.test,这两个包没有包含关系,是两个独立的包。虽然在文件夹里看vip.hhcy为src\vip\hhcy;vip.hhcy.test为src\vip\hhcy\test,虽然这个文件夹的目录在src\vip\hhcy下,但是两个包没有任何关联。

导入类(import)

  • 非静态导入

Java会默认导入java.lang包下所有的类,因此这些类我们可以直接使用。

如果我们需要导入别的包的类,可以使用以下两种方法:

  1. 使用import 包名.类名,例如导入java.util包下的Date类可以使用import java.util.Date
  2. 使用import 包名.*,这个方***导入该包下面的所有的类,例如import java.util.*,这样我们就把util的包下所有的类都导入了进来,但是大部分编程规范是不推荐使用这种方式的,这样可能会引起类的冲突,所以我们一般使用第一种方法。

对于引起类的冲突可以用一下的例子来理解:

import java.sql.Date;
import java.util.*;  //导入该包下所有的类。会降低编译速度,但不会降低运行速度。

public class ImportTest {
    public static void main(String[] args) {
        //如果上面我们import的是java.sql.*,编译器就识别不出是哪个包的Date类,就会报错
        Date date01;  //这里指的是java.sql.Date
        //如果我们要用java.util包下的Data类,我们需要完整的路径
        java.util.Date data02=new java.util.Date();
        System.out.println(data02);
    }
}
  • 静态导入

静态导入同样有两种方法:

  1. 使用import static 包名.类名.静态属性,导入指定的静态属性。
  2. 使用import static 包名.类名.*,导入指定类下的所有静态属性。

我们将静态属性导入后我们就可以直接使用,例如:

import static java.lang.Math.PI;
import static java.lang.Math.*;

public class ImportStaticTest {
    public static void main(String[] args) {
        System.out.println(PI);  //导入了PI可以直接输出常量PI
        //导入了Math类下的所有静态属性
        System.out.println(E); //E常量
        System.out.println(random());  //随机数的静态方法
    }
}

方法

方法的使用

面向对象中,整个程序的基本单位是类,方法是从属于类和对象的。

方法声明格式:

[修饰符1 修饰符2 …] 返回值类型 方法名(形式参数列表){
    Java语句;… … …
}

方法的调用方式:对象名.方法名(实参列表)

方法的详细说明:

  1. 修饰符:修饰符有权限修饰符(private,protected,public),以及关键字例如static
  2. 返回值类型:事先约定的返回值的数据类型,如无返回值,必须显示指定为为void。
  3. 返回值:方法在执行完毕后返还给调用它的环境的数据。
  4. Java语句:Java中的控制语句(控制语句可以参考21天学会Java之(Java SE第二篇):流程控制语句、Java中常用的转义字符、递归结构的流程控制语句部分)。
  5. 方法名:我们自己定义的方法名,命名规范可以参考21天学会Java之(Java SE第一篇):标识符、常量、变量、数据类型以及运算符的标识符部分。
  6. 形式参数:在方法声明时用于接收外界传入的数据。
  7. 实参:实参的数目、数据类型和次序必须和所调用的方法声明的形式参数列表匹配。

注意事项:

  1. return语句终止方法的运行并指定要返回的数据。

  2. Java中进行方法调用中传递参数时,遵循值传递的原则(传递的都是数据的副本):

    • 基本类型传递的是该数据值的copy值。

    • 引用类型传递的是该对象引用的copy值,但指向的是同一个对象。

方法的重载(Overload)以及方法的重写(Override)

  • 方法的重载(Overload)

构成方法重载的条件:参数不同,即:形参类型、形参个数、形参顺序至少有一个不同

以下几种条件不构成方法重载:

  1. 只有返回值不同不构成方法的重载
  2. 只有形参的名称不同,不构成方法的重载

重载的方法,实际是完全不同的方法,只是名称相同而已。

  • 方法的重写(Override)

子类通过重写父类的方法,可以用自身的行为替换父类的行为,方法的重写是实现多态的必要条件。

方法的重写需要符合下面的五个条件:

  1. 方法名、参数、返回值相同。
  2. 子类方法不能缩小父类方法的访问权限。
  3. 子类方法不能抛出比父类方法更多的异常(但子类方法可以不抛出异常)。
  4. 存在于父类和子类之间。
  5. 方法被定义为final不能被重写。

对象(Object)和类(class)

首先,我们需要明白一点Java是一种典型的面向对象语言。

面向过程和面向对象

  • 面向过程(Procedure Oriented)和面向对象(Object Oriented,OO)

    1. 都是解决问题的思维方式,都是代码组织的方式。
    2. 解决简单问题可以使用面向过程
    3. 解决复杂问题:宏观上使用面向对象把握,微观处理上仍然是面向过程。
  • 面向对象思考方式

    面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了;

    面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。

    软件分析、设计和开发各个阶段对应面向对象就分别称为面向对象分析(OOA)、面向对象设计(OOD)和面向对象编程(OOP)。

  • 面向过程与面向对象的优缺点

    面向过程
    优点:性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源,比如单片机、嵌入式开发、Linux/Unix等一般采用面向过程开发,性能是最重要的因素。
    缺点:没有面向对象易维护、易复用、易扩展

    面向对象
    优点:易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统更加灵活、更加易于维护
    缺点:性能比面向过程低

  • 注意事项

    1. 面向对象具有三大特征:封装性、继承性和多态性,而面向过程没有继承性和多态性,并且面向过程的封装只是封装功能,而面向对象可以封装数据和功能。所以面向对象优势更明显。
    2. 一个经典的比喻:面向对象是盖浇饭、面向过程是蛋炒饭。盖浇饭的好处就是“菜”“饭”分离,从而提高了制作盖浇饭的灵活性。饭不满意就换饭,菜不满意换菜。用软件工程的专业术语就是“可维护性”比较好,“饭” 和“菜”的耦合度比较低。

对象的本质

  1. 对象说白了也是一种数据结构(对数据的管理模式),将数据和数据的行为放到了一起。
  2. 在内存上,对象就是一个内存块,存放了相关的数据集合。
  3. 对象的本质就一种数据的组织方式。

对象和类的概念

  1. 对象是具体的事物;类是对对象的抽象;
  2. 类可以看成一类对象的模板,对象可以看成该类的一个具体实例。
  3. 类是用于描述同一类型的对象的一个抽象概念,类中定义了这一类对象所应具有的共同的属性、方法。
  4. 某个类的对象、某个类的实例与某个类的实例化是一样的意思。

类的定义

  1. 每一个源文件可以同时定义多个class但是必须有且只有一个public class,并且public class的类名和文件名保持一致。
  2. 对于一个类来说,一般有三种常见的成员:属性field、方法method、构造器constructor。这三种成员都可以定义零个或多个(如果没有定义构造器,则编译器会自动定义一个无参的构造函数)。

属性(成员变量)

(1)属性用于定义该类或该类对象包含的数据或者说静态特征,属性作用范围是整个类体。

(2)在定义成员变量时可以对其初始化,如果不对其初始化,Java使用默认的值对其初始化。

成员变量的默认值可以参考21天学会Java之(Java SE第一篇):标识符、常量、变量、数据类型以及运算符的数据类型部分。

构造器(构造方法)

构造器的定义

  1. 构造器是一个创建对象时被自动调用的特殊方法,目的是对象的初始化。
  2. 构造器的名称应与类的名称一致,Java通过new关键字来调用构造器,从而返回该类的实例,是一种特殊的方法。

构造器的重载

  1. 构造器即构造方法,其实质上也是一种方法,只不过赋予了它特殊的作用,与普通方法一样都可以重载如何重载可以参考上文,这样我们就可以写多个构造器。

  2. 如果方法构造中形参名与属性名相同时,需要使用this关键字区分成员变量与形参,例如:this.name=name,this.name表示成员变量,name表示形参。

构造器的注意事项

  1. 通过new关键字调用。
  2. 构造器虽然有返回值,但是不能定义返回值类型(返回值的类型肯定是本类),不能在构造器里使用return返回某个值。
  3. 如果我们没有定义构造器,则编译器会自动定义一个无参的构造函数。如果已定义则编译器不会自动添加(一般我们再自己定义完构造器后都要再定义一个无参的构造器)。
  4. 构造器的方法名必须和类名一致。