面向对象/关于静态

本文详细介绍了Java中的static关键字,包括静态变量、静态方法的特性、生命周期和使用场景。同时,讲解了final关键字的作用,如防止继承、防止方法重写和变量篡改。此外,还探讨了单例模式的概念和实现方式,以及main方法的解析。
摘要由CSDN通过智能技术生成

Java学习

1 static静态

总结:有static修饰的属性/方法 与类同时出现

  1. static 用来修饰的结构:属性、方法; 代码块、内部类;
修饰属性
  1. static修饰属性

    变量的分类

    1. 按照数据类型:基本数据类型、引用数据类型

    2. 按照类中声明的位置:

      成员变量:按照是否使用static修饰进行分类:
      使用static修饰的成员变量:静态变量、类变量
      不使用static修饰的成员变量:非静态变量、实例变量

      局部变量:方法内、方法形参、构造器内、构造器形参、代码块内等。

  2. 静态变量与实例变量

① 个数
静态变量:在内存空间中只有一份,被类的多个对象所共享。
实例变量:类的每一个实例(或对象)都保存着一份实例变量。

② 内存位置

​ 静态变量:存放在堆空间
​ 实例变量:存放在堆空间的对象实体中。

在这里插入图片描述

③ 加载时机

​ 静态变量:随着类的加载而加载,由于类只会加载一次,所以静态变量也只有一份。

比如
 private static int init = 1001;  //只会加载一次,不会重新赋值

​ 实例变量:随着对象的创建而加载。每个对象拥有一份实例变量

④ 调用者
静态变量:可以被类直接调用,也可以使用对象调用。

       Account.setInterestRate(0.0123);

​ 实例变量:只能使用对象进行调用。

   Account acct1 = new Account();
        System.out.println(acct1.element);

⑤ 判断是否可以调用 —> 从生命周期的角度解释

类变量实例变量
yesno
对象yesyes

⑥ 消亡时机
静态变量:随着类的卸载而消亡
实例变量:随着对象的消亡而消亡

修饰方法:

(类方法、静态方法)

  1. 可以通过“类.静态方法”的方式,直接调用静态方法
    静态方法内只能调用静态的属性或静态的方法。

补充:在类的非静态方法中,可以调用当前类中的静态结构(属性、方法)或非静态结构(属性、方法)

类变量实例变量
yesno
对象yesyes

  1. static修饰的方法内,不能使用this和super

  2. 什么时候需要将属性声明为静态的?

判断当前类的多个实例是否能共享此成员变量,且此成员变量的值是相同的。

开发中,常将一些常量声明是静态的。比如:Math类中的PI

  1. 什么时候需要将方法声明为静态的?

    方法内操作的变量如果都是静态变量(而非实例变量)的话,则此方法建议声

    明为静态方法

    开发中,常常将工具类中的方法,声明为静态方法。比如:Arrays类、Math类

    1. 值得思考的题
    public class StaticTest {
        public static void main(String[] args) {
            Order order = null;
            order.hello();
            System.out.println(order.count);
        }
    }
    
    class Order {
        public static int count = 1;
    
        public static void hello() {
            System.out.println("hello!");
        }
    }
    

    由于类中声明为静态,则在程序运行时就已经加载了类中的属性和方法 .

2 final关键字的使用

(固定住 , 这样就不会被随意修改 , 一般用于功能完善的方法和重复使用的固定数字)

  1. final的理解:最终的\断子绝孙的

  2. 可修饰:类、方法、变量

  3. 具体说明

3.1 final修饰:表示此类不能被继承。(extends)
比如:String、StringBuffer、StringBuilder类

但可以被调用

public class Something {
    public static void main(String[] args) {
        Other o = new Other();
        new Something().addOne(o);
    }
    public void addOne(final Other o) {
        o.i++;  //可以调用
    }
}
class Other {
    public int i;
}

