day18-java

static 关键字

概述

package com.itheima.staticdemo;

/**
 * 被static修饰的成员变量称为静态变量,也叫类变量
 * 类变量属于类,只在内存中加载一次,被所有的对象共享
 * 可以使用类名直接调用,亦可使用对象调用但不推荐
 * 类方法的调用与类变量相同
 * 注意:同一个类中可以省略类名
 */
public class Demo01Static {
    public static void main(String[] args) {
        User user = new User();
        //不应该通过类实例访问静态成员
        user.onlineNumber = 5;
        //通过类名访问,5
        System.out.println(User.onlineNumber);
    }
}

访问注意事项

package com.itheima.staticdemo;

/**
 * 访问注意事项:
 * 1.静态方法只能访问静态成员变量
 * 2.实例方法可以访问静态成员变量和实例成员变量
 * 3.静态方法中不能出现this关键字
 */
public class Demo02Static {
    private static String name;
    public static void print(){
        //System.out.println(this);this关键字属于对象,静态方法不一定使用对象调用
    }
    public static void main(String[] args) {
        print();
    }
}

静态方法、变量的定义

package com.itheima.staticdemo;

/**
 * 类变量与类同时加载,类的字节码文件加载进方法区的同时
 * 类变量加载进堆内存的静态变量区
 * 若一个方法表示的是对象本身的行为或者需要访问实例成员,则需要申明为实例成员方法
 * 若实现的是一个共用功能,则可以申明为静态方法
 */
public class User {
    private String name;
    private int age;
    public static int onlineNumber;

    public static void main(String[] args) {
        //类名调用
        User.onlineNumber = 10;
        //System.out.println(name);报错
        //本类中可省略类名,10
        System.out.println(onlineNumber);

        User u1 = new User();
        u1.age = 10;
        u1.name = "张三";
        //对象调用(不推荐)
        u1.onlineNumber++;
        System.out.println(u1.name);
        System.out.println(u1.age);
        //11
        System.out.println(onlineNumber);

        User u2 = new User();
        u2.name = "李四";
        u2.age = 30;
        u2.onlineNumber++;
        System.out.println(u2.name);
        System.out.println(u2.age);
        //12
        System.out.println(onlineNumber);

    }
}

工具类

1.itheima工具类

package com.itheima.staticdemoutil;

import java.util.Random;

/**
 * 工具类,里面定义了很多类方法,方便调用,提高代码复用性
 * 因为不需要创建对象调用,所以应将构造器私有化,专业!
 */
public class ItheimaUtil {
    //构造器私有化
    private ItheimaUtil() {
    }

    /**
     * 生成验证码
     * @param n 验证码位数
     * @return 返回生成的验证码
     */
    public static String createVerifyCode(int n){
        String code = "";
        String s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        Random random = new Random();
        for (int i = 0; i < n; i++) {
            int index = random.nextInt(s.length());
            code += s.charAt(index);
        }
        return code;
    }
}

测试itheima工具类

package com.itheima.staticdemoutil;

/**
 * 测试ItheimaUtil工具类
 */
public class TestIthaimaUtil {
    public static void main(String[] args) {
        //生成一个4位验证码
        System.out.println(ItheimaUtil.createVerifyCode(4));
        //构造器私有化后无法创建该类对象
        //ItheimaUtil itheimaUtil = new ItheimaUtil();
    }
}

2.Arrays工具类

package com.itheima.staticdemoutil;

/**
 * 训练:
 * 数组工具类
 * 1.toString(),返回整数数组内容,返回字符串格式为[1,3,4,5]
 * 2.getAvg(),去掉最高分、最低分,计算返回平均值
 */
public class ArraysUtils {
    private ArraysUtils(){

    }
    /**
     * 返回整数数组内容,返回字符串格式为[1,3,4,5]
     * @param arr 传入的整数数组
     * @return 返回生成的字符串
     */
    public static String toString(int[] arr){
        if (arr == null){
            return null;
        }
        String s = "[";
        for (int i = 0; i < arr.length; i++) {
            String ss = "";
            if (i == arr.length-1){
                ss = arr[i] + "]";
            }else {
                ss = arr[i] + ",";
            }
            s += ss;
        }
        return s;
    }

