java基础之 static (静态变量 静态方法 静态方法的重载 静态代码块)和访问修饰符(public,private))继承里的静态方法

1.静态变量

public class MerchandiseV2WithStaticVariable {

    public String name;
    public String id;
    public int count;
    public double soldPrice;
    public double purchasePrice;

    // >> TODO 静态变量使用 static 修饰符
    // >> TODO 静态变量如果不赋值,Java也会给它赋以其类型的初始值
    // >> TODO 静态变量一般使用全大写字母加下划线分割。这是一个习惯用法
    // >> TODO 所有的代码都可以使用静态变量,只要根据防范控制符的规范,这个静态变量对其可见即可
    //    TODO 比如 public 的静态变量,所有的代码都可以使用它
    public static double DISCOUNT_FOR_VIP = 0.95;

    //    TODO 但是如果没有public修饰符,只能当前包的代码能使用它
    static int STATIC_VARIABLE_CURR_PACKAGE_ONLY = 100;

1.静态变量和成员变量不一样,成员变量的值在不同的对象里面可以不一样,但是静态变量的值在所有对象里都一样,如果一个对象改变了静态变量的值,那么其他对象引用该静态变量的值也会随着发生变化。
2.静态变量和成员变量不一样的是,静态变量不需要随着对象的创建才创建出来,我们可以直接用类名就引用它;
静态变量一个类一个
成员变量一个实例一个

使用同一个包里不同类里的静态变量:

  // >> TODO 使用别的类的静态变量的时候,需要使用完整形态:类名.静态变量名字
        MerchandiseV2WithStaticVariable.DISCOUNT_FOR_VIP = 0.5;
        bigProfit.describe();
        double cost2 = bigProfit.buy(10, true);
        System.out.println("VIP 购买10个" + bigProfit.getName() + "的花费为" + cost2);

        // >> TODO 静态变量在整个Java程序中只有一个(对比实例变量,是每个实例有一份
        //    TODO 所以静态变量一旦变化,所有使用这个静态变量的地方的值都会变
        MerchandiseV2WithStaticVariable m0 = littleSuperMarket.getMerchandiseOf(0);

使用不同包里的静态变量

import com.geekbang.supermarket.MerchandiseV2WithStaticVariable;
import  static com.geekbang.supermarket.MerchandiseV2WithStaticVariable.*;

public class MerchandiseV2DescAppMain {
    public static void main(String[] args) {
        MerchandiseV2WithStaticVariable merchandise = new MerchandiseV2WithStaticVariable
            ("书桌", "DESK9527", 40, 999.9, 500);

        merchandise.describe();

        // >> TODO 使用import static来引入一个静态变量,就可以直接用静态变量名访问了
        //    TODO import static也可以使用通配符*来引入一个类里所有静态变量
        System.out.println(DISCOUNT_FOR_VIP);
    }
}

也就是说,同一包里就用类名.静态变量
不同包里就用包名.类名.静态变量
综上,其实无论在同一个包里还是不同包里,都可以使用import的方法先给它导入进来,然后就可以直接使用静态变量了;

2.静态方法
静态方法(也叫类方法):只能使用参数和静态变量,换言之,就是就是没有this自引用(变量引用和方法引用)的方法;
静态方法的定义和调用:
定义:

public class MerchandiseV2 {

    public String name;
    public String id;
    public int count;
    public double soldPrice;
    public double purchasePrice;

    // >> TODO 静态变量使用 static 修饰符
    public static double DISCOUNT_FOR_VIP = 0.95;

    // >> TODO 静态方法使用static修饰符。
    // 静态方法的方法名没有约定俗称全大写
    public static double getVIPDiscount() {
        // >> TODO 静态方法可以访问静态变量,包括自己类的静态变量和在访问控制符允许的别的类的静态变量
        return DISCOUNT_FOR_VIP;
    }

    // >> TODO 除了没有this,静态方法的定义和成员方法一样,也有方法名,返回值和参数
    // >> TODO 静态方法没有this自引用,它不属于某个实例,调用的时候也无需引用,直接用类名调用,所以它也不能直接访问成员变量
    // >> TODO 当然在静态方法里面,也可以自己创建对象,或者通过参数,获得对象的引用,进而调用方法和访问成员变量
    // >> TODO 静态方法只是没有this自引用的方法而已。
    public static double getDiscountOnDiscount(LittleSuperMarket littleSuperMarket) {
        double activityDiscount = littleSuperMarket.activityDiscount;
        return DISCOUNT_FOR_VIP * activityDiscount;
    }

使用


import com.geekbang.supermarket.MerchandiseV2;
import  static com.geekbang.supermarket.MerchandiseV2.getVIPDiscount;

public class MerchandiseV2DescAppMain {
    public static void main(String[] args) {
        MerchandiseV2 merchandise = new MerchandiseV2
            ("书桌", "DESK9527", 40, 999.9, 500);

        merchandise.describe();

        // >> TODO 使用import static来引入一个静态方法,就可以直接用静态变量名访问了
        //    TODO import static也可以使用通配符*来引入一个类里所有静态变量
        System.out.println(getVIPDiscount());

    }
}

静态方法的重载

public class DiscountMgr {

    public static double BASE_DISCOUNT = 0.99;

    public static double VIP_DISCOUNT = 0.85;

    public static double SVIP_DISCOUNT = 0.75;

    // >> TODO 静态方法的重载也是一样的,方法签名不同即可:方法名+参数类型
    // >> TODO 判断调用哪个方法,也是根据调用时参数匹配决定的。
    public static double getDiscount() {
        return BASE_DISCOUNT;
    }

