韩顺平java基础-10-面向对象编程
类变量和类方法
类变量
static
- 静态变量被同一个类所有对象共享
- 类变量在类加载的时候生成
定义语法
访问修饰符 static 数据类型 变量名
如何访问类变量
类名.类变量名 //类变量随着类加载而创建,所以即使没有创建对象实例也可以访问。
使用细节
- 什么时候需要用类变量
需要某个类的所有对象共享一个变量,都可以考虑使用类变量
- 类变量与实例变量的区别
类变量是该类所有对象共享,实例变量是每个对象独享
类方法
类方法就是静态方法
语法
访问修饰符 static 数据返回类型 方法名(){}
类方法使用场景
当方法中不涉及到任何和对象相关的成员时,可以将方法设计成静态方法,提高开发效率。
希望不创建实例,也可以调用某个方法(当作工具使用)
注意事项
类方法可以通过类名直接调用,非静态方法需要创建对象再调用。
类方法不能使用this和super等关键字。
类方法只能访问静态成员(方法和变量),不能访问实例方法。
普通成员方法既可以访问静态成员也可以访问非静态成员
理解main方法语法
public static void main(String[] args)
- main 方法是java虚拟机调用
- Java虚拟机需要调用类的main方法,所以访问权限必须是public
- java虚拟机在执行main方法时不创建对象,所以该方法必须时static
注意
静态方法main,可以访问本类的静态成员,但是不可以访问本类的非静态成员
代码块
代码化块又称为初始化块,属于类中的成员[即 是类的一部分],类似于方法,将逻辑语句封装在方法体中,通过{}包围起来。
但和方法不同,没有方法名,没有返回,没有参数,只有方法体,而且不用通过对象或类显式调用,而是加载类时或创建对象时隐式调用。
基本语法
[修饰符]{代码};
说明
修饰符 只能是 static
使用static修饰的叫静态代码块,没有static修饰的叫普通代码块
代码块调用优先于构造器
理解
相当于另一种形式的构造器
应用场景
如果多个构造器中都有重复的语句,可以抽取到初始化块中,提高代码的重用性
细节
- static代码块,作用就是对类进行初始化,随着类加载而执行,并且只会执行一次。如果是普通代码块,每创建一个对象,就会执行。
类什么时候被加载?
1创建对象实例时(new) 2 创建子类对象实例时,父类同时被加载,同时父类先加载
3 使用类的静态成员时,类被加载
- 创建一个对象时,在一个类中的调用顺序是:
1调用静态代码块和静态属性初始化 优先级:优先级相同,按照定义顺序执行
2调用普通代码块和普通属性初始化 优先级:优先级相同,按照定义顺序执行
3调用构造器
- 构造器 默认执行
super
和调用普通代码块 - 创建一个子类对象(含继承关系)时,在一个类中的调用顺序是:
1父类的静态代码块和静态属性初始化
2子类的静态代码块和静态属性初始化
3父类的普通代码块和普通属性初始化
4父类构造器
5子类的普通代码块和普通属性初始化
6子类构造器
- 静态代码块只能直接调用静态成员,普通代码块可以调用任意成员
单例设计模式
静态方法和静态属性的应用
应用实例
饿汉式(如果没有使用对象,也会随着类的加载自动创建)懒汉式(没有使用对象时,不会创建对象,在调用接口时才创建)
步骤
- 构造器私有化 private
- 在类的内部创建静态对象
- 提供公共static方法接口,返回对象
小结
饿汉式:在类加载时就创建对象,可能存在资源浪费问题
懒汉式:线程存在安全问题
final关键字
使用场景
- 不希望类被继承,可以用final修饰
- 不希望父类中的方法被重写,可以用final修饰
- 不希望类的某个属性的值被修改,可以用final修饰
- 不希望某个局部变量被修改,可以用final修饰
细节
- final修饰的变量称为常量,必须赋初值。
- 赋值位置:1.定义时 2.构造器中 3.代码块中
- 如果final修饰的是静态属性,则赋值位置:1.定义时 2.静态代码块 不能在构造器中赋值
- final类不能继承,但是可以实例化
- 非final类,final方法不能被重写,但是可以被继承
- final类的方法不必使用final再次修饰方法(画蛇添足)
- final和static结合使用,不会导致类加载,效率更高
- 包装类 String Double Int是final类 不能被继承
抽象类
定义
父类方法不确定时,用abstract修饰方法,抽象方法没有方法体。
细节
- 抽象类不能被实例化(new)
- 抽象类不一定要包含abstract方法
- 一旦类中包含抽象方法,则必须声明为抽象类
- abstract只能修饰类和方法
- 如果一个类继承了抽象类,则它必须实现抽象类中的所有抽象方法,除非子类也声明为抽象类。
- 抽象方法不能使用private,final,static来修饰,因为与重写相违背。
模板设计模式(抽象类使用)
动态绑定机制
接口
封装一些没有实现的方法,根据具体情况实现方法
interface 接口名{//属性 //方法}
class 类名 implements 接口{自己属性 自己方法}
细节
- 普通类实现接口,必须实现接口的所有抽象方法。抽象类实现接口,可以不用实现接口方法。
- 接口中,默认是抽象方法,不用abstract关键字
- jdk8后,可以有默认实现方法,但是需要使用default关键字修饰;可以有静态方法。
- 接口不能实例化,本身是抽象概念
- 类可以同时实现多个接口 接口也可以继承其他的接口
- 接口中的属性 只能是public static final属性
接口 vs 继承类
实现接口是对java单继承机制的补充
继承:
子类可以直接使用父类中已存在的方法
接口:
扩展子类的功能
接口多态
多态参数
多态数组:向下转型
多态传递
内部类
类的五大成员
属性、方法、构造器、代码块、内部类
局部内部类
- 局部内部类定义在外部类的局部位置(通常在方法中),相当于局部变量
- 可以直接访问外部类的所有成员,包括私有的
- 不能添加访问修饰符,但是可以使用final修饰
- 作用域:仅仅作用于定义它的方法或代码块中
- 局部内部类使用外部类:可以直接访问外部类的所有成员
- 外部类使用局部内部类:在方法中创建对象使用
- 外部类和局部内部类成员重名时,遵循就近原则优先访问内部类成员。如果想要访问外部类成员,使用 外部类名.this.成员 访问
匿名内部类
- 当作实参直接传递
成员内部类
- 可以直接访问外部类的所有成员,包括私有的
- 成员内部类,定义在外部类的成员位置
- 可以用修饰符(本质是成员,可以加)
- 成员内部类使用外部类:可以直接访问外部类的所有成员
- 外部类使用成员内部类:在方法中创建对象使用
- 外部其他类使用成员内部类:1.创建成员内部类的对象 2.在外部类中创建方法返回对象实例
- 外部类和成员内部类成员重名时,遵循就近原则优先访问内部类成员。如果想要访问外部类成员,使用 外部类名.this.成员 访问
静态内部类
- 定义在外部类的成员位置,static修饰
- 可以直接访问外部类的静态成员,不能访问非静态成员
- 可以用修饰符(本质是成员,可以加)
小结
- 内部类共四种:局部内部类、匿名内部类、成员内部类、静态内部类
- 重点掌握匿名内部类:
new 类/接口(参数列表){};
- 成员内部类、静态内部类 放在外部类的成员位置,本质是一个成员