3.2 final修饰方法:表示此方法不能被重写
比如:Object类中的getClass()

3.3 final修饰变量:既可以修饰成员变量,也可以修饰局部变量。
此时的"变量"其实就变成了"常量",意味着一旦赋值,就不可更改。

​ 3.3.1 final修饰成员变量的赋值?

显式赋值

      final int num;
        num = 10;

代码块中赋值

final int MAX_SCORE;
> 
>     {
>         MAX_SCORE = 100;
>     }

构造器中赋值

final int LEFT;
public E(){
        LEFT = 2;
    }
    public E(int left){
        LEFT = left;
    }

3.3.2 final修饰局部变量

方法内声明的局部变量:在调用局部变量前,一定需要赋值。而且一旦赋值,就不可更改

 public void method(){
        final int num;
        num = 10;
//        num++;
        System.out.println(num);
    }

方法的形参:在调用此方法时,给形参进行赋值。而且一旦赋值,就不可更改

    public void method(final int num){
//        num++;
        System.out.println(num);
    }	
  1. final与static搭配:修饰成员变量时,此成员变量称为:全局常量

    常用于一个特定的数字要重复调用 , 避免不知道其意义 .

    比如:Math的PI

3 单例模式
  1. 设计模式概述:
    设计模式是在大量的实践中总结理论化之后优选的代码结构、编程风格、以及解决问题的思考方式。设计模式免去我们自己再思考和摸索

经典的设计模式一共有23种

在这里插入图片描述

  1. 单例模式(Singleton):
    所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法。

  2. 实现单例模式:

饿汉式

class Bank{

    //1. 类的构造器私有化
    private Bank(){

    }

    //2. 在类的内部创建当前类的实例
    //4. 此属性也必须声明为static的
    private static Bank instance = new Bank();

    //3. 使用getXxx()方法获取当前类的实例,必须声明为static的
    public static Bank getInstance(){
        return instance;
    }

}

懒汉式

class GirlFriend{
    //1.类的构造器私有化
    private GirlFriend(){
    }

    //2. 声明当前类的实例
    //4. 此属性也必须声明为static的
    private static GirlFriend instance = null;