    /**
     * 去掉最高分、最低分,计算返回平均值
     * @param arr 传入的整数数组
     * @return 返回平均值
     */
    public static double getAvg(int[] arr){
        if (arr == null){
            return -1;
        }
        double avg = 0;
        int max = arr[0],min = arr[0],sum = 0;
        for (int i = 0; i < arr.length; i++) {
            if (arr[i]>max){
                max = arr[i];
            }
            if (arr[i]<min){
                min = arr[i];
            }
            sum += arr[i];
        }
        avg = (sum-max-min)/(arr.length-2);
        return avg;
    }
}

测试Arrays工具类

package com.itheima.staticdemoutil;

/**
 * 测试ArraysUtils工具类
 */
public class TestArraysUtils {
    public static void main(String[] args) {
        int[] arr = {1,3,2,5};
        System.out.println(ArraysUtils.toString(arr));
        System.out.println(ArraysUtils.getAvg(arr));
    }
}

代码块

package com.itheima.staticdemocodeblock;

import java.util.ArrayList;

/**
 * 静态代码块:static{},使用static修饰,与类同时加载一次,
 * 自动触发,在main方法之前,用于初始化静态资源
 * 实例代码块:{},每次创建对象都执行一次,在构造器之前
 * 用于初始化实例资源
 */
public class Demo01CodeBlock {
    private static String name;
    private int age;
    public static ArrayList<String> list = new ArrayList<>();

    public Demo01CodeBlock() {
        System.out.println("构造器执行了");
    }

    public static void main(String[] args) {
        System.out.println("main方法执行了");
        System.out.println(name);
        System.out.println(list);
        Demo01CodeBlock d1 = new Demo01CodeBlock();
    }
    static {
        //初始化静态成员变量
        System.out.println("静态代码块触发了");
        name = "张三";
        list.add("a");
    }
    {
        System.out.println("实例代码块触发了");
        //初始化实例成员变量,可以,但很少这么做
        age = 10;
    }
}

代码块案例:

package com.itheima.staticdemocodeblock;

import java.util.ArrayList;

/**
 * 案例:使用静态代码块生成一副牌
 */
public class Case01 {
    public static ArrayList<String> list = new ArrayList<>();

    static {
        String[] arr1 = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
        String[] arr2 = {"♠","♥","♣","♦"};
        for (int i = 0; i < arr1.length; i++) {
            for (int i1 = 0; i1 < arr2.length; i1++) {
                String s = arr2[i1] + arr1[i];
                list.add(s);
            }
        }
        list.add("小🃏");
        list.add("大🃏");
    }
    public static void main(String[] args) {
        System.out.println(list);
    }
}

单例模式

1.饿汉单例模式

package com.itheima.staticdemosingleinstance;

/**
 * 设计模式:一个问题有n种解法,其中最优秀的解法被总结出来后,
 * 称之为设计模式,有二十多种
 * 单例模式:应用该模式的类只能有一个对象
 * 饿汉单例模式:在类获取对象时就已经创建好了对象
 */
public class Demo01SingleInstance {
    /**
     * 1.构造器私有化
     */
    private Demo01SingleInstance(){

    }

    /**
     * 2.定义一个静态变量存储对象
     */
    public static Demo01SingleInstance instance = new Demo01SingleInstance();

}

2.懒汉单例模式

package com.itheima.staticdemosingleinstance;

/**
 * 懒汉单例模式:
 * 在真正需要对象时才去创建对象
 */
