本文是Java的面向对象篇,学习于廖雪峰的Java教程.

面向对象基础

1.方法

  • private方法和private字段不能外部类访问。
  • private方法和private字段是用来方便自身类使用的,为了保证类的封装性。
  • this 变量指当前实例。
  • 局部变量的优先级高于字段,可变参数也是局部变量。
  • 可变参数的定义:类型... 变量名,相当于数组。

2.构造方法

  • 构造方法名与类名相同,构造方法无返回值,必须用new操作符调用。
  • 未自定义构造方法时,系统会默认创建一个无参数构造方法。
  • 如果已经自定义构造方法,系统将不再默认创建构造方法。
  • 引用类型的字段默认是null,数值类型的字段是默认值,int类型默认值是0,布尔类型默认值是false
  • 字段的最终赋值结果由构造方法中的赋值语句决定。
  • 一个类中可以有多构造方法,只是参数列表不同。

3.重载方法

  • 方法名相同但参数列表不同的方法叫(overload)重载方法,返回类型通常是相同的。
  • 重载方法的目的是实现相似的功能但得出不同的结果。
  • 方法签名: 方法名和参数列表。

4.继承

  • 继承是面向对象编程中的一种强大机制,它明显的功能就是实现代码复用。
  • 可以用extends 关键字来实现继承。
  • 一个类只能继承自一个父类,但一个类可以同时被多个类继承。
  • 未用关键字extends声明继承关系的类,默认 extends Object.
  • protected声明的字段和方法可以被继承树内的子类访问。
  • super表示父类(超类)
  • 在任何类的构造方法中,第一行必须是父类的构造方法。
  • 如无明显地调用父类的构造方法,编译器会生成默认无参数的调用父类的构造方法。
  • 如果明显地调用了父类的构造方法,编译器将不再生成默认构造方法。

4.向上转型&向下转型

  • 向上转型:将一个子类类型转变为父类类型。
  • 向下转些:将一个父类类型转变为子类类型。
  • 向下转型可能会失败,失败时会报ClassCastException错误。
  • instanceof可以判断一个变量的类型是否是指定类型或者指定类型的子类。
  • 继承是is关系,组合是has关系,组合是指某个类有另一个类的实例,但这两个类没有继承关系。

5.覆写方法

  • 方法签名相同的方法,叫覆写方法(override)。

  • 重载方法和覆写方法的区别

比较 重载 覆写
方法名 相同 相同
参数列表 不同 相同
返回类型 一般相同 相同
  • 覆写方法前加上@Override可以让编译器帮助检查是否进行了正确的方法覆写。

6.多态

  • 多态: 某个方法的调用,是由实现调用方法的实例的实际类型决定的。
  • 多态的功能:允许添加更多类型的子类实现相似的功能,在实现代码的高复用性的同时,也不需要修改基于父类的代码。
  • 可以通过super关键字调用父类的方法。

7.final

  • final修饰的类不能被继承。
  • final修饰的方法不能被覆写。
  • final修饰的字段不能被重新赋值,但可在构造方法中初始化。
  • final修饰的局部变量不能被重新赋值。

8.抽象类

  • 抽象方法:只给出了方法的定义,但方法内没有实现如何语句,不能被执行,目的是让子类去实现它。
  • 如果定义了抽象方法,相关类必须声明为抽象类,否则会导致编译失败。
  • 抽象方法和抽象类都用关键字abstract修饰。
  • 抽象类无法被实例化,并且子类必须实现父类定义的抽象方法,所以抽象类相当于定义了”规范”。
  • 面向抽象编程:这种尽量引用高层类型,避免引用实际子类型的方式,称之为面向抽象编程。

9.接口

  • 如果一个抽象类没有字段,并且所有方法都是抽象方法,那么这个类可改写为接口。
  • 接口类用关键字interface声明,并且用关键字implements实现继承。
  • 接口支持多继承,即一个类可以实现多个接口。
  • 接口定义的方法默认是public abstract类型,所以在定义接口方法时可忽略不写。
  • 一个接口可以继承自另一个接口,使用关键字extends实现继承。
  • 在子类中增加default方法实现单独功能,可以不用修改父类方法,实现代码的灵活性。

10.接口vs抽象类

比较 接口 抽象类
继承 多继承 单继承
字段 无实例字段,但可有静态(static final)字段 有实例字段
抽象方法 可定义抽象方法 可定义抽象方法
非抽象方法 不能定义非抽象方法,但可有final方法 可定义非抽象方法

11.静态字段&静态方法

  • 静态字段
    • static关键字修饰的字段为静态字段。
    • 静态字段有共享空间,实例字段有单独的空间,换种话说,静态字段属于类,而实例字段属于实例对象。
    • 普通通过类名.字段的方式访问静态字段。
  • 静态方法
    • static修饰的方法为静态方法。
    • 静态方法内部不能访问实例字段,只能访问静态字段,因为静态方法只属于类而不属于实例。
    • 接口可以有静态字段,并且静态字段必须用final修饰,编译器会自动加上这些修饰符。
    • 普遍通过类名.方法的方式调用静态方法。

12.包

  • 设置包(package)机制是为了解决同名类冲突的问题。
  • 真实完整的类名为包名.类名
  • Java文件和Class文件的存放目录层次与包名结构一致。
  • Java文件放在src目录下,class文件放在bin目录下。
  • 包作用域:未被public,private,protected修饰的字段和方法为包的作用域。
  • 在一个类中使用另一个包中的类
    • 通过写出完整类名。
    • 通过import语句导入其他包中的类。
    • 通过import static 语句导入其他类的静态字段和静态方法。
  • 如果有两个类名称相同,那么只能import其中一个类,另一个写完整类名。
  • 包名命名推荐使用倒置的域名来保证唯一性。

13.classpath&jar

  • classpath
    • classpath是一种环境变量,用来指示jvm搜索.class文件。
    • classpath的设定
      • 在系统环境变量中设置
      • 在启动JVM时设置。
        • java -cp /<环境变量> /<文件>
      • rt.jar是Java核心库的压缩包。
  • jar包
    • jar包是一种zip格式的压缩文件。
    • /META-INF/MANIFEST.MF是jar包中特殊的文件,可以指定main-class及其它信息。

14.模块

  • 模块是为了管理依赖,模块以.jmod作为扩展名。

  • java.base是”根模块”,所有模块直接或间接依赖java.base模块。

  • module-info.java是模块的描述文件。

    module hello.world {
    	requires java.base; // 可不写,任何模块都会自动引入java.base
    	requires java.xml;
    }
  • 以上,其中module是关键字,hello.world是模块的名称,requires表示引用其他模块。