    //3. 通过getXxx()获取当前类的实例,如果未创建对象,则在方法内部进行创建
    public static GirlFriend getInstance(){

        if(instance == null){

            instance = new GirlFriend();

        }

        return instance;


    }
}
  1. 对比两种模式(
    特点:

饿汉式:“立即加载”,随着类的加载,当前的唯一实例就自动创建
懒汉式:“延迟加载”,在需要使用的时候手动创建。

优缺点:

饿汉式:(优点)写法简单,由于内存中较早加载,使用更方便、更快。是线程安全的。
(缺点)内存中占用时间较长
懒汉式:(优点)在需要的时候进行创建,节省内存空间。
(缺点)线程不安全

  1. 运用场景

手机app,打开界面时,布满整个屏幕

2

main()方法的剖析
public static void main(String args[]){}

  1. 理解1:看做是一个普通的静态方法

    public class MainTest {
        public static void main(String[] args) { //程序的入口
            String[] arr = new String[]{"AA","BB","CC"};
            Main.main(arr);
        }
    }
    
    class Main{
    
        public static void main(String[] args) { //看做是普通的静态方法
            System.out.println("Main的main()的调用");
            for (int i = 0; i < args.length; i++) {
                System.out.println(args[i]);
            }
    
        }
    
    }
    
  2. 理解2:看做是程序的入口,格式是固定的。

  3. 与控制台交互(如何从键盘获取数据?)

传值方式

方式1:使用Scanner
方式2:使用main()的形参进行传值。

4 代码块1

回顾:类中可以声明的结构:属性、方法、构造器;代码块(或初始化块)、内部类

  1. 作用
    用来初始化类或对象的信息(即初始化类或对象的成员变量)

  2. 代码块的修饰:
    只能使用static进行修饰。

  3. 代码块的分类:
    **静态代码块:**使用static修饰
    **非静态代码块:**没有使用static修饰

  4. 具体使用:
    4.1 静态代码块

    1. 随着的加载而执行
    2. 由于类的加载只会执行一次,进而静态代码块也只会执行一次
    3. 作用:用来初始化的信息
    4. 内部可以声明变量、调用属性或方法、编写输出语句等操作。
    5. 静态代码块的执行要先于非静态代码块的执行
    6. 如果声明有多个静态代码块,则按照声明的先后顺序执行
    7. 静态代码块内部只能调用静态的结构(即静态的属性、方法),非静态不可以

4.2 非静态代码块

  1. 随着对象的创建而执行
  2. 每创建当前类的一个实例就会执行一次
  3. 作用:用来初始化对象的信息
  4. 内部可以声明变量调用属性或方法、编写输出语句等操作。
  5. 如果声明有多个非静态代码块,则按照声明的先后顺序执行
  6. 非静态代码块内部可以调用静态的结构(即静态的属性、方法),静态也可以
       public User(){
        System.out.println("新用户注册");
        registrationTime = System.currentTimeMillis();//获取系统当前时间 (距离1970-1-1 00:00:00的毫秒数)
        userName = System.currentTimeMillis() + "";
        password = "123456";
    }
   
   ___________________________________________________
   //可改成
   
   {
        System.out.println("新用户注册");
        registrationTime = System.currentTimeMillis();//获取系统当前时间 (距离1970-1-1 00:00:00的毫秒数)
    }

    //代码块的使用
    public User1(){

        userName = System.currentTimeMillis() + "";
        password = "123456";
    }
5 赋值先后顺序
  1. 可以给类的非静态的属性(即实例变量)赋值的位置有:
    ① 默认初始化
    ② 显式初始化 或 ⑤ 代码块中初始化
    ③ 构造器中初始化

④ 有了对象以后,通过"对象.属性"或"对象.方法"的方法进行赋值

  1. 执行的先后顺序:
    ① - ②/⑤ - ③ - ④

  2. 给实例变量赋值的位置很多,开发中如何选?

显示赋值:比较适合于每个对象的属性值相同的场景

构造器中赋值:比较适合于每个对象的属性值不相同的场景

  1. 执行口诀

    由父及子 , 静态先行

    有几个类就先执行几个类中的静态 , 切记子类的父类要先执行 2

    public class Test02 {
        static int x, y, z;
    
        static {
            int x = 5; 
            x--; //4 XXX错了 在代码块里定义了一个局部变量,在出了代码块的生命周期后 ,这个局部变量就消亡了 . 此x非 Test02.x 
        }
    
        static {
            x--; //3 XXX 从初始值开始-- = -1
        }
    
        public static void method() {
            y = z++ + ++z; //-1+1=0
        }
    
        public static void main(String[] args) {
            System.out.println("x=" + x); //-1  
            z--; //-1
            method(); 
            System.out.println("result:" + (z + y + ++z)); //1+0+2=3
        }
    
    
    }
    
    
    //代码块先于构造器执行
    
    public class Test03 {
        public static void main(String[] args) {
            Sub s = new Sub();
        }
    }
    class Base{
        Base(){
            method(100);  //2 是子类已经重写的方法 因为默认省略了 this.method 表示的是当前对象的方法
        }
        {
            System.out.println("base");   //1 一定是先执行代码块
        }
        public void method(int i){
            System.out.println("base : " + i);
        }
    }
    class Sub extends Base{
        Sub(){
            super.method(70);  //表示被重写的父类的代码 .
        }
        {
            System.out.println("sub");
        }
        public void method(int j){
            System.out.println("sub : " + j);  
        }
    }
    

  1. 类的成员之四 ↩︎

  2. 因为执行时会调用super();此时就会执行父类 , 的静态 ↩︎

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值