面向对象编程(下)——第一部分

上一篇:面向对象编程(中)——第二部分


6. 面向对象编程(下)

6.1 关键字:static(静态的)
1. static的介绍

使用范围(可以修饰的结构):在Java类中,可用static修饰属性、方法、代码块、内部类

修饰后的结构的特点

  • 随着类的加载而加载
  • 优先于对象存在
  • 修饰的成员,被所有对象所共享
  • 访问权限允许时,可不创建对象,直接被类调用
2. 类变量(静态变量):被static修饰的属性

类变量(类属性)由该类的所有实例共享

2.1 属性的分类

属性,按是否使用static修饰分为:静态属性(静态变量或类变量)和非静态属性(实例变量)

  • 实例变量:创建类的多个对象时,每个对象都独立的拥有一套类中的非静态属性,当修改其中一个对象中的非静态属性时,不会导致其他对象中同样的属性值的修改。

  • 静态变量:创建类的多个对象时,多个对象共享同一个静态变量,当通过某一个对象修改静态变量时,会导致其他对象调用此静态变量时,是修改过的。

2.2 其他说明

  • 静态变量随着类的加载而加载,可以通过"类.静态变量"的方式进行调用

  • 静态变量的加载要早于对象的创建

  • 由于类只会加载一次,则静态变量在内存中也只会存在一份:存在方法区的静态域中

  • 类可以调用类变量,不可以调用实例变量;对象既可以调用类变量,也可以调用实例变量

  • 静态属性的使用可以从生命周期的角度理解

2.3 例子

class Person { 
    public int id;
    public static int total = 0;
}

public class PersonTest {
    public static void main(String args[]) {
        Person.total = 100; // 不用创建对象就可以访问静态成员,访问方式:类名.类属性
        System.out.println(Person.total);
        
        Person person = new Person();
        System.out.println(person.total); // 输出100
        
        person.total = 123;
        System.out.println(Person.total); // 输出123
        
        Person.id = 1; // 编译不通过
	}
}

2.4 类变量和实例变量内存解析

类变量和实例变量内存解析

说明:首先当类加载时,会将静态变量放到方法区的静态域中,并根据类型进行初始化,然后在主方法中通过类名的方式调用total属性,并将其值赋值为100,则修改静态域中的total值为100,随后new了一个Person对象,则在堆中开辟一块空间存放该对象的实例变量等信息,并在栈中创建一个引用让其指向该对象,然后通过该对象的引用修改了total的值,则修改静态域中的total值为123,最后又new了一个Person对象,则在堆中再次开辟一块空间存放该对象的实例变量等信息,并在栈中创建一个引用让其指向该对象,然后又通过该对象的引用修改了total的值,则修改静态域中的total值为222,因此,最后total的值为222。(创建对象的详细内存解析见面向对象(上))

3. 类方法(静态方法):被static修饰的方法

3.1 注意点

  • 静态方法随着类的加载而加载,可以通过"类.静态方法"的方式进行调用
  • 类可以调用静态方法,不可以调用非静态的方法;对象既可以调用静态方法,也可以调用非静态方法
  • 静态方法中,只能调用静态的方法或属性;非静态方法中,既可以调用非静态的方法或属性,也可以调用静态的方法或属性
  • 静态方法中,不能使用this关键字、super关键字
  • 静态方法的使用可以从生命周期的角度理解
  • static修饰的方法不能被重写

3.2 例子

class Person {
    private int id;
    private static int total = 0;
    public static void setTotalPerson(int total) {
        Person.total = total;
    }
}
public class PersonTest {
    public static void main(String[] args) {
    	Person.setTotalPerson(3);
	} 
}
4. 单例 (Singleton)设计模式

4.1 设计模式的概念

设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格、以及解决问题的思考方式。

设计模式分类

  • 创建型模式:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式
  • 结构型模式:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式
  • 行为型模式、策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式

4.2 单例设计模式的概念

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

实现方法:首先必须将类的构造器的访问权限设置为private,这样,就不能用new操作符在类的外部产生类的对象了,但在类内部仍可以产生该类的对象。因为在类的外部开始还无法得到类的对象,只能调用该类的某个静态方法以返回类内部创建的对象,静态方法只能访问类中的静态成员变量,所以,指向类内部产生的该类对象的变量也必须定义成静态的。

4.3 单例设计模式的例子

饿汉式:在声明时进行初始化赋值

class Singleton {
    private static Singleton single = new Singleton();
    
    private Singleton() {
        
    }
    
    public static Singleton getInstance() {
    	return single;
    }
}

懒汉式:在调用时进行初始化赋值

class Singleton {
    private static Singleton single = null;
    
    private Singleton() {
        
    }
    
    public static Singleton getInstance() {
        if(single == null) {
        	single = new Singleton();
        }
    	return single;
    }
}

饿汉式和懒汉式的区别

