JAVA 类方法和类变量

类方法和类变量

类变量static

  • 类变量又名静态变量,是该类的所有对象共享的变量。任何一个该类的对象去访问它时,取到的都是相同的值;同样任何一个该类的对象去修改它时,修改的也是同一个变量。
public static int count = 0;
访问修饰符 static 数据类型 变量名
  • 最大特点是会被child所有的对象实例共享。

  • 必须遵守相关的访问权限。(public private protected)

  • 类变量可以用类名访问:Child.count(Child类中的静态变量count)

  • 不管static存储在哪里,共识:

    1. static所有同一个类的对象共享的
    2. 在什么时候生成的?在类加载的时候就已经生成了。
  • 如何访问类变量?

    • 类名.类变量名(推荐)。不用创建对象也能访问,因为类变量是随着类的加载而创建的。

    • 对象名.类变量名

  • 什么时候需要使用类变量?

    • 某个类的所有对象都共享一个变量时(定义学生类,调剂所有学生共交多少钱)

    • 与实例变量(普通属性)的区别:类变量是该类所有对象共享的,实例变量是每个对象共享的

  • 类变量的生命周期是随着类加载而开始,随着类消亡而消失。

类方法static

  • 也叫静态方法
访问修饰符 static 数据返回类型 方法名(){}
  • 如何调用类方法?

    • 类名.类方法名(推荐)

    • 对象名.类方法名

  • 当方法使用static修饰后,就是个静态方法,就能访问静态变量。

  • 不用创建实例也可以调用某种方法时使用:Math.sqrt(),可以写自己的工具包

  • 类方法中无this的参数,普通方法隐含this参数

  • 类方法中不许使用和对象有关的关键字(调用直接使用变量名就行),比如this和super,普通方法可以

  • 类方法只能访问静态变量或者静态方法;普通方法既可以访问非静态成员也能访问静态成员

main方法的语法

public static void main(String[] args) {}
  1. 谁在调用main方法?Java虚拟机在调用

  2. Java虚拟机需要调用main方法,所以访问权限是public

  3. Java虚拟机执行main方法时不必创建对象(有static),所以必须为static

  4. 该方法接受String类型的数组参数,该数组中保存执行java命令时传递给所运行的类的参数

  5. 静态方法main不能访问本类的非静态成员,也不能调用本类的非静态方法,如果要使用,需要创建实例使用

代码块

又称为初始化块,属于类中成员,类似于方法,将逻辑语句封装在方法体中,通过{}包围起来。
但和方法不同,没有方法名,没有返回,没有参数,只有方法体,而且不用通过对象或类显式调用,而是加载类时,或创建对象时隐式调用。

[修饰符]{
	代码
};

注意:

  1. 修饰符可选
  2. 使用static叫做静态代码块,无static为非静态代码块
  3. 逻辑语句中可以为任意逻辑语句
  4. ;可省略

好处:

  1. 相当于另一种形式的构造器(对构造器的补充机制),可做初始化操作
  2. 如果多个构造器中有重复语句,可以抽取到代码块中,提高代码的复用性(当不管调用哪个构造器创建对象都需要调用代码块的内容)
  3. 代码块的调用优先于构造器

注意事项:

  1. static代码块叫做静态代码块,作用是对类进行初始化,随着类的加载而执行,且只执行一次;普通代码块每创建一个对象就执行一次(看作是构造器的一个补充,只有构造器被调用了才会调用普通代码块)
  2. 类什么时候被加载?
    1. 创建对象实例时(new)
    2. 创建子类对象实例时,父类也会被加载;而且父类先被加载再加载子类
    3. 使用类的静态成员时(静态属性、静态方法)
    4. 只是使用类的静态成员时,普通代码块不会被执行
  3. 代码块的调用顺序:
    1. 静态:多个静态代码块和静态变量初始化优先级相同,则若存在多个则按照定义的顺序调用
    2. 普通:多个普通代码块和普通变量初始化优先级相同,则若存在多个则按照定义的顺序调用
    3. 调用构造方法
  4. 构造器的最前面其实隐含了super() (继承父类时自动调用父类的无参构造器)。,静态代码块是优于构造器和普通代码块执行的。涉及父类时,首先调用父类的普通代码块,再父类的构造器,再本类的代码块,再本类的构造器。调用普通代码块
  5. 创建一个子类时,静态代码块、静态变量初始化、普通代码块、普通变量初始化调用顺序:
    1. 父类的静态代码块、静态变量
    2. 子类的静态代码块、静态变量
    3. 父类普通代码块、普通变量
    4. 父类构造器
    5. 子类普通代码块、普通变量
    6. 子类构造器

