Java面向对象编程高阶(一)
- 一、关键字static
- 1、static修饰属性
- 2、静态变量与实例变量的对比
- 3、static修饰方法
- 4、什么时候将属性声明为静态的?
- 5、什么时候将属性声明为静态的?
- 6、代码演示
一、关键字static
static用来修饰的结构:属性、方法、代码块、内部类;
1、static修饰属性
方式一:按照数据类型:基本数据类型、引用数据类型
方式二:按照类中声明的位置:
-
成员变量:按照是否使用static修饰进行分类
- 使用static修饰的成员变量:静态变量、类变量
- 不使用static修饰的成员变量:非静态变量、实例变量
-
局部变量:方法内、方法形参、构造器内、构造器形参、代码块内
2、静态变量与实例变量的对比
个数
静态变量:在内存空间中只有一份,被类的多个对象所共享
实例变量:类的每一个实例都保存着一份实例变量
内存位置
静态变量:jdk之前,存放在方法区;jdk7之后存放在堆空间
实例变量:存放在堆空间的对象实体中
加载时机:
静态变量:随着类的加载而加载,由于类只会加载一次,所以静态变量也只有一份。
实例变量:随的对象的创建而加载。每个对象拥有一份实例变量。
调用者:
静态变量:可以被类直接调用、也可以被对象调用
实例变量:只能使用对象调用
消亡时机:
静态变量:随着类的卸载而消亡
实例变量:随着对象的消亡而消亡
3、static修饰方法
随着类的加载而加载
可以通过“类.静态方法”的方式直接调用静态方法
静态方法内可以调用静态的属性和静态的方法;(属性和方法的前缀使用的是当前类,可以省略)
不能调用非静态的属性和非静态方法。
static修饰的方法内,不能使用this和super
补充:在类的非静态方法中,可以调用当前类中的静态结构(属性、方法)或非静态结构(属性、方法)
4、什么时候将属性声明为静态的?
判断当前类的多个实例是否能够共享此成员变量,且成员变量的值是相同的
开发中我们常将一些常量声明为静态的。例如:Math中的PI
5、什么时候将属性声明为静态的?
方法内操作的变量如果是静态变量(而非实例变量)的话,则此方法建议声明为静态方法。
6、代码演示
package com;/*** package:com** @Author jimmy-yan* @Create 2024/10/26 22:21*/
public class ChinsesTest {public static void main(String[] args) {Chinese c1 = new Chinese();c1.name = "kobe";c1.age = 19;c1.nation = "china";Chinese c2 = new Chinese();c2.name = "jimi";c2.age = 20;System.out.println(c1);System.out.println(c2);System.out.println(c1.nation); //chinaSystem.out.println(c2.nation); //chinac2.nation = "CNA";System.out.println(c1.nation); //CNASystem.out.println(c2.nation); //CNA}
}class Chinese {//非静态变量、实例变量String name;int age;//静态变量、类变量static String nation;@Overridepublic String toString() {return "Chinese{" +"name='" + name + '\'' +", age=" + age +'}';}public void eat(String food) {System.out.println("我喜欢吃" + food);}public static void show() {System.out.println("我是中国人");//todo 调用静态结构System.out.println("nation=" + nation);method1();//todo 调用非静态结构
// System.out.println("name="+name);
// eat("饺子");}public static void method1() {System.out.println("我是静态测试方法");}public void method2() {System.out.println("我是非静态测试方法");}}
package com;/*** package:com** @Author jimmy-yan* @Create 2024/10/26 23:15*/
public class CircleTest {public static void main(String[] args) {Circle c1 = new Circle();System.out.println(c1);Circle c2 = new Circle();System.out.println(c2);System.out.println(Circle.total);Circle c3 = new Circle();System.out.println(c3);System.out.println(Circle.total);}}class Circle {double radius;int id; //编号static int total; //创建实例的个数public Circle() {this.id = init;init++;total++; //todo}public Circle(double radius){this();this.radius=radius;}// todo 加static,实现自动给id赋值的基数private static int init = 1001;@Overridepublic String toString() {return "Circle{" +"radius=" + radius +", id=" + id +'}';}
}
案例:编写一个类实现银行账户的概念,包含的属性有:账号、密码、存款余额、利率、最小余额,定义封装这些属性的方法,账号要自动生成。编写主类,使用银行账户类,输入、输出3个存储的上述信息。
考虑:哪些属性可以设计成static属性
package com;/*** package:com** @Author jimmy-yan* @Create 2024/10/27 20:05*/
public class AccountTest {public static void main(String[] args) {Account acc1 = new Account();System.out.println(acc1);Account acc = new Account("kobe", 666666);System.out.println(acc);}
}class Account {int id;String account;int password;double deposit_balance;static double rate;static double minimum_balabce;static int init = 1000;public Account() {init++;id = init;}public Account(String account, int password) {this();this.account = account;this.password = password;}@Overridepublic String toString() {return "Account{" +"id=" + id +", account='" + account + '\'' +", password=" + password +", deposit_balance=" + deposit_balance +'}';}
}
Account{id=1001, account='null', password=0, deposit_balance=0.0}
Account{id=1002, account='kobe', password=666666, deposit_balance=0.0}