    public static double getDiscount(boolean isVIP) {
        // TODO >> 这节课这么无聊,我们顺带学一个三元操作符吧。
        // TODO    三元操作符的返回类型就是冒号两边的类型,两边的类型要和等号左边的变量类型兼容
        // double abc = true ? "" : 0;

        double svipDiscount = (isVIP ? VIP_DISCOUNT : 1);
        return getDiscount() * svipDiscount;
    }

    public static double getDiscount(int svipLevel) {
        double ret = getDiscount() * VIP_DISCOUNT;
        for (int i = 0; i < svipLevel; i++) {
            ret *= SVIP_DISCOUNT;
        }
        return ret;
    }

    // 这节课这么无聊,我们顺带看几个不是那么正经的getDiscount吧

    // >> TODO 返回值不算是方法签名,重载的方法可以有完全不同的返回值类型
    public static void getDiscount(String s) {
        System.out.println(s);
    }

    public static int getDiscount(int a, int b) {
        return a > b ? a : b;
    }


    public static boolean getDiscount(int a, int b, int c) {
        return a > b && b > c;
    }

    public static String getDiscount(long abc) {
        return "" + abc;
    }

    public static void main(String[] args) {
        getDiscount(1, 2);
    }

}

静态代码块


public class DiscountMgr {

    public static void main(String[] args) {
        System.out.println("最终main 方法中使用的SVIP_DISCOUNT是" + SVIP_DISCOUNT);
    }

    public static double BASE_DISCOUNT;

    public static double VIP_DISCOUNT;

    // >> TODO 使用某个静态变量的代码块必须在静态变量后面
    // >> TODO (但是仅仅赋值没有限制,很妖的语法哈,有些语法就应该在学会的第一时间忘掉它)
    public static double SVIP_DISCOUNT;


    static {
        BASE_DISCOUNT = 0.99;
        VIP_DISCOUNT = 0.85;
        SVIP_DISCOUNT = 0.75;

        // >> TODO 静态代码块里当然可以有任意的合法代码
        System.out.println("静态代码块1里的SVIP_DISCOUNT" + SVIP_DISCOUNT);

        // >> TODO 这段代码在哪个方法中呢?<clinit>,即class init。会在每个class初始化的时候被调用一次
//         SVIP_DISCOUNT = 9/0;
    }

    // >> TODO 其实给静态变量赋值也是放在代码块里的,static代码块可以有多个,是从上向下顺序执行的。
    //    TODO 可以认为这些代码都被组织到了一个clinit方法里
    // public static double WHERE_AM_I = 9/0;

//     public static double SVIP_DISCOUNT;

    static {
        SVIP_DISCOUNT = 0.1;
        System.out.println("静态代码块2里的SVIP_DISCOUNT" + SVIP_DISCOUNT);
    }


}

我们发现,静态代码块并不在我们的方法体里面,那它在哪儿呢,事实上,它存在于java的一个初始化方法里面;
3.访问修饰符(public,private)
在这里插入图片描述

// >> TODO 类,静态方法,静态变量,成员变量,构造方法,成员方法都可以使用访问修饰符
public class MerchandiseV2 {

    // >> TODO 成员变量应该都声明为private
    // >> TODO 如果要读写这些成员变量,最好使用get set方法,这些方法应该是public的
    // >> TODO 这样做的好处是,如果有需要,可以通过代码,检查每个属性值是否合法。
    private String name;
    private String id;
    private int count;
    private double soldPrice;
    private double purchasePrice;
    private NonPublicClassCanUseAnyName nonPublicClassCanUseAnyName;
    public static double DISCOUNT = 0.1;

    // >> TODO 构造方法如果是private的,那么就只有当前的类可以调用这个构造方法
    public MerchandiseV2(String name, String id, int count, double soldPrice, double purchasePrice) {
        this.name = name;
        this.id = id;
        this.count = count;
        this.soldPrice = soldPrice;
        this.purchasePrice = purchasePrice;
        // soldPrice = 9/0;
    }

    // >> TODO 有些时候,会把所有的构造方法都定义成private的,然后使用静态方法调用构造方法
    // >> TODO 同样的,这样的好处是可以通过代码,检查每个属性值是否合法。
    public static MerchandiseV2 createMerchandise(String name, String id, int count,
                                                  double soldPrice, double purchasePrice) {
        if (soldPrice < 0 || purchasePrice < 0) {
            return null;
        }
        return new MerchandiseV2(name, id, count, soldPrice, purchasePrice);
    }

    public MerchandiseV2(String name, String id, int count, double soldPrice) {
        this(name, id, count, soldPrice, soldPrice * 0.8);
    }

    public MerchandiseV2() {
        this("无名", "000", 0, 1, 1.1);
    }

    // >> TODO public的方法类似一种约定,既然外面的代码可以使用,就意味着不能乱改。比如签名不能改之类的
    public void describe() {
        System.out.println("商品名字叫做" + name + ",id是" + id + "。 商品售价是" + soldPrice
            + "。商品进价是" + purchasePrice + "。商品库存量是" + count +
            "。销售一个的毛利润是" + (soldPrice - purchasePrice));
        freeStyle();
    }

    // >> TODO 对于private的方法,因为类外面掉不到,所以无论怎么改,也不会影响(直接影响)类外面的代码
    private void freeStyle() {

    }

继承里的静态方法

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值