原因如下:创建对象时:

  1. 先进行类的加载
    1. 先加载父类,再加载子类
    2. 所以先执行父类的静态代码块、静态变量,再执行子类的静态代码块、静态变量
  2. 再创建对象
    1. 先走子类的构造器,隐含了一个super(父类的无参构造器)和普通代码块,所以先走父类,先执行父类普通代码块、普通变量,再执行父类构造器
    2. 父类执行完成后走子类普通代码块、普通变量,最后执行子类构造器

final

  • 修饰类、属性、方法、局部变量
  • 可能使用到final:
    • 不希望类被继承时
    • 不希望父类的某个方法被子类覆盖/重写(override),可以用final修饰
    • 不希望类的某个属性值被修改,可以用final修饰
    • 不希望某个局部变量被修改,可以用final修饰

注意事项:

  1. final修饰的属性又叫常量,一般大写命名

  2. final修饰的属性在定义时,必须赋初值,并且以后不能在修改。可在如下位置赋值:

    1. 定义时
    2. 构造器中
    3. 代码块中
  3. final修饰的属性是静态时,初始化位置只能为:

    1. 定义时
    2. 静态代码块中

    不能在构造器中赋值!

  4. final类不能继承,但可以实例化对象

  5. 类不是final类但含有final方法,则该方法不能重写,但是能被继承

  6. 类已经是final了就没必要把方法设置为final了,因为类不能被继承了,怎么能重写呢?

  7. final不能修饰构造器

  8. final往往和static往往搭配使用,因为使用时不会导致类的加载,可以直接使用这个值(即不会调用静态代码块,静态代码块是在类加载时使用)

  9. 包装类、 string也是final类

抽象类

父类不知道方法具体如何实现时,就考虑讲方法设计为抽象方法。抽象方法就是没有实现的方法(即没有方法体)。当一个类中存在抽象方法时,需要将该类声明为abstract类。一般来说,抽象类会被继承,由子类来重写该方法。

  • 抽象类不能被实例化
  • 抽象类不一定包含抽象方法,还可以由实现的方法
  • 一旦类中存在抽象方法时,必须将该类声明为abstract类
  • 只能修饰类和方法,不能修饰属性
  • 抽象类本质还是类,所以可以拥有类的任意成员
  • 抽象方法不能有主体,即不能实现
  • 如果一个类继承了抽线类,必须实现抽象类的所有方法,除非他自己也声明为抽象类
  • 抽象类不能使用private、final、static修饰,因为这些关键词都是和重写相关的

接口

给出一些没有实现的方法封装在一起,到某个类需要使用的时候根据具体情况写出来。

alt+enter可以快捷实现所有方法

interface 接口名{

}
class 类名 implements 接口{
必须实现的接口从抽象方法
}

接口中,抽象方法可以省略abstract

注意事项:

  1. 接口不能实例化
  2. 所有方法都是public
  3. 一个普通类实现接口就必须实现接口里面所有方法
  4. 抽象类实现接口,可以不用实现接口的方法
  5. 一个类可以实现多个接口
  6. 接口中的属性只能是final,并且是public static final(默认)。
  7. 接口的属性访问形式:接口名。属性名
  8. 接口不能继承其他类,但是可以继承多个别的接口
  9. 接口的修饰符只能是public和默认,和类的修饰符是相同的
接口vs继承类

子类继承了父类就自动拥有了父类的功能

子类需要扩展功能可以通过实现接口的方式扩展

实现接口是对java单继承机制的补充

接口的多态

computer的work方法的参数是接口,那么可以通过接口名.方法来调用方法。在类中new了computer对象调用work时,computer.work()里面的参数可以是实现了接口的任意对象,这就体现了接口的多态。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V0t8fGP1-1679030711972)(C:\Users\wsco24\AppData\Roaming\Typora\typora-user-images\image-20230228222959673.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gvOxQEUq-1679030711973)(C:\Users\wsco24\AppData\Roaming\Typora\typora-user-images\image-20230228223045791.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SmLRpEpJ-1679030711973)(C:\Users\wsco24\AppData\Roaming\Typora\typora-user-images\image-20230228223301570.png)]

继承的多态

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LYy1AdQR-1679030711974)(C:\Users\wsco24\AppData\Roaming\Typora\typora-user-images\image-20230228223343962.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-arnrCmoh-1679030711974)(C:\Users\wsco24\AppData\Roaming\Typora\typora-user-images\image-20230228223351028.png)]

多态数组

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W8tZP01M-1679030711974)(C:\Users\wsco24\AppData\Roaming\Typora\typora-user-images\image-20230228223914407.png)]

内部类

一个类的内部又完整的嵌套了另一个类的结构 ,被嵌套的类被称为内部类。是类的五大成员(属性、方法、构造器、代码块、内部类)

最大特点:可以直接访问私有属性

分类:

  • 定义在外部类局部位置上的:(比如在方法中)

    • 局部内部类

    • 匿名内部类

  • 定义子啊外部类的成员位置上:

    • 成员内部类(没用static修饰)
    • 静态内部类(使用static修饰)
