Java面向对象之static关键字

1-static关键字的使用

/*
static关键字的使用

1-static:静态的

2-static可以用来修饰:属性、方法、代码块、内部类

3-static修饰属性:静态变量(或类变量)

  ①属性,按是否使用static修饰,又分为:静态属性 vs 非静态属性(实例变量)。

    实例属性:我们创建了类的多个对象,每个对象都独立的拥有一套类中的非静态属性。当修改其中一个对象中的非静态属性时,不会改变其他对象的属性。

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

  ②static修饰符的其他说明:

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

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

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

    4- 类变量 实例变量

    类     yes      no

    对象  yes  yes

  ③静态属性举例:System.out; Math.PI;

4-static修饰方法:静态方法

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

  ② 静态方法 非静态方法

  类  yes  no

  对象   yes    yes

  ③静态方法中,只能调用静态的方法或属性。非静态方法中,既可以调用非静态的方法或属性,也可以调用静态的方法或属性

5-static使用注意点:

在静态的方法内,不能使用this关键字、super关键字

6-开发中:

如何确定一个属性是否声明为Static的?

  >属性时可以被多个对象所共享的,不会随着对象的不同而不同的。

  >类中常量也通常声明为static的

如何确定一个方法是否声明为Static的?

  >操作静态属性的方法,通常设置为static的

  >工具类中的方法,习惯声明为static的,比如:Math,Array,Collections

*/

public class StaticTest {
    public static void main(String[] args) {
        Chinese.nation = "中国";
        Chinese c1 = new Chinese();
        c1.name = "李白";
        c1.age = 22;
        
        Chinese c2 = new Chinese();
        c2.name = "韩信";
        c2.age = 21;
        
        // c1.nation = "CHN";
        System.out.println(c2.nation); // 中国
        
        Chinese.walk();
    }
}
// 中国人
class Chinese{
    String name;
    int age;
    
    static String nation;
    
    public void eat() {
        System.out.println("吃中餐");
        walk();
    }
    public static void walk() {
        System.out.println("人:走路");
        
        System.out.println(nation); // 中国
        
        // eat(); 还没在内存中加载出来所有,不能调用
    }
    public static void speak() {
        System.out.println("人:讲话");
        walk();
    }
}
StaticTest.java

2-类变量 vs 实例变量内存解析

3-static关键字的应用举例

package com.lzh.exer;
/*
 * Static关键字的应用
 */
public class CircleTest {
    public static void main(String[] args) {
        Circle c1 = new Circle();
        Circle c2 = new Circle();
        Circle c3 = new Circle(3.4);
        
        System.out.println("c1的id:"+c1.getId()); // 1001
        System.out.println("c2的id:"+c2.getId()); // 1002
        System.out.println("c3的id:"+c3.getId()); // 1003
        
        System.out.println("创建圆的个数:"+Circle.getTotal()); // 3
    }
}
class Circle{
    private double redius;
    private int id; // 自动赋值
    
    private static int total; // 记录创建元的个数
    private static int init = 1001; // static声明的属性被所有对象共享
    
    public Circle() {
        id = init++;
        total++;
    }
    public Circle(double redius) {
        this();
        this.redius = redius;
//        id = init++;
//        total++;
    }
    
    public int getId() {
        return id;
    }
    
    
    public static int getTotal() {
        return total;
    }

    public double findArea() {
        return Math.PI * redius * redius;
    }
}
CircleTest.java

4-static使用练习

package com.company;
/*
 * 编写一个类实现银行账户的概念,包含的属性有“帐号”、“密 码”、“存款余额”、“利率”、“最小余额”,
 * 定义封装这些 属性的方法。账号要自动生成。 编写主类,使用银行账户类,输入、输出3个储户的上述信息。 
 * 考虑:哪些属性可以设计成static属性
 * 
 */
public class AccountTest {
    public static void main(String[] args) {
        Account account1 = new Account();
        Account account2 = new Account("123456",10000);
        
        Account.setInterestRate(0.012);
        Account.setMinMoney(100);
        
        System.out.println(account1);
        System.out.println(account2);
        
        System.out.println(account1.getBalance());
        System.out.println(account1.getId());
        System.out.println(account1.getPassWord());
        System.out.println(account1.getInterestRate());
        System.out.println(account2.getBalance());
    }

}

class Account{
    private int id;
    private String passWord = "000000";
    private double balance;
    
    private static double interestRate; // 利率共享
    private static double minMoney = 1.0; // 最小余额
    private static int init = 1001; // 用于自动生成id
    
    // 声明构造器
    public Account() {
        id = init++;
    }
    public Account(String passWord,double balance) {
        this();
        this.passWord = passWord;
        this.balance = balance;
    }
    
    public String getPassWord() {
        return passWord;
    }
    public void setPassWord(String passWord) {
        this.passWord = passWord;
    }
    public double getBalance() {
        return balance;
    }
    public void setBalance(double balance) {
        this.balance = balance;
    }
    public static double getInterestRate() {
        return interestRate;
    }
    public static void setInterestRate(double interestRate) {
        Account.interestRate = interestRate;
    }
    public static double getMinMoney() {
        return minMoney;
    }
    public static void setMinMoney(double minMoney) {
        Account.minMoney = minMoney;
    }
    public int getId() {
        return id;
    }
}
AccountTest.java

5-单例 (Singleton)设计模式

