javajavase

属性

又称为成员变量,属性的声明是在类中方法外
声明

  1. 修饰符 数据类型 属性名 = 初始值; //显式初始化
  2. 修饰符 数据类型 属性名; //声明类时没有显式给属性赋初值,那么在创建对象后,属性有默认的初始值

修饰符

  • 权限修饰符:private、缺省、protected、public
  • 其他修饰符:static、final

封装

  • 属性使用private修饰,只能在本类中直接使用,在其他类中不可见
  • 提供公共的getXxx()/setXxx()
    • set方法:用于为属性赋值,修改属性值
    • get方法:用于获取、访问某个属性的值

属性赋值顺序

  1. 默认初始化
  2. 显式初始化/代码块赋值
  3. 构造器中初始化
  4. 通过**对象.属性****对象.方法**的方式赋值

与局部变量的区别

  • 声明位置、修饰符、内存位置、是否默认初始化

方法

基本概念

  • 方法是类或对象行为特征的抽象,用来完成某个功能操作

    1. 修饰符 返回值类型 方法名(形参列表) 抛出的异常列 {
    2. 方法的实现
    3. }

    意义

  • 使程序变得简短而清晰

  • 有利于程序的维护
  • 提高程序开发的效率
  • 提高代码的重用性

注意:Java里的方法不能独立存在,所有的方法必须定义在类里
分类

  • 按参数

    • 无参

      1. 修饰符 返回值类型 方法名() {
      2. 方法体
      3. }
    • 有参

      1. 修饰符 返回值类型 方法名(形参列表) {
      2. 方法体
      3. }
  • 按返回值

    • void类型修饰的方法——单独调用
    • 有明确返回值的方法
      1. 单独调用,没有意义
      2. 输出调用,不是很好,可能需要对结果进一步操作
      3. 赋值调用,推荐
      • 在本类中
        • 变量名 = 方法名(实参列表);
        • 作为另一个方法调用的实参
        • 作为表达式的一部分
  • 按static
    • 本类中**方法名(实参列表);**
    • 在其他类中
      • 方法是static修饰的

**类名.方法名(实参列表);**
**变量名 = 类名.方法名(实参列表);**

  1. - 方法是非static修饰的

**对象名.方法名(实参列表);**
**变量名 = 对象名.方法名(实参列表);**
命令行参数

  • public static void main(String[] args)
    • 通过命令行传的参数,在args数组中
    • 如果要使用命令行的参数 args[0]…
  • 怎么传
    • cmd: java 包.类 参数1 参数2 参数3…
    • eclipse: run菜单—>run configration—>选择运行哪个main方法—>program argument
    • IDEA: Edit Configurations

返回值

  • 基本类型
  • 类: 返回的是该类的一个对象
  • 抽象类: 返回的是该抽象类的子类对象。用多态的方法
  • 接口: 返回的是该接口的实现类对象。用多态的方法
  • 链式编程
    • **对象.方法1().方法2().方法3();**
    • 方法1()调用完毕后,返回一个对象;
    • 方法2()调用完毕后,返回一个对象;
    • 方法3()调用完毕后,可以是对象,也可以不是

注意事项

  • 方法不调用不执行
  • 方法之间是平级关系,不能嵌套定义
  • 实参的数目、数据类型和次序必须和所调用的方法声明的形式参数列表匹配
  • return 语句终止方法的运行并指定要返回的数据,如果方法有明确的返回值类型,就必须有return语句返回一个值

    重载

    在同一个类中,方法名相同,参数列表不同,与返回值无关

  • 参数的个数不同或参数的对应的数据类型不同

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

作用:允许功能相似的方法重名,使方法定义和调用都简化了
调用:正常方法调用即可,传进对应的参数,编译器自动选择你指定类型参数的方法执行

可变参数

声明
**数据类型... 形参名**

  • 一个方法最多只能有一个可变参数
  • 声明必须在方法的形参列表的最后一个
  • 可变参数的数据类型可以是任意类型
  • 数据类型[] 形参名与可变参数不能构成重载