局部内部类

定义在外部类局部位置上的:(比如在方法中)。本质上仍然是一个类

  1. 可以访问外部类的所有成员,包括私有属性私有方法
  2. 不能添加访问修饰符,因为其地位就是局部变量,但是能用final修饰
  3. 作用域:在定义他的方法或者代码块中(相当于局部变量)
  4. 可以直接访问外部类的成员
  5. 外部类在方法中可以创建内部类的对象,然后调用方法即可。
  6. 外部其他类不能访问局部内部类
  7. 外部类和局部类成员重名时,遵循就近原则。如果想访问外部类成员,可以使用外部类名.this.成员(不是静态的,不能外部类名.成员),外部类名.this本质是外部类的对象
匿名内部类

定义在外部类局部位置上的:(比如在方法中)。并且没有类名!同时还是一个对象。

new 类或接口(参数列表){
	类体
}

需求是类只使用一次,传统方法是写一个类然后实现接口并创建对象,较为繁琐。可以使用匿名内部类来简化开发。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1OwczAp3-1679030711974)(C:\Users\wsco24\AppData\Roaming\Typora\typora-user-images\image-20230301110647601.png)]

tiger编译类型IA,运行类型为该匿名内部类。

底层中其实是:class XXX implements IA{

public void cry(){}

},XXX是系统自动分配一个类名

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9VLnOFAw-1679030711975)(C:\Users\wsco24\AppData\Roaming\Typora\typora-user-images\image-20230301111446611.png)]

  • 调用匿名内部类的方法(两种):

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qBy8O0Sp-1679030711975)(C:\Users\wsco24\AppData\Roaming\Typora\typora-user-images\image-20230301112106753.png)]

编译类型person,运行类型是匿名内部类

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lWjT6B99-1679030711975)(C:\Users\wsco24\AppData\Roaming\Typora\typora-user-images\image-20230301112238848.png)]

匿名内部类本身也是一个对象,可以直接调用

匿名内部类当作实参传递时最简洁有效。

成员内部类

定义位置是在外部类的成员位置上。

可以访问外部类的所有成员,包括私有属性私有方法。

任意添加访问修饰符,因为地位是一个成员。

作用域:在整个外部类中(相当于局部变量)

调用方式:作为一个外部类的成员,所以是外部类.内部类[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4fVauktm-1679030711975)(C:\Users\wsco24\AppData\Roaming\Typora\typora-user-images\image-20230301160642091.png)]

如果内部类成员和外部类成员重名,遵守就近原则;想访问外部类属性,可以使用外部类名.this.属性

静态内部类

定义位置是在外部类的成员位置上。

用static修饰

可以访问外部类的所有成员,包括私有属性私有方法。

任意添加访问修饰符,因为地位是一个成员。

枚举

定义枚举实现:

  1. 构造器私有化,目的防止直接new
  2. 去掉set方法,防止属性被修改
  3. 在season内部创建固定的一组对象。为什么要static,因为希望他可以直接访问(类变量)
public final static Season spring = new Season("spring", "warm");

注意事项:

  1. 不需要set方法,因为枚举对象通常为只读
  2. 对枚举对象使用final+static共同修饰,实现底层优化。
  3. 枚举对象名通常全部大写
  4. 枚举对象根据需要可以拥有多个属性
使用enum实现枚举类
  1. enum替代关键词class
  2. 直接使用SPRING(“spring”, “warm”):常量名(实参列表)
  3. 如果有多个,使用逗号间隔,最后一个带分号
SPRING("spring", "warm"),WINTER("winter","cold")
  1. enum实现枚举,需要讲定义常量对象写在属性前面
  2. 使用enum实现枚举类是不能再继承其他类了,java单继承机制,默认继承Enum类,但是可以实现接口

注意事项:

  1. enum开发枚举类时,默认继承Enum类,enum的枚举类是final类型
  2. 传统的public final static Season spring = new Season(“spring”, “warm”)简化为SPRING(“spring”, “warm”)调用的是两个参数的构造器
  3. 无参构造器创建对象,则可以省略小括号和实参列表
  4. 枚举对象必须放在枚举类的行首
enum常用方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GEjZ01iP-1679030711976)(C:\Users\wsco24\AppData\Roaming\Typora\typora-user-images\image-20230302152305483.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zf6G9RQ4-1679030711976)(C:\Users\wsco24\AppData\Roaming\Typora\typora-user-images\image-20230302152819796.png)]

注解Annotation

元数据,用于修饰解释包、类、方法、属性、构造器、局部变量等数据信息。

  • @Override:限定某个方法是重写父类的方法

  • @Deprecated:用于表示某个程序元素(类、方法)已过时
  • @SuppressWarnings:抑制编译器警告
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值