首页
技术小册
AIGC
面试刷题
技术文章
MAGENTO
云计算
视频课程
源码下载
PDF书籍
「涨薪秘籍」
登录
注册
第一章:OOP:继承
第二章:关键字 super
第三章:关键字 static
第四章:成员变量初始化
第五章:OOP:多态
第六章:关键字 native
第七章:关键字 final
第八章:Object 类的使用
第九章:抽象类
第十章:接口
第十一章:经典接口介绍
第十二章:包装类
第十三章:内部类
当前位置:
首页>>
技术小册>>
Java语言基础6-面向对象高级
小册名称:Java语言基础6-面向对象高级
3.1 概述 - 当我们在编写一个类的时候,其实就是在描述其对象的属性和行为,而并没有产生实质上的对象,只有通过 new 关键字才会产生出对象,这时系统才会分配内存空间给对象,其方法才可以供外部调用。 我们有时候希望无论是否产生了对象或无论产生了多少个对象的情况下,某些特定的数据在内存空间里只有一份 ,例如,所有的中国人都有个国家名称,每一个中国人都共享这个国家名称,不必在每一个中国人的实例对象中都单独分配一个用于代表国家名称的变量。 ![](/uploads/images/20230724/faee385b5ce7461ca18d6f6d47cc87b6.png) 3.2 类属性、类方法的设计思想 类属性作为该类各个对象之间的共享的变量。在设计类的时候,分析哪些属性不会因为对象的不同而改变,将这些属性设置为类属性,相应的方法设置为类方法。 如果方法和调用者无关,则这样的方法通常被声明为类方法,由于不需要创建对象就可以调用类方法,从而简化了方法的调用。 3.3 static 的使用范围 在 Java 中,static 可以修饰 属性 、方法 、代码块 、内部类 。 3.4 被 static 修饰的成员的特点 ① 随着类的加载而加载。 ② 优先于对象存在。 ③ 修饰的成员,被所有对象所共享。 ④ 访问权限允许的情况下,可以不创建对象,直接被类调用(推荐)。 3.5 类变量 类变量(类属性)由该类的所有实例共享。 示例: ```bash package com.github.staticdemo.demo; /** * @author maxiaoke.com * @version 1.0 */ public class Person { public static int total = 0; private int id; public Person() { total++; id = total; } } ``` ```bash package com.github.staticdemo.demo; /** * @author maxiaoke.com * @version 1.0 */ public class PersonTest { public static void main(String[] args) { System.out.println(Person.total); // 0 // 不用创建对象就可以访问静态成员 // 访问的方式:类名.类属性 类名.类方法 Person.total = 100; System.out.println(Person.total); // 100 Person p = new Person(); System.out.println(p.total); // 101 } } ``` 3.6 类方法 没有对象的实例时,可以用 类名.方法名() 的形式访问由 static 修饰的类的方法。 在 static 方法内部只能访问类的 static 修饰的属性或方法,不能访问类的非 static 的结构(加载时机不同,类变量初始化是优先于对象的)。 因为不需要实例就能访问到 static 方法,因此 static 方法内部是不能有 this 或 super 的。 static修饰的方法不能被重写 。 示例: ```bash package com.github.staticdemo.demo; /** * @author maxiaoke.com * @version 1.0 */ public class Person { public static int total = 0; private final int id; public Person() { total++; this.id = total; } public static int getTotal() { return total; } } ``` ```bash package com.github.staticdemo.demo; /** * @author maxiaoke.com * @version 1.0 */ public class PersonTest { public static void main(String[] args) { System.out.println(Person.total); // 0 // 不用创建对象就可以访问静态成员 // 访问的方式:类名.类属性 类名.类方法 Person.total = 100; System.out.println(Person.total); // 100 int total = Person.getTotal(); System.out.println(total); // 100 Person p = new Person(); System.out.println(Person.total); // 101 } } ``` 3.7 单例模式 3.7.1 概述 - 设计模式是 在大量的实践中总结和理论化之后优选的代码结构、编程风格以及解决问题的思考方式 。设计模式免去了我们再思考和摸索,就像经典的棋谱,不同的棋局,采用不同的棋谱。 - 所谓的类的单例设计模式,就是采取一定的方法保证在整个软件系统中,对 某个类有且仅有存在一个对象实例 ,并且该类只提供一个取得其对象实例的方法。如果我们要让类在一个虚拟机中只能产生一个对象,我们首先必须 将类的构造器的访问权限设置为private ,这样,就不能使用 new 关键字在类的外部产生类的对象了,但是类内部依然可以产生该类的对象。 因为类的外部开始还无法得到类的对象,只能 调用该类的某个静态方法 返回类内部创建的对象,静态方法只能访问类中的静态成员变量,所以,指向类内部产生的 该类对象的变量也必须定义为静态的 。 3.7.2 单例模式 - 示例:饿汉式 ```bash package com.github.staticdemo.demo2; /** * @author maxiaoke.com * @version 1.0 */ public class Singleton { /** * 内部提供一个当前类的实例 此实例也必须是静态化的 */ private static final Singleton singleton = new Singleton(); // 私有化构造器 private Singleton() { } /** * 提供公共的静态方法,返回当前类的对象 * * @return {@link Singleton} */ public static Singleton getInstance() { return singleton; } } ``` 示例:懒汉式 ```bash package com.github.staticdemo.demo3; /** * 懒汉式暂时有线程安全问题 * @author maxiaoke.com * @version 1.0 */ public class Singleton { /** * 内部提供一个当前类的实例 此实例也必须是静态化的 */ private static Singleton singleton; // 私有化构造器 private Singleton() { } /** * 提供公共的静态方法,返回当前类的对象 * * @return {@link Singleton} */ public static Singleton getInstance() { if (null == singleton) { singleton = new Singleton(); } return singleton; } } ``` 3.7.3 单例模式的好处 由于单例模式只生成一个实例, 减少了系统性能的开销 ,当一个对象的产生需要比较多的资源的时候,如:读取配置、产生其他依赖对象时,则可以通过在应用启动的时候直接产生一个实例对象,然后永久驻留内存的方式来解决。 举例:java.lang.Runtime ```bash package java.lang; import java.io.*; import java.util.StringTokenizer; import sun.reflect.CallerSensitive; import sun.reflect.Reflection; public class Runtime { private static Runtime currentRuntime = new Runtime(); public static Runtime getRuntime() { return currentRuntime; } private Runtime() {} // 其他略 } ``` 3.7.4 单例模式的应用场景 - ① 应用程序的日志应用 ,一般使用单例模式实现,由于共享日志的文件一直处于打开状态,所以只能有一个实例去操作,否则内容不好追加。 - ② 数据库连接池 ,一般使用单例模式实现,因为数据库连接是一种数据库资源。 - ③ 读取资源文件的类 ,一般使用单例模式实现,没有必要每次使用配置文件数据的时候,都生成一个对象去读取。 - …… 3.8 理解 main 方法的语法 - 由于 Java 虚拟机需要调用类的 main() 方法,所以该方法的访问权限必须是 public 。 - 因为 Java 虚拟机执行 main() 方法的时候不需要创建对象,所以该方法必须是 static 的。 - main() 接收一个 String 类型的数组参数,该数组汇总保存执行 Java 命令时传递给所运行的类的参数。 - 因为 main() 方法是静态的,我们不能直接访问该类中的非静态成员,必须创建该类的一个实例对象后,才能通过这个对象去访问类中的非静态成员。
上一篇:
第二章:关键字 super
下一篇:
第四章:成员变量初始化
该分类下的相关小册推荐:
Java语言基础12-网络编程
Java语言基础9-常用API和常见算法
Java语言基础15-单元测试和日志技术
Mybatis合辑2-Mybatis映射文件
深入理解Java虚拟机
Java必知必会-Maven初级
Java面试指南
Mybatis合辑5-注解、扩展、SQL构建
Mybatis合辑1-Mybatis基础入门
Java语言基础11-Java中的泛型
Java并发编程实战
JAVA 函数式编程入门与实践