类变量和类方法
类变量也叫静态变量/静态属性,是该类的所有对象共享的变量,任何一个本类的对象访问他时,取到的值都是相同的,同样任何本类的一个对象去修改它时修改的也是听一个变量
定义语法:------->访问修饰符 static 数据类型 变量名;[推荐]
static 访问修饰符 数据类型 变量名;
类名.类变量名
or 对象名.类变量名
推荐使用 第一种
package static_;
public class VisitStatic {
public static void main(String[] args) {
//类名.类变量名
System.out.println(A.name);
//说明: 类变量是随着类的加载而创建的,所以即使没有创建对象实例也可以放访问
//通过对象名.类名也可以访问
/* A a = new A();
System.out.println(a.name);*/
}
}
class A {
//类变量
public static String name = "勾八";
//类变量的访问,同样要遵守相关访问权限
}
static变量是对象共享的
1.static变量是同一个类所有对象共享
2.是他提醒类变量,在类加载时就生成了
类属性、类方法的设计思想:
类属性作为该类各个对象之间共享的变量
在设计类时,分析哪些属性不因对象的不同而改变,将这些属性设置为类属性。相应的方法设置为类方法。如果方法与调用者无关,则这样的方法通常被声明为类方法,由于不需要创建对象就可以调用类方法,从而简化了方法的调用。
1.什么时候需要使用类变量
我们需要让某个类所有对象共享一个变量时,就可以考虑使用类变量
2.类变量与实例变量(普通属性)的区别
类变量是共享的 实例变量是每个对象独享的
3.加上static关键字称为类变量或者静态变量 否则称为实例变量/成员变量/非静态属性(变量)/属性
4.类变量可以通过类变量.类变量名 或者 对象名.类变量名 来访问
6.类变量是在类加载时就加载了
7.类变量的生命周期是随着类加载开始的
类方法也叫静态方法
访问修饰符 static 数据返回类型 方法名(){
方法体
}
使用方法:类名.类方法名 或者 对象名,类方法名
package static_;
import java.util.SplittableRandom;
public class StaticMetnod {
public static void main(String[] args) {
//创建两个学生对象
stu tom = new stu("tom");
tom.payFee(100);
stu may = new stu("may");
may.payFee(200);
//输出当前收到的总学费
stu.showFee();
}
}
class stu {
private String name;//普通成员
//定义一个静态变量,来积累学生学费
private static double fee = 0;
public stu(String name) {
this.name = name;
}
//说明
//1.当方法使用了static修饰后,该方法就是静态方法
//2.静态方法就可以访问静态属性
public void payFee(double fee){
stu.fee += fee;//累计
}
public static void showFee() {
System.out.println(stu.fee);
}
}
当方法不涉及 任何和对象相关的成员
1.类方法和普通方法都是随着类加载而加载,将结构信息储存在方法区
2.类方法可以通过类名调用,也可以通过对象名调用
3.普通方法和对象有关,不能通过类名调用,只能通过对象名调用
4.类方法中不能使用和对象有关的关键字,例如this和super
5.类方法只能访问静态属性, 静态方法
6.普通成员方法既可以访问普通{属性,方法}也可以访问静态{属性, 方法}
静态方法只能访问静态属性(方法)
深入理解main方法
mian方法是虚拟机调用的
为什么是public访问权限: 因为Java虚拟机与main方法不在同一个类
在main方法中,我们可以直接调用main方法所在类的静态方法静态属性
package main_;
public class Main01 {
private static String name = "sss";
public static void main(String[] args) {
System.out.println(name);
}
}
静态的方法,要想访问本类的非静态属性或方法,需要先创建对象
基本介绍:代码块又称为初始化块,属于类中的成员(即类的一部分)。类似于方法,将逻辑语句封装在方法体中,通过{}包围起来。
用法不同,没有方法名,没有返回,没有参数。只有方法体,而且不用通过对象或类显式调用,而是加载类时,或创建对象时隐式调用。
基本语法:[修饰符]{
代码
}
注意事项:
1.修饰符可选,要写的话,也只能写static
2.没有修饰符的普通块,使用普通块的初始化代码块;没有static修饰的,叫普通代码块。
3.普通代码可以使用控制语句(输入、输出、方法调用、循环、判断等)。
4.‘;’号可以与‘,’号可以省略。
package codeblock_;
public class CodeBlock01 {
public static void main(String[] args) {
Movie 你好 = new Movie("你好");
}
}
class Movie {
private String name;
private double price;
private String director;
// 三个构造器 ---->进行了重载
// 1.下边的三个构造器都有相同的语句
// 2.代码比较冗余
// 3.这时我们可以把相同语句放在一个代码块中
// 4.当我们调用那个构造器,创建对象,都会先调用代码块内容
// 5.代码块的调用顺序优先于构造器
{
System.out.println("电影屏幕打开....");
System.out.println("广告开始.....");
System.out.println("正片开始......");
}
public Movie(String name) {
this.name = name;
}
public Movie(String name, double price) {
this.name = name;
this.price = price;
}
public Movie(String name, double price, String director) {
this.name = name;
this.price = price;
this.director = director;
}
}
理解:
------------->1.代码块相当于另外一种形式的构造器,可以做初始化操作
2.如果多个构造器中都有重复的语句,可以抽取到初始化模块中提高代码重用性
1.)static代码块也叫静态代码块作用是对类进行初始化,随着类的加载而执行,只会执行一次,而普通代码块,每创建一个对象,就执行一次
2.类什么时候被加载
创建对象实例时 (new)
创建子类对象实例,父类也会被加载
使用类的静态成员时(静态属性、静态方法)
package codeblock_;
import jdk.internal.dynalink.beans.StaticClass;
public class CodeBlockDetail01 {
public static void main(String[] args) {
//类被加载的情况举例
//创建对象实例时(new)
//AA aa = new AA();
//创建子类对象实例时,父类被调用
BB bb = new BB();
//使用类的静态成员时
System.out.println(Cat.n1);
}
}
class Cat{
public static int n1 = 99;
static {
System.out.println("Cat的静态代码块被执行----------");
}
}
class AA {
static {
System.out.println("AA 的静态代码被执行--------");
}
}
class BB extends AA {
static {
System.out.println("BB的静态代码块被执行----------");
}
}
3.普通的代码块,在创建对象实例时,会被隐式调用。被创建一次,就会调用一次。如果只是使用类的静态成员时,普通代码块并不会执行。
创建一个对象时,在一个类调用顺序是:(重点,难点):1)调用静态代码块和静态属性的初始化(注意:静态代码块和静态属性初始化的优先级一样,如果有多个静态代码块和多个静态变量初始化,则按他们定义的顺序调用)
[举例]:
public class CodeBlocakDetail02 {
public static void main(String[] args) {
A a = new A();
}
}
class A {
private static int n1 = 1;
static {
System.out.println("A代码块");
}
public static int getN1() {
System.out.println("getN1");
return 100;
}
}
2)调用普通代码块和普通属性的初始化(注意:普通代码块和普通初始化的优先级一样,如果有多个普通代码块和多个普通属性初始化,则按定义顺序调用)
3)调用构造方法。
4)构造方法的最前面其实隐含了super()和调用普通代码块
静态相关的代码块,属性初始化,在类加载时,就执行完毕,因此是优于构造器和普通代码块
package codeblock_;
public class CodeBlocakDetail03 {
public static void main(String[] args) {
new BBB();
}
}
class AAA {
public AAA() {
//super
//调用本类代码块
System.out.println("aaa() ");
}
}
class BBB extends AAA {
{
System.out.println("BBBB代码块");
}
public BBB(){
//super();
//调用本类的普通代码块
System.out.println("BBB()");
}
}
创建一个子类时(继承关系),他们的静态代码块,静态属性初始化,普通代码块,普通属性初始化,构造方法的调用顺序如下:
1)父类的静态代码块和静态属性初始化(优先级一样,按定义顺序执行)
2)子类的静态代码块和静态属性初始化(优先级一样,按定义顺序执行)
3)父类的普通代码块和普通属性初始化(优先级一样,按定义顺序执行)
4)父类的构造方法
5)子类的普通代码块和普通属性初始化(优先级一样,按定义顺序执行)
6)子类的构造方法 // 面试题
静态代码块只能直接调用静态成员(静态属性和静态方法),普通代码块可以调用任意成员。
静态方法和属性的使用。
设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格,以及解决问题的思考方式。设计模式就像是经典的棋谱,不同的棋局,我们用不同的棋谱,免去我们自己再思考和摸索。
1.所谓的单例设计模式,就是采用一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且只提供一个取得其对象实例的方法
2.单例模式有两种方式: 1)饿汉式 2)懒汉式
演示饿汉式和懒汉式单例模式的实现。
步骤如下:
1.构造器私有化 => 防止直接 new
2.类的内部创建对象
3.向外暴露一个静态的公共方法。 getInstance
4.代码实现