public class Demo02SingleInstance {
    /**
     * 1.构造器私有化
     */
    private Demo02SingleInstance(){}
    /**
     * 2.定义静态变量用于存储对象
     * 注意:该变量最好私有化
     */
    private static Demo02SingleInstance instance;
    /**
     * 3.定义方法创建对象
     * 判断是否第一次创建对象,是则创建,否则返回之前的对象
     */
    public static Demo02SingleInstance getInstance(){
        if (instance == null){
            instance = new Demo02SingleInstance();
        }
        return instance;
    }
}

测试单例模式

package com.itheima.staticdemosingleinstance;

/**
 * 测试单例模式
 * @author shifan
 */
public class TestSingleInstance {
    public static void main(String[] args) {
        //饿汉单例:
        //创建对象,只能通过类名获取唯一的对象
        Demo01SingleInstance s1 = Demo01SingleInstance.instance;
        Demo01SingleInstance s2 = Demo01SingleInstance.instance;
        //true
        System.out.println(s1 == s2);

        //懒汉单例:
        //通过getInstance方法获取对象
        Demo02SingleInstance d1 = Demo02SingleInstance.getInstance();
        Demo02SingleInstance d2 = Demo02SingleInstance.getInstance();
        //true
        System.out.println(d1 == d2);
    }
}

继承内存图

继承内存图

继承的特点

package com.itheima.extendsdemofeature;

/**
 * 继承的特点:
 * 1.子类可以继承父类的属性和方法,但不能继承父类的构造器
 * 2.Java是单继承模式:一个类只能直接继承一个类
 * 3.Java不支持多继承但是支持多层继承
 * 4.Java中所有的类都是object的子类
 */
public class TestExtendsFeature {
    public static void main(String[] args) {
        /*
         有争议的问题:
         1.子类是否能继承父类的私有成员?
            可以,只不过不能直接访问
         2.子类是否能继承父类的静态成员?
            可以直接调用,但只是共享,不是继承
         */
        Student stu = new Student();
        stu.name = "张三";
        //张三
        System.out.println(stu.name);
        //stu.eat();报错
    }
}
class People{
    public static String name;
    public int age;
    private void eat(){
        System.out.println("干饭干饭!");
    }
    void run(){
        System.out.println("跑");
    }
    public static void study(){
        System.out.println("学习");
    }
}
class Student extends People{
    public int age;

    /**
     * @Override 是重写注解,加上后方法必须重写正确才不会报错,且代码可读性好
     * 重写方法必须方法名、参数列表和父类方法相同
     * 子类重写父类方法时,访问权限必须大于等于父类
     * 这里父类访问权限为default,子类权限为public
     */
    @Override
    public void run(){
        System.out.println("走路");
    }
/*  私有方法不能被重写
    @Override
    public void eat(){
        System.out.println("吃饭");
    }*/

/*  静态方法不能被重写
    @Override
    public static void study(){
        System.out.println("学习");
    }*/


    public void printAge(){
        int age = 10;
        /*
        在子类方法中访问成员满足就近原则
        首先在子类局部范围找,然后在子类成员范围找,
        最后在父类成员范围找,找不到就报错
         */
        //这里使用本方法内的age
        System.out.println(age);
        //这里使用本类的age
        System.out.println(this.age);
        //这里使用父类的age
        System.out.println(super.age);
    }
}

子类构造器、this、super关键字

package com.itheima.extendsdemoconstructor;

/**
 * 1.子类构造器的特点:
 * 子类中所有构造器都会默认先访问父类中无参构造器再执行自己
 * 即所有子类构造器中都隐式调用了父类无参构造器,super()
 * 2.子类构造器访问父类有参构造器:
 * 用于初始化继承自父类的属性
 *
 */
public class TestExtendsConstructor {
    public static void main(String[] args) {
        Student stu1 = new Student("张三",18);
        System.out.println(stu1.getAge());
        System.out.println(stu1.getName());
    }
}
/**
 * this()和super()都只能放在方法内第一行,故不能同时出现
 * 因为:1.this(...)调用本类其他有参构造器的时候,
 * 其他有参构造器还是会自动调用父类有参构造器
 * 2.子类初始化之前必须先初始化父类,故super()必须放在第一行
 */
