JavaSE 09 面向对象(下)

1、static关键字

⑴ 概念


static是一个修饰符,可以修饰属性、方法、内部类,但是不能修饰构造器和局部变量。
用static修饰的成员,称为静态成员或类成员;不用static修饰的成员,称为普通成员或实例成员。

⑵ 静态属性


当该类的所有的对象都共享该属性,而且值一样时,可以将属性定义为静态的。
例如:圆周率、国家(人的属性)等

静态属性和普通属性的特点

  ① 1.static属性都随着类的加载而加载(在内存中【方法区中的静态域】开辟了空间),随着类的卸载而死亡。
     2.普通属性随着对象的创建而加载,随着对象的消亡而消亡。
  ② 1.static属性的生命周期较长。
     2.普通属性的声明周期较短。
  ③ 1.static属性存放在方法区中。
     2.普通属性存放在堆中。
  ④ 1.static属性在整个内存中只有一份。
     2.普通属性根据对象的数量可以有多个。
  ⑤ 1.static属性可以被多个对象共享。
     2.普通属性只能被当前对象独享。
  ⑥ 1.static属性的值,被某一对象修改后,则会影响到其他共享此属性的对象。
     2.普通属性的值,被某一对象修改后,则不会影响到其他包含此属性的对象。
  ⑦ 1.static属性,可以通过类名来直接调用。因为该属性和对象无关。
     2.普通属性,则需要通过对象来调用。
  ⑧ 1.static属性,被成为静态属性或类属性。
     2.没有被static修饰的属性,被成为普通属性或非静态属性或实例属性。

⑶ 静态方法


当该方法不涉及到任何和该类有关的成员时,可以将方法定义为静态的。
例如:Arrays类、Math类等中的方法都是静态的。

静态方法和普通方法的特点

① 1.static方法是随着类的加载而被加载,它可以通过类名来调用。因为不需要this关键字。
   2.普通方法也是随着类的加载而被加载的,它必须通过对象来调用。因为它需要this关键字【普通方法隐含一个this的形参】。
② 1.static方法中只能访问static的属性或方法。如果非要访问普通的方法或属性,则需要通过创建对象来调用。
   2.普通方法既可以访问static的属性或方法,又可以访问普通的属性或方法。

   ③ 1.static方法没有重写这一概念

   2.普通方法(父类中的)可以被子类重写。

示例:

public class Father {
  public static void method() {
  }
}

class Son extends Father {
  @Override
  public static void method() {
  }
}

其中子类中会报错:The method method() of type Son must override or implement a supertype method
静态方法没有重写的概念

⑷ 静态成员的特点


① 都是随着类的加载而被加载。
② 声明周期都比较长。
③ 都可以通过类名. 的方式来调用。
④ 都属于类的成员,和对象无关。

2、final关键字

⑴ 概念


final可以修饰变量(属性或局部变量)、方法、类,但不能修饰构造器。

⑵ final修饰类


特点:被final修饰的类,不能被继承。
例如:String类等。

⑶ final修饰方法


特点:父类中定义的被final修饰的方法,子类中不能重写。但可以被继承(被子类对象调用)。

⑷ final修饰变量


特点:
① 被final修饰的变量,因为它不能再次被修改,所以一般也称为常量。
② 常量的命名规范:所有的字母都大写,以提高代码的阅读性。
③ 被final修饰的引用数据类型的变量,可以修改引用的对象的属性值,但是不能更改地址号【引用】,也就是不能更改对象。
示例:

public class Test {
  final Book book = new Book();

  public void method() {
    book.name = "Java";
    book = new Book(); // 错误: 无法为最终变量book分配值
  }
}

class Book {
  String name;
}

④ final修饰属性和修饰局部变量的区别:
     ⒈ 修饰属性【全局变量】
          必须在声明时并赋值;或先声明并在构造器中赋值,或先声明并在初始化块中赋值。

示例:

public class Test {
  // final double PI = 3.14;

  // final double PI;
  /* public Test( ){
       PI = 3.14;
     }*/