使用

  • 在声明它的方法中,可变参数当做数组使用——形参名就是数组名
  • 可变参数的方法调用时

    • 可变参数的对应的位置,可以传0~n个实参
    • 可变参数的对应的位置,可以传1个数组对象,当然这个数组对象的元素数据类型必须与可变参数的数据类型是一致

      🔴值传递机制

      形参:方法声明时的参数
      实参:方法调用时实际传给形参的参数值
      遵循值传递的原则(传递的都是数据的副本)
  • 基本类型做参数:将实参基本数据类型变量的“数据值”传递给形参,形参的改变不影响实参

  • 引用类型做参数:将实参引用数据类型变量的“地址值”传递给形参,形参的改变影响实参

实参将值传给形参的过程,称为参数传递,实际上就是一个赋值的过程

递归

一个方法体内调用它自身
方法递归包含了一种隐式的循环,它会重复执行某段代码,但这种重复执行无须循环控制
递归一定要向已知方向递归,否则这种递归就变成了无穷递归,类似于死循环
递归结构包括两个部分

  • 递归头:递归的结束条件,如果没有头,将陷入死循环
  • 递归体

递归的缺陷

  • 递归调用会占用大量的系统堆栈,内存耗用多,在递归调用层次多时速度要比循环慢的多,所以在使用递归时要慎重
  • 任何能用递归解决的问题也能使用迭代解决。当递归方法可以更加自然地反映问题,并且易于理解和调试,不强调效率问题时,可以采用递归

构造器

是一个创建对象时被自动调用的特殊方法,给对象的数据进行初始化

  1. //无参构造
  2. 修饰符 类名() {
  3. 方法体
  4. }
  5. //有参构造
  6. 修饰符 类名(形参列表) {
  7. 方法体
  8. }

特点

  • 构造器方法名必须与类名相同
  • 构造器没有返回值类型
  • 构造器可以重载
  • 任何类中都有构造器,如果没有显式定义构造器,编译器将自动添加一个默认的无参构造器
  • 如果显式/手动声明了任何一个构造器,编译器将不再自动添加默认的无参构造
  • 不能被static、final、synchronized、abstract、native修饰,不能有return语句
  • 父类的构造器不可被子类继承

作用

  • 和new一起使用,创建对象
    • **new 构造方法();**

调用无参构造,Random rand = new Random();

  • **new 构造方法(实参列表);**

调用有参构造,Scanner input = new Scanner(System.in);
为属性赋值
对象创建的过程

  • 构造方法是创建Java对象的重要途径,通过new关键字调用构造器时,构造器也确实返回该类的对象,但这个对象并不是完全由构造器负责创建
  • 创建一个对象分为如下四步:
    1. 分配对象空间,并将对象成员变量默认初始化
    2. 显式初始化、多个初始化块依次被执行
    3. 执行构造方法体
    4. 返回对象的地址给相关的变量

JavaBean

  • 类是公共的
  • 有一个无参的公共的构造器
  • 有属性,且有对应的get、set方法

代码块

用来初始化类、对象
静态代码块

  1. static {
  2. }
  • 内部可以有输出语句
  • 随着类的加载而执行,而且只执行一次
  • 作用:初始化类的信息
  • 如果一个类中定义了多个静态代码块,则按照声明的先后顺序执行
  • 静态代码块的执行要优先于非静态代码块的执行
  • 静态代码块内只能调用静态的属性、静态的方法,不能调用非静态结构

非静态代码块

  1. {
  2. }
  3. 在类中,称为构造块
  4. 在方法中,称为普通代码块
  • 内部可以有输出语句
  • 构造块随着对象的创建而执行
  • 每创建一个对象,就执行一次构造块
  • 作用:可以在创建对象时,对对象的属性等进行初始化
  • 如果一个类中定义了多个非静态代码块,则按照声明的先后顺序执行
  • 非静态代码块内可以调用静态的属性、方法,或非静态的属性、方法
  • 当多个构造器中重复的代码,可以提取到构造块中

执行特点

  • 由父及子,静态先行
  • 静态代码块(只执行一次)——构造块(每次创建对象)——构造器(每次创建对象)

示例

  1. class Father {
  2. static {
  3. System.out.println("1");
  4. }
  5. {
  6. System.out.println("2");
  7. }
  8. public Father() {
  9. System.out.println("3");
  10. }
  11. }
  12. public class Son extends Father {
  13. static {
  14. System.out.println("4");
  15. }
  16. {
  17. System.out.println("5");
  18. }
  19. public Son() {
  20. System.out.println("6");
  21. }
  22. public static void main(String[] args) { // 由父及子 静态先行
  23. System.out.println("0");
  24. System.out.println("************************");
  25. new Son();
  26. System.out.println("************************");
  27. new Son();
  28. System.out.println("************************");
  29. new Father();
  30. }
  31. }