class Student extends People {
    public Student() {
/*
        若父类中没有无参构造器这里就会报错,
        因为子类的构造器都会先自动调用父类无参构造器
        可手动调用父类有参构造器解决,super(...)
*/
    }
    public Student(String name){
        //this调用本类其他构造方法,这里用于未给定age的情况
        this(name,18);
    }

    public Student(String name, int age) {
        //调用父类有参构造器初始化继承自父类的属性
        //简化了子类的有参构造,提高了代码复用
        super(name, age);
    }
}

class People {
    private String name;
    private int age;

    public People() {
    }

    public People(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

练习题1

package com.itheima.exercises;

import com.itheima.exercises.domain.NewPhone;
import com.itheima.exercises.domain.Phone;

/**
 * 每一款手机都有自己的品牌和价格,原来的手机只能打电话,发短信;
 * 现在的新手机,在打电话和发短信的基础上还能玩儿游戏,请设计程序,完成手机的升级!
 */
public class Exercise01 {
    public static void main(String[] args) {
        Phone p1 = new Phone();
        p1.setBrand("诺基亚");
        p1.setPrice(1000);
        System.out.println("旧手机品牌:"+p1.getBrand());
        System.out.println("旧手机价格:"+p1.getPrice());
        System.out.println("旧手机功能:");
        p1.call();
        p1.sendMessage();
        System.out.println("=============================================");
        NewPhone p2 = new NewPhone();
        p2.setBrand("苹果");
        p2.setPrice(10000);
        System.out.println("新手机品牌:"+p2.getBrand());
        System.out.println("新手机价格:"+p2.getPrice());
        System.out.println("新手机功能:");
        p2.call();
        p2.playGames();
        p2.sendMessage();
    }
}
class Phone{
    private String brand;
    private int price;

    public void sendMessage(){
        System.out.println("发短信");
    }
    public void call(){
        System.out.println("打电话");
    }

    public Phone() {
    }

    public Phone(String brand, int price) {
        this.brand = brand;
        this.price = price;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }
}
class NewPhone extends Phone {
    public void playGames() {
        System.out.println("玩游戏");
    }
}

练习题2

package com.itheima.exercises;

import com.itheima.exercises.domain.IPhone;

/**
 * 每一款手机都有自己的品牌和价格,
 * 原来的手机只能打电话,发短信,来电显示只能显示手机号;
 * 现在的新手机针对于来电显示做了功能的升级,还能显示头像,
 * 还能显示归属地,请设计程序,完成手机的升级!
 */
public class Exercise02 {
    public static void main(String[] args) {
        IPhone iPhone = new IPhone();
        iPhone.called("123");
    }
}
class IPhone extends OldPhone {
    @Override
    public void called(String number){
        super.called(number);
        System.out.println("头像:^_^");
        System.out.println("归属地:北京");
    }
}
class OldPhone{
    private String brand;
    private int price;

    public OldPhone() {
    }

    public OldPhone(String brand, int price) {
        this.brand = brand;
        this.price = price;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    void sendMessage(){
        System.out.println("发短信");
    }
    void call(){
        System.out.println("打电话");
    }
    void called(String number){
        System.out.println("号码"+number+"来电");
    }
}

练习题3

package com.itheima.exercises;

import com.itheima.exercises.domain.Bear;
import com.itheima.exercises.domain.Panda;

/**
 *  白色4条腿的北极熊(Bear)会吃(吃蜂蜜)和抓鱼(catchFish)
 *  黑色4条腿的大熊猫(Panda)会吃(吃竹子)和爬树(climbTree)
 *  要求: 把北极熊和大熊猫的共性提取动物类(Animal)中,使用抽象类
 */
public class Exercise03 {
    public static void main(String[] args) {
        Bear bear = new Bear();
        bear.catchFish();
        bear.eat();
        Panda panda = new Panda();
        panda.climbTree();
        panda.eat();
    }
}

class Bear extends Animal {
    public Bear() {
        super("白色", 4);
    }
    @Override
    public void eat(){
        System.out.println("北极熊吃蜂蜜");
    }
    public void catchFish(){
        System.out.println("北极熊会抓鱼");
    }
}
class Panda extends Animal{
    public Panda() {
        super("白色", 4);
    }
    @Override
    public void eat(){
        System.out.println("熊猫吃竹子");
    }
    public void climbTree(){
        System.out.println("熊猫会爬树");
    }
}

练习题4

测试类

package com.itheima.exercises;

import com.itheima.exercises.domain.Buyer;
import com.itheima.exercises.domain.Lecturer;
import com.itheima.exercises.domain.Maintainer;
import com.itheima.exercises.domain.Tutor;

/**
 * 在传智播客有很多员工(Employee),
 * 按照工作内容不同分教研部员工(Teacher)和行政部员工(AdminStaff)
 * 教研部根据教学的方式不同又分为讲师(Lecturer)和助教(Tutor)
 * 行政部根据负责事项不同,
 * 有分为维护专员(Maintainer),采购专员(Buyer)
 * 公司的每一个员工都编号,姓名和其负责的工作
 * 工作内容:
 *   讲师: 工号为 666 的讲师 乔峰 在讲课
 *   助教: 工号为 668的助教 段誉 在帮助学生解决问题
 *   维护专员: 工号为 686 的维护专员 柳岩 在解决不能共享屏幕问题
 *   采购专员: 工号为 888 的采购专员 景甜 在采购音响设备
 *
 * 提示:赋值可以用set方法或者构造方法
 */
public class Exercise04 {
    public static void main(String[] args) {
        Lecturer lecturer = new Lecturer(666,"乔峰");
        lecturer.work();
        Tutor tutor = new Tutor(668, "段誉");
        tutor.work();
        Maintainer maintainer = new Maintainer(686, "柳岩");
        maintainer.work();
        Buyer buyer = new Buyer(888, "景甜");
        buyer.work();
    }
}

Employee类

package com.itheima.exercises.domain;

public class Employee {
    private int num;
    private String name;
    public void work(){}

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Employee(int num, String name) {
        this.num = num;
        this.name = name;
    }

    public Employee() {
    }
}

Teacher类

package com.itheima.exercises.domain;

public class Teacher extends Employee {
    public Teacher(int num, String name) {
        super(num, name);
    }

    public Teacher() {
    }
}

Lecturer类

package com.itheima.exercises.domain;

public class Lecturer extends Teacher {
    public Lecturer(int num, String name) {
        super(num, name);
    }

    public Lecturer() {
    }

    @Override
    public void work(){
        System.out.println("工号为"+this.getNum()+"的讲师"+this.getName()+"在讲课");
    }
}

Tutor类

package com.itheima.exercises.domain;

public class Tutor extends AdminStaff {
    public Tutor(int num, String name) {
        super(num, name);
    }

    public Tutor() {
    }

    @Override
    public void work(){
        System.out.println("工号为"+this.getNum()+"的助教"+this.getName()+"在帮助学生解决问题");
    }
}

AdminStaff类

package com.itheima.exercises.domain;

public class AdminStaff extends Employee {
    public AdminStaff(int num, String name) {
        super(num, name);
    }

    public AdminStaff() {
    }
}

Maintainer类

package com.itheima.exercises.domain;

public class Maintainer extends AdminStaff {
    public Maintainer(int num, String name) {
        super(num, name);
    }

    public Maintainer() {
    }

    @Override
    public void work(){
        System.out.println("工号为"+this.getNum()+"的维护专员"+this.getName()+"在解决不能共享屏幕问题");
    }
}

Buyer类

package com.itheima.exercises.domain;

public class Buyer extends AdminStaff {
    public Buyer(int num, String name) {
        super(num, name);
    }

    public Buyer() {
    }

    @Override
    public void work(){
        System.out.println("工号为"+this.getNum()+"的采购员"+this.getName()+"在采购音响设备");
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值