/*
* 单例设计模式:
* 1-采取一定的方法保证在整个的软件系统中,对 某个类只能存在一个对象实例
* 2-如何实现?
* ①饿汉式
* ②懒汉式
*
* 3-区分饿汉式和懒汉式
* 饿汉式:
* 好处->饿汉式是线程安全的
* 坏处->加载时间过长
* 懒汉式:
* 好处->延迟对象的创建
* 坏处->目前写法线程不安全 后面在修改
*/
public class SingletonTest1 {
    public static void main(String[] args) {
        // Bank bank = new Bank();
        Bank bank1 = Bank.getInstace();
        Bank bank2 = Bank.getInstace();
        
        System.out.println(bank1 == bank2); // true
    }
}
// 饿汉式单例模式
class Bank{
    // 1-私有化类的构造器
    private Bank() {
        
    }
    // 2-内部创建类的对象
    private static Bank instance = new Bank();
    
    // 3-提供公共静态的方法返回类的对象
    public static Bank getInstace() {
        return instance;
    }
    // 4-要求此对象也必须声明为静态的
}
单例模式之饿汉式
package com.lzh.java1;
/*
 * 单例模式懒汉式的实现
 * 
 * 懒汉式暂时还存在线 程安全问题,讲到多 线程时,可修复
 * 
 */
public class SingletonTest2 {
    public static void main(String[] args) {
        Order order1 = Order.getInstance();
        Order order2 = Order.getInstance();
        System.out.println(order1 == order2); // true
    }
}
class Order{
    
    // 1-设置私有化的构造器
    private Order() {
        
    }
    // 2-声明当前类对象,没有初始化。注意此对象必须声明为static的
    private static Order instance = null;
    // 3-声明public static 的返回当前类对象的方法
    public static Order getInstance() {
        if(instance == null) {
            instance = new Order();
        }
        return instance;
    }
}
单例模式之懒汉式
/*
* 单例设计模式的优点
*/

/*
* 单例设计模式的应用举例
*/

6-类的成员之四:代码块(或初始化块)

/*
* 类的成员之四:代码块(或初始化块)
*
* 1-代码块的作用:用来初始化类、对象
* 2-代码块有修饰的话,只能使用static
* 3-分类:静态代码块 vs 非静态代码块
* 4-静态代码块
* >内部可以有输出语句
* >随着类的加载而执行,只会执行这一次
* >作用:初始化类的信息
* >可以定义多个代码块,则按照声明的先后顺序执行
* >静态代码块的执行要优于非静态代码块的执行
* >只能调用静态结构,不能调用非静态结构
*
* 5-非静态代码块
* >随着对象的创建而执行
* >内部可以有输出语句
* >每创建一个对象,就执行一次非代码块
* >作用:可以在创建对象时,对对象属性等进行初始化
* >能调用静态结构,也能能调用非静态结构
*
* 6-对属性可以赋值的位置
* ①默认初始化
* ②显示初始化
* ③构造器中初始化
* ④有了对象以后,可以通过"对象.属性"或"对象.方法"的方式,进行赋值
* ⑤在代码块中赋值
* 执行书序:① - ② / ⑤ - ③ - ④
*
* 7-判断执行顺序时:由父及子,静态先行
*/
public class BlockTest {
    public static void main(String[] args) {
        String des = Person.desc;
        // System.out.println(des);
        Person p1 = new Person();
    }

}
class Person{
    // 属性
    String name;
    int age;
    static String desc = "我是一个人";
    
    // 构造器
    public Person() {
        
    }
    public Person(String name,int age) {
        this.name = name;
        this.age = age;
    }
    // 静态代码块
    static {
        System.out.println("Hello statci block");
        desc = "我是一个爱学习的人";
        info();
        // eat();
        // 不可调用非静态结构
    }
    // 非静态代码块
    {
        System.out.println("Hello block");
        info();
        this.name = "alex";
    }
    // 方法
    public void eat() {
        System.out.println("吃饭");
    }
    @Override
    public String toString() {
        // TODO Auto-generated method stub
        // return super.toString();
        return "Person[name="+name+", age="+age+"]";
    }
    public static void info() {
        System.out.println("我是一个快乐的人");
    }
}
BlockTest.java

7-final关键字

/*
* final:最终的
* 1-final可以用来修饰的结构:类、方法、变量
*
* 2-final 用来用来修饰一个类:此类不能再被子类继承
* 比如:String类、System类、StringBuffer类
*
* 3-final 用来修饰方法表明此方法不可以被重写
* 比如:Object类中的getClass方法
*
* 4-final 修饰变量:此时的"变量"称为是一个常量
* ①final修饰属性:可以考虑赋值的位置有:显示初始化、代码块中初始化、构造器
* ②final修饰局部变量:
* 修饰形参时,表明此形参是一个常量,只能在方法体内调用传入的实参,不能修改
*
* 5-static final 用来修饰:全局常量
*/
public class finalTest {
    public static void main(String[] args) {
        
    }
    
    final int height = 10;
    final int COLOR = 1; // 显示初始化
    final int WIDTH;
    final String name;
    public void setHeight(int height) {
        this.height = height; // 报错
    }
    {
        WIDTH = 3; // 代码块中初始化
    }
    public finalTest() {
        name = "alex"; // 构造器中初始化
    }
    
    public void showNumber(final int number) {
        number = 10; // 报错
        // final修饰形参变量后,只能在方法体内调用传入的实参,不能修改
        System.out.println(number);
    }
    
}

final class Person{
    // final修饰类后,不能再被子类继承
}
class Man extends Person{
    // 报错
}

class Animal{
    public final void show() {
        
    }
}
class Dog extends Animal{
    // public void show() {
        // 报错,不能再被重写
    // }
}
finalTest.java

 

posted @ 2020-06-04 17:29  赖正华  阅读(142)  评论(0编辑  收藏  举报