  final double PI;
  {
    PI = 3.14;
  }
}

     ⒉ 修饰局部变量
          不一定声明时并赋值,可以先声明,随后再赋值。
⑤ 通常会用static final 一起搭配,来修饰属性,以此来提高效率。

3、初始化块

⑴ 概念


初始化块属于类的成员之一,用于初始化信息。

⑵ 语法

 修饰符 {
    语句
 }

⑶ 注意事项


① 初始化块类似于方法,但是没有返回值,没有形参列表。它只有方法体,但是不能通过类或对象来显示地调用,只能在创建对象或加载类时,被隐式地调用。
② 修饰符只能是static【可有可无】
③ 语句可以为任意的输入、输出、条件判断、循环等。
静态初始化块只能调用类的静态成员。

⑷ 作用


① 可以用来初始化信息。
② 当多个构造器包含相同的语句时,可以抽取出来,放到初始化块中,以此减少代码量,提高代码的重用性。

⑸ 特点


① 一个类中可以有多个静态初始化块或普通初始化块,创建对象或加载时会执行这些初始化块。 同一类型的初始化块的执行顺序为定义的先后顺序,自上而下依次被执行
② 当一个类中既有静态初始化块又有普通静态初始化块时,静态初始化块的执行会优先于普通初始化块的执行。
静态初始化块随着类的加载而被执行,而且 只会被执行一次普通初始化块会随着对象的创建而被执行,而且 可以被执行多次
④ 当一个类中含有静态初始化块、普通初始化块、静态属性、普通属性和构造器时,被执行的优先级是: 静态 > 普通 > 构造器。其中 静态初始化块和静态属性的执行顺序,由其各自定义的先后顺序决定,自上而下依次被执行
⑤ 当一个子类中含有静态初始化块、普通初始化块、静态属性、普通属性和构造器,其父类中也含有静态初始化块、普通初始化块、静态属性、普通属性和构造器时。被执行的优先级是: 父类静态 > 子类静态 > 父类普通 > 父类构造器 > 子类普通 > 子类构造器。其中 静态初始化块和静态属性的执行顺序,由其各自定义的先后顺序决定,自上而下依次被执行

4、单例模式

⑴ 作用

单例模式可以解决整个项目中,只需要有一个某类的实例。

⑵ 为什么用它

① 在项目中频繁地调用某一类中的成员,而且不需要该类的对象。这时就不需要多次实例化该类的对象,只要一个该类的对象即可。这样做可以提高效率,减少内存的消耗。
② 从逻辑上来说,只能有一个某类的实例,如果创建了多个该类的实例,则会导致逻辑错误,项目混乱。

⑶ 实现步骤

① 私有化构造器。
② 在本类中创建私有化的对象。
③ 提供一个公共的、静态的get方法。

⑷ 分类

① 饿汉式


在类加载时创建对象

示例:

public class Test {
  public static void main(String[] args) {
    Singleton s1 = Singleton.getInstance();
    Singleton s2 = Singleton.getInstance();
    System.out.println(s1 == s2);
    System.out.println(s1);
    System.out.println(s2);
  }
}

class Singleton {
  private Singleton(){}

  private static Singleton instance = new Singleton();

  public static Singleton getInstance() {
    return instance;
  }
}

② 懒汉式


在调用方法时创建对象。

示例【这不是最终版本,因为当前示例是线程不安全的。最终版本在 JavaSE 15 多线程 (9、线程的同步 ⑽ 解决单例模式懒汉式的线程同步问题)中】:

public class Test {
  public static void main(String[] args) {
    Singleton s1 = Singleton.getInstance();
    Singleton s2 = Singleton.getInstance();
    System.out.println(s1 == s2);
    System.out.println(s1);
    System.out.println(s2);
  }
}

class Singleton {
  private Singleton(){}

  private static Singleton instance;

  public static Singleton getInstance() {
    if (null == instance) {
      instance = new Singleton();
    }
    return instance;
  }
}

③ 饿汉式和懒汉式的区别


懒汉式创建对象的时机【在调用方法时创建对象】比饿汉式创建对象的时机【在类加载时创建对象】较晚。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值