饿汉式是随着类的加载而加载,对象的加载时间过长,但是饿汉式是线程安全的;而懒汉式则是在调用时进行创建,延迟了对象的创建,但是懒汉式是线程不安全的(可以修改为线程安全的)。

4.4 单例设计模式的优点

由于单例模式只生成一个实例,减少了系统性能开销,当一个对象的产生需要比较多的资源时,如读取配置、产生其他依赖对象时,则可以通过在应用启动时直接产生一个单例对象,然后永久驻留内存的方式来解决。如java.lang.Runtime类即使用单例模式。

4.5 单例设计模式的应用场景
  • 网站的计数器,一般也是单例模式实现,否则难以同步。
  • 应用程序的日志应用,一般都使用单例模式实现,这一般是由于共享的日志文件一直处于打开状态,因为只能有一个实例去操作,否则内容不好追加。
  • 数据库连接池的设计一般也是采用单例模式,因为数据库连接是一种数据库资源。
  • 项目中,读取配置文件的类,一般也只有一个对象。没有必要每次使用配置文件数据,都生成一个对象去读取。
  • Application 也是单例的典型应用
  • Windows的Task Manager (任务管理器)就是很典型的单例模式
  • Windows的Recycle Bin (回收站)也是典型的单例应用。在整个系统运行过程中,回收站一直维护着仅有的一个实例。
6.2 理解main方法的语法
1. 方法格式

public static void main(String[] args) {}

由于Java虚拟机需要调用类的main()方法,所以该方法的访问权限必须是public,又因为Java虚拟机在执行main()方法时不必创建对象,所以该方法必须是static的,该方法接收一个String类型的数组参数,该数组中保存执行Java命令时传递给所运行的类的参数。

2. 使用说明
  • main()方法作为程序的入口

  • main()方法也是一个普通的静态方法

  • main()方法可以作为与控制台交互的方式(传递的参数都在args里)。

    命令行方式:在命令java xxx后面添加参数,例如:java HelloWorld "123" "aaa" 15 aa

    IDE方式:通过修改运行的配置

6.3 类的成员之四: 代码块(初始化块)
1. 代码块(初始化块)的说明

作用:对Java类或对象进行初始化

修饰符:代码块如果有修饰的话,只能使用static

分类:静态代码块(使用static修饰)和非静态代码块(不使用static修饰)

执行规则:由父及子,静态先行

2. 静态代码块:用static 修饰的代码块
  • 内部可以有输出语句
  • 可以在类加载时,对类的属性等进行初始化操作
  • 静态代码块内只能调用静态的属性、静态的方法,不能调用非静态的结构
  • 如果一个类中定义了多个静态代码块,则按照声明的先后顺序执行
  • 静态代码块的执行要先于非静态代码块
  • 静态代码块随着类的加载而执行,且只执行一次

例子

class Person {
    public static int total;
    static {
    	total = 100;
    }
}
public class PersonTest {
    public static void main(String[] args) {
        System.out.println("total = " + Person.total); // 100
    }
}
3. 非静态代码块:没有static修饰的代码块
  • 内部可以有输出语句
  • 可以在创建对象时,对对象的属性等进行初始化操作
  • 非静态代码块内可以调用静态的属性、静态的方法,或非静态的属性、非静态的方法
  • 如果一个类中定义了多个非静态代码块,则按照声明的先后顺序执行
  • 随着对象的创建而执行,且先于构造器执行(每创建一个对象,就执行一次非静态代码块)

例子

class Person {
    public int id;
    {	
        id = 1;
    	System.out.println("非静态代码块执行了");
    }
}
public class PersonTest {
    public static void main(String[] args) {
        Person p1 = new Person(); // 输出:"非静态代码块执行了"
        System.out.println("id = " + p1.id); // 1
        
        Person p2 = new Person(); // 输出:"非静态代码块执行了"
        System.out.println("id = " + p2.id); // 1
    }
}
4. 对属性可以赋值的位置总结

可以赋值的位置

①默认初始化

②显式初始化

③构造器中初始化

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

⑤在代码块中赋值

执行的先后顺序:① - ② / ⑤ - ③ - ④(②和⑤谁先声明谁先执行)

6.4 关键字:final

在Java中声明类、变量和方法时,可使用关键字final来修饰,表示“最终的”。

  • final修饰的类不能被继承。提高安全性,提高程序的可读性。

    例子:String类、System类、StringBuffer类等

  • final修饰的方法不能被子类重写

  • 例子:Object类中的getClass()。

  • final修饰的变量(成员变量或局部变量)即称为常量。名称大写,且只能被赋值一次。

    • final修饰属性:可以考虑赋值的位置有显式初始化、代码块中初始化、构造器中初始化
    • final修饰局部变量:尤其是使用final修饰形参时,表明此形参是一个常量。当调用此方法时,给常量形参赋一个实参,一旦赋值以后,就只能在方法体内使用此形参,但不能进行重新赋值。
  • 被static final用来修饰的属性称为全局常量


下一篇:面向对象编程(下)——第二部分

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT程

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值