内部类

定义

  • 把类定义在其他类的内部,这个类就被称为内部类
  • 成员内部类编译会生成Outer.class和Outer$Inner.class
  • 局部内部类会生成Outer.class和Outer$1Inner.class,同名内部类数字1会递增

内部类的访问规则

  • 内部类可以直接访问外部类的成员包括私有
  • 外部类要访问内部类的成员,必须创造对象
  • 内部类和外部类没有继承关系。内部类如果想要访问外部的变量,需要创建对象,或巧用this关键字(假装这里有一个指向上边的箭头)通过外部类名限定this对象**outer.this**

内部类的作用

  • 当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,那么整个内部的完整结构最好使用内部类
  • 实现多继承
  • 可以解决实现接口方法重名的问题

    成员内部类

    在成员位置定义的类被称为成员内部类,和成员方法、成员变量平级

    1. 修饰符 class 外部类 {
    2. 修饰符 class 内部类 {
    3. }
    4. }

    特点

  • 一方面,作为外部类的成员:

    • 调用外部类的结构
    • 可以被static修饰
    • 可以被4种不同的权限修饰
  • 另一方面,作为一个类:

    • 类内可以定义属性、方法、构造器等
    • 可以被final修饰,表示此类不能被继承。不使用final就可以被继承
    • 可以被abstract修饰

      非静态内部类

  • 在外部类的外面使用内部类

    1. Outer.Inner inner = new Outer().new Inner();
    2. Outer out = new Outer();
    3. Outer.Inner inner = out.new Inner();
  • 在外部类中使用内部类

    • 在外部类的静态成员中,不能直接使用内部类
    • 在外部类的非静态成员部分,把内部类当做普通类使用
  • 在内部类中使用外部类的成员 没有限制

    静态内部类

  • 在外部类的外面

    1. Outer.Inner inner = new Outer.Inner();
  • 在外部类中使用没有限制

  • 在内部类中使用外部类的成员

    • 在静态内部类中,不能使用外部类的非静态成员
    • 其他的成员可以直接使用,包括私有的

      局部内部类

      在局部位置定义的类被称为局部内部类,和局部变量平级

      1. 修饰符 class 外部类 {
      2. 修饰符 返回值类型 方法名(形参列表) {
      3. class 内部类名 {
      4. }
      5. }
      6. }

      注意

  • 只能在声明它的方法、代码块、构造器中使用,而且是先声明后使用。除此之外的任何地方都不能使用该类

  • 局部内部类可以使用外部类的成员,包括私有的
  • 局部内部类可以使用外部方法的局部变量但是必须是final的,由局部内部类和局部变量的声明周期不同所致
  • 不能使用public protected private static这些成员修饰符
  • 局部内部类中,不能包含静态成员的

    匿名内部类

    1. new 父类构造器(实参列表|实现接口) {
    2. 匿名内部类的类体部分
    3. }
  • 特点

    • 匿名内部类必须继承父类或实现接口
    • 匿名内部类只能有一个对象
    • 匿名内部类对象只能使用多态形式引用
    • 匿名内部类没有访问修饰符、构造器、类名
    • 只有一个对象,声明匿名内部类与创建对象,同时进行

范例

  1. public class InnerClassTest {
  2. //返回一个实现了Comparable接口的类的对象
  3. public Comparable getComparable(){
  4. //创建一个实现了Comparable接口的类:局部内部类
  5. //方式一:
  6. class MyComparable implements Comparable {
  7. @Override
  8. public int compareTo(Object o) {
  9. return 0;
  10. }
  11. }
  12. return new MyComparable();
  13. //方式二:
  14. return new Comparable() {
  15. @Override
  16. public int compareTo(Object o) {
  17. return 0;
  18. }
  19. };
  20. }
  21. }

UML类图类图.webp

  • 表示public类型, - 表示private类型,# 表示protected类型
    方法的写法:方法的类型(+、-) 方法名(参数名: 参数类型):返回值类型