admin 管理员组

文章数量: 1184232

一.什么是面向对象

1. 概念

现在来说-java语言的核心就是面向对象,这个可能行业干很久了,才能具体体会。

为什么要面向对象?什么是对象?我们要明白

1.1 面向对象:

在 Java 中,面向对象(Object-Oriented Programming,简称 OOP) 是一种编程思想,它将现实世界中的事物抽象为对象,通过对象之间的交互来实现程序功能。其核心是将数据(属性)和操作数据的方法(行为)封装在一起,强调 “以对象为中心” 思考问题。

1.2 而Java 面向对象的四大核心特性(粗略):

  1. 封装(Encapsulation)
    将对象的属性(数据)和方法(操作)捆绑在一起,通过访问修饰符(如 privatepublic)控制外部对内部数据的访问,仅暴露必要的接口。
    例如:一个 Person 类封装了姓名(name)和年龄(age),外部只能通过 setName()getAge() 等方法操作这些属性,避免直接修改导致的数据混乱。

  2. 继承(Inheritance)
    允许一个类(子类)继承另一个类(父类)的属性和方法,实现代码复用和扩展。子类可以新增自己的特性或重写父类方法。
    例如:Student 类可以继承 Person 类,复用 name 等属性,同时新增 studentId 等特有属性。

  3. 多态(Polymorphism)
    同一行为(方法)在不同对象上有不同的实现方式。通过父类引用指向子类对象,调用方法时会动态绑定到实际对象的实现。
    例如:Animal 类有 sound() 方法,Dog 和 Cat 子类分别重写为 “汪汪” 和 “喵喵”,调用时会根据实际对象类型执行对应逻辑。

  4. 抽象(Abstraction)
    忽略次要细节,提炼核心特征,通过抽象类(abstract class)或接口(interface)定义规范,不关注具体实现。
    例如:Shape 接口定义 getArea() 方法,具体由 CircleRectangle 等类实现各自的计算逻辑。

2.面向对象编程步骤:


1.设计类
     类:描述某一类事务或人的数据和行为,抽象的,例如:学生类或教室类,就是抽象的,没有说明具体是哪一位学生
   语法:

public class 类名{

数据或行为

//行为就是方法,数据就是变量

}
2.创建对象,也叫实例化对象
    对象:是具体对象事务或人,例如:张三同学,220教室,非常具体
    语法:类  对象名 = new 类();
3.使用对象,存储数据和执行行为
    数据使用: 对象名.变量名
    行为使用: 对象名.方法名([参数])

案例1:

设计一个学生类(自定义类 一般用来定义对象的属性和方法 这里是属性定义):

Demo测试(测试类,引用自定义类的数据类型的时候要确认引用的类的目录路径正确例如Scanner和Random都在util包里面): 首先new一个对象 然后赋值给对象的属性 再调用对象的属性 已经把数据存储到对象了我们会发现

案例2

定义自定义类(这里定义属性和方法):

public class Student {
    String name; //储存名字
    int Chinese;//储存语文成绩
     int Math;//存储数学成绩


    public void getSum(){
        int sum = Chinese+Math;
        System.out.println(name+"总成绩为:"+sum);
    }
    public  void Average(){
        int sum = Chinese+Math;
        System.out.println(name+"平均成绩为:"+sum/2);
    }
}

定义测试类(调用方法:对象名+方法名):

package 面相对象基础案例;
//        new 一个对象 new 的是Student类


//目标:请用面向对象编程的方式,存储如下两个学生的信息,并要求打印出每个学生的总成绩和平均成绩
//面向对象编程步骤:
// 1.设计类
//      类:描述某一类事务或人的数据和行为,抽象的,例如:学生类或教室类,就是抽象的,没有说明具体是哪一位学生
//      语法:public class 类名{ 数据或行为,行为就是方法,数据就是变量}
// 2.创建对象,也叫实例化对象
//      对象:是具体对象事务或人,例如:张三同学,220教室,非常具体
//      语法:类  对象名 = new 类();
// 3.使用对象,存储数据和执行行为
//      数据使用: 对象名.变量名
//      行为使用: 对象名.方法名([参数])
public class Demo01 {
    public static void main(String[] args) {
        Student s1 = new Student();

        s1.name = "科比";
        s1.Chinese = 59;
        s1.Math = 59;

//        创建第二个对象
        Student s2 = new Student();
        s2.name = "詹姆斯";
        s2.Chinese = 1;
        s2.Math = 1;

        System.out.println(s1.name+"语文成绩是"+s1.Chinese+"\t数学成绩是"+s1.Math);
        System.out.println(s2.name+"语文成绩是"+s2.Chinese+"\t数学成绩是"+s2.Math);

        s1.getSum();
        s1.Average();
        s2.getSum();
        s2.Average();
    }
}

运行结果:

2.1 类和对象的关系:

Java 作为纯面向对象语言,一切皆对象(除基本数据类型外,可通过包装类转为对象),类是对象的模板,对象是类的实例。这种思想让代码更贴近现实世界,提高了可维护性和复用性。

而这些对象即各个事件的参与者,将这些对象抽取出“像”的部分、“共同”的部分,就形成了类。

在图中有一个类:人类。这个类有一些特性和行为,都具备年龄、性别、身高、体重等特性,都具备奔跑、学习、睡觉、思考等行为。这个类可以当作一个模板,模板下具体的产物就是一个个满足这些特性和行为的对象。图中的每个人,都是人类的一个具体的对象。

在编写程序时,一般先编写类,再根据类去创建对象。

  • 对象:具体的事物,具体的实体,具体的实例,模板下具体的产品,每件产品都满足这个模板规定的特性和行为。
  • :对对象向上抽取出“像”的部分,共同特性的部分,形成类,类是抽象的,是一个模板。

2.2. 类的定义和使用练习

在java中基本的单位就是:类

把现实生活中的事物抽象为java中的类==>根据类创建对象==>调用对象的功能帮助我们完成事情

把事物的属性定义为类中的成员变量,把事物的行为定义为类中的成员方法

成员变量:把变量定义在类中,方法的外边

成员方法:定义一个方法,去掉static关键字

1.定义一个“手机(Phone)”类,有以下成员:

成员属性(成员变量):品牌(String brand)、颜色(String color)、价格(double price)、屏幕大小(double screenSize)

成员方法:打电话(call)

输出:使用xx品牌,xx颜色,xx价格,xx屏幕大小的手机打电话!

发短信(sendMsg)

输出:使用xx品牌,xx颜色,xx价格,xx屏幕大小的手机发短信!

定义测试类Demo02Phone,创建两个手机对象,并存储两部手机信息,分别调用打电话和发短信的方法

package com.itheima.demo02test;

public class Phone {
    //品牌(String brand)
    String brand;
    //颜色(String color)
    String color;
    //价格(double price)
    double price;
    //屏幕大小(double screenSize)
    double screenSize;

    //打电话(call)
    public void call(){
        System.out.println("使用"+brand+"品牌,"+color+"颜色,"+price+"价格,"+screenSize+"屏幕大小的手机打电话!");
    }

    //发短信(sendMsg)
    public void sendMsg(){
        System.out.println("使用"+brand+"品牌,"+color+"颜色,"+price+"价格,"+screenSize+"屏幕大小的手机发短信!");
    }
}

 3. 对象的内存图

4. 成员变量和局部变量区别 

在类中的位置不同 重点
  成员变量:类中,方法外
 局部变量:方法中或者方法声明上(形式参数)
 作用范围不一样 重点
 成员变量:类中
 局部变量:方法中
 初始化值的不同 重点
 成员变量:有默认值
 局部变量:没有默认值。必须先定义,赋值,最后使用
 在内存中的位置不同 了解
 成员变量:堆内存
 局部变量:栈内存
 生命周期不同 了解
 成员变量:随着对象的创建而存在,随着对象的消失而消失
 局部变量:随着方法的调用而存在,随着方法的调用完毕而消失

定义一个有参Varible类
 ​  

package com.itheima.demo03variable;

public class Variable {
    //成员变量:类中,方法外 a s
    int a;
    String s;

    //局部变量:方法中或者方法声明上(形式参数) b c i
    public void show(int b){
        int c;
        for (int i = 0; i < 3; i++) {
            System.out.println(i);
        }

        //成员变量:有默认值,可以直接使用
        System.out.println("a:"+a);//a:0
        System.out.println("s:"+s);//s:null

        //局部变量:没有默认值。必须先定义,赋值,最后使用
        //System.out.println(c);//Variable 'c' might not have been initialized 变量c没有被初始化
        c = 100;
        System.out.println("c:"+c);
        System.out.println("b:"+b);
    }

    public void show02(){
        //成员变量:类中的所有的方法中都可以使用
        System.out.println("a:"+a);//a:0
        System.out.println("s:"+s);//s:null

        //局部变量:方法中(定义变量的方法中有效)
        //System.out.println(b);//Cannot resolve symbol 'b'
        //System.out.println(w);//Cannot resolve symbol 'w'
    }
}

这是我上课的教学图:

这里讲一下 当方法跑完了之后 方法和局部变量(如果没有其他方法还在调用)的内存空间的占用会被jvm的虚拟机垃圾回收机制回收掉,也就是栈内存,堆内存,方法区的关于这个方法的局部变量和文件都会销毁掉

 

5.封装


5.1封装概述


封装:私有成员变量,对外提供公共的get/set方法


封装:
生活中:攒一台电脑==>买很多配件(cpu,主板,硬盘,风扇,内存条,显卡,电源...)==>组装到一起
电脑裸奔==>不安全==>洒水了,进灰尘...
买一个机箱,把所有的零件装在机箱中==>安全==>封装
java中:让用户直接访问成员变量==>不安全==>随便赋值
s.age = -18; 不报错,但是生活中年龄不能为负数
解决:使用封装思想解决
java中封装的概念:私有成员变量,对外提供公共的get/set方法


1.私有成员变量:可以使用关键字private(私有)
private关键字可以用于修饰成员变量和成员方法,不能修饰局部变量
被private关键字修饰的成员变量和成员方法,只能在本类中使用,其他类不能使用


2.对外提供公共的get/set方法:供其他类使用私有的成员
set(设置)方法:用于给私有成员变量赋值
get(获取)方法:用于获取私有成员变量的值
封装的好处:提高代码的安全性,不让用户直接访问成员变量,通过方法访问(在方法中增加一些限制)


5.2封装代码实现

封装类(Bean)
 

package com.itheima.demo04fengzhuang;

/**
    封装
 */
public class Student {
    private String name;
    private int age;

    // set(设置)方法:用于给私有成员变量赋值
    public void setAge(int a){
        // 增加一个判断,判断年龄是否合法
        if(a<=0 || a>120){
            // System.out.println("年龄非法");
            age = 18;
        }else{
            age = a;
        }
    }

    // get(获取)方法:用于获取私有成员变量的值
    public int getAge(){
        return age;
    }

    public void setName(String s){
        name = s;
    }
    public String getName(){
        return name;
    }

    // 私有的成员,只能在本类(Student)中使用
    public void show(){
        System.out.println(name);
        System.out.println(age);
    }
}

 测试类:

package com.itheima.demo04fengzhuang;

/**
 * @Author: byj
 * @Date: 2025/7/23 - 07 - 23 - 11:33
 * @Description: com.itheima.demo04fengzhuang
 * @version: 1.0
 */
public class Demo01Student {
    public static void main(String[] args) {
        Student s = new Student();
        //s.name = "小美"; // 'name' has private access in 'com.itheima.demo04fengzhuang.Student'
        //s.age = -18;// 'age' has private access in 'com.itheima.demo04fengzhuang.Student'
        //System.out.println(s.name+" "+s.age);

        // 使用set方法,给私有成员变量赋值
        s.setName("小美");
        s.setAge(-18);

        // 使用get方法,获取成员变量的值
        System.out.println(s.getName()+" "+s.getAge());

        s.setAge(20);
        System.out.println(s.getName()+" "+s.getAge());
    }
}

5.3. 封装练习

1.定义一个猫Cat类

成员变量:姓名(name),年龄(age),种类(kind)

要求:使用封装的思想定义Cat类

私有成员变量(3个)

对外提供公共的get/set方法(6个)

package 面相对象基础案例;

public class Cat {
//    1.定义一个猫Cat类
//成员变量:姓名(name),年龄(age),种类(kind)
    private String name;
    private int  age;
    private   String kind;

    public Cat() {

    }
//要求:使用封装的思想定义Cat类
//私有成员变量(3个)
//对外提供公共的get/set方法(6个)

    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;
    }

    public String getKind() {
        return kind;
    }

    public void setKind(String kind) {
        this.kind = kind;
    }

    public Cat(String name, int age, String kind) {
        this.name = name;
        this.age = age;
        this.kind = kind;
        System.out.println(this.name);
        System.out.println(this.age);
        System.out.println(this.kind);
    }
    public void Print(String name, int age, String kind){
        this.name = name;
        this.age = age;
        this.kind = kind;
        System.out.println("名字:\t"+this.name);
        System.out.println("年龄:\t"+this.age);
        System.out.println("种类:\t"+this.kind);
    }
}

2.定义测试类:包含main方法类 Demo01Cat

public class Demo04Cat {
    public static void main(String[] args) {
////姓名: 肥波
////年龄: 5
////种类: 加菲猫
        Cat cat = new Cat();
        cat.Print("肥波",5,"加菲猫");
    }
}

在类中创建Cat对象

使用setXXX方法给私有成员变量赋值:没有返回值,有参数

使用getXXX方法获取私有成员变量的值:有返回值,没有参数

---------------------------------------------------

程序执行结果:

姓名: 肥波

年龄: 5

种类: 加菲猫

5.4. this关键字

this关键字

this:这个

问题:当局部变量和成员变量重名时,局部变量会隐藏成员变量的值

解决:使用this.变量名=>代表访问的当前类中的成员变量

----------------------------------------------------------

this代表当前对象的引用(引用:引用的就是对象在堆内存中的地址值)

哪个对象调用的方法,方法中的this就是哪个对象

package com.itheima.demo05this;

public class Animal {
    private String name;

    public void show(){
        System.out.println(this);
        String name = "旺财";
        System.out.println("变量的就近访问原则:"+name); // 旺财
        System.out.println("this.name:"+this.name); // 小强
    }

    public String getName() {
        return name;
    }

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

 
1.this.变量名:表示成员变量(具体对象)
2.this表示当前对象的引用(引用堆内存中对象的地址值)
 那个对象调用的方法,方法中this就是那个对象

 

package com.itheima.demo05this;

/**
 * @Author: byj
 * @Date: 2025/7/23 - 07 - 23 - 14:47
 * @Description: com.itheima.demo05this
 * @version: 1.0
 */
public class Demo01This {
    public static void main(String[] args) {
        Animal a = new Animal();
        System.out.println(a);// com.itheima.demo05this.Animal@3b07d329
        a.setName("小强");
        a.show();

        Animal a2 = new Animal();
        System.out.println(a2);// com.itheima.demo05this.Animal@3d075dc0
        a2.setName("熊大");
        a2.show();
    }
}

5.5. 使用快捷键添加get/set方法(重点)

使用快捷键生成get/set方法(重点)

alt+insert(ins)==>选择Getter and Setter==>ctrl+A(选择所有的成员变量)==>回车(点击OK)

fn+alt+insert(ins)==>选择Getter and Setter==>ctrl+A(选择所有的成员变量)==>回车(点击OK)

鼠标右键点击空白地方==>选择Generate==>选择Getter and Setter==>ctrl+A(选择所有的成员变量)==>回车(点击OK)

package com.itheima.demo06student;

public class Student {
    //私有成员变量
    private String name;
    private int age;
    private String sex;

    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;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }
}

package com.itheima.demo06student;

public class Demo01Student {
    public static void main(String[] args) {
        //定义Student类型的变量,创建Student对象为变量赋值
        Student s = new Student();
        s.setName("王心凌");
        s.setAge(18);
        s.setSex("女");
        //\t==>制表符(tab)
        System.out.println(s.getName()+"\t"+s.getAge()+"\t"+s.getSex());
    }
}

6. 构造器(构造方法)

6.1. 构造器概述

构造器: 创建对象,就是调用类中的构造器完成

格式:

修饰符 方法名(参数){

给成员变量赋值(省略)

}

空参数构造器:

public Student(){ }

带参数构造器:

public Student(String name,int age){

this.name = name;

this.age = age;

}

格式说明:

1.构造器没有返回值类型,不是void,是根本就没有这个字段

2.构造器也没有返回值

3.构造器的名字,必须和类名相同(一模一样)

构造器的作用:

1.在创建对象时初始化对象的状态(给成员变量赋初始化值)

2.带参构造器,可以给成员变量赋指定值(相当于set方法)

构造器的注意事项:

1.如果类中没有明确写出构造器,那么JVM会为类增加一个默认的构造器

格式:public Student(){}

2.如果类中有明确写出构造器,那么JVM就不会为类增加默认的构造器

如果想使用空参数构造器,必须手动写出

3.构造器可以重载(在一个类中,出现了方法名相同,但是参数列表不同(个数,类型,顺序)的方法)

 

比如:

package com.itheima.demo06constructor;

public class Student {
    private String name;
    private int age;

    // 给Student类,添加空参数的构造器
    public Student(){
        System.out.println("Student类的空参数构造器!");
    }

    // 给Student类,添加给name赋值的构造器
    public Student(String name){
        this.name = name;
    }

    // 给Student类,添加给age赋值的构造器
    public Student(int age){
        this.age = age;
    }

    // 给Student类,添加同时给name和age赋值的构造器(满参数构造器)
    public Student(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;
    }
}
package com.itheima.demo06constructor;

public class Demo01Constructor {
    public static void main(String[] args) {
       // 使用Student类的空参数构造器创建对象
       Student s1 = new Student();
       System.out.println(s1.getName()+"\t"+s1.getAge());

        // 使用Student类给name赋值的构造器创建对象
        Student s2 = new Student("关晓彤");
        System.out.println(s2.getName()+"\t"+s2.getAge());

        // 使用Student类给age赋值的构造器创建对象
        Student s3 = new Student(18);
        System.out.println(s3.getName()+"\t"+s3.getAge());

        // 使用同时给name和age赋值的构造器
        Student s4 = new Student("鹿晗",18);
        System.out.println(s4.getName()+"\t"+s4.getAge());
    }
}

6.2. JavaBean(重点)

JavaBean 是 Java语言编写类的一种标准规范。

符合JavaBean 的类,要求必须是公共的,并且具有无参数的构造器,提供用来操作成员变量的set 和get 方法。

添加get|set方法快捷键

alt+insert(ins)==>选择Getter and Setter==>ctrl+A(选择所有的成员变量)==>回车(点击OK)

添加空参数构造器快捷键

alt+insert(ins)==>选择Constructor==>什么变量的不选择==>回车(点击OK)

添加满参数构造器快捷键

alt+insert(ins)==>选择Constructor==>ctrl+A(选择所有的成员变量)==>回车(点击OK)

 

package com.itheima.demo08javabean;

public class Student {
    //1.1私有成员变量
    private String name;
    private int age;

    //2.给类添加空参数和满参数构造器
    public Student() {
    }

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

    /*public Student(String name) {
        this.name = name;
    }

    public Student(int age) {
        this.age = age;
    }*/

    //1.2对外提供公共的get/set方法
    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;
    }
}

测试类:

package com.itheima.demo08javabean;

public class Demo01Student {
    public static void main(String[] args) {
        //使用空参数构造器创建Student对象
        Student s1 = new Student();
        //使用get方法获取成员变量的值
        System.out.println(s1.getName()+"\t"+s1.getAge());//null    0
        //使用set方法给成员变量赋值
        s1.setName("颜如玉");
        s1.setAge(18);
        //使用get方法获取成员变量的值
        System.out.println(s1.getName()+"\t"+s1.getAge());//颜如玉 18

        //使用满参数构造器创建Student对象
        Student s2 = new Student("黄金屋",18);
        //使用get方法获取成员变量的值
        System.out.println(s2.getName()+"\t"+s2.getAge());//黄金屋 18
        //问题:有满参数构造器,set方法还有用吗? 有用
        //使用set方法修改成员变量的值
        s2.setAge(20);
        //使用get方法获取成员变量的值
        System.out.println(s2.getName()+"\t"+s2.getAge());//黄金屋 20
    }
}

7. lombok优化JavaBean实体类

7.1. 下载lombok(我用的是jdk-17没有lombok)

将这个jar包放一个固定位置

7.2. 项目关联这个jar包

7.3. 代码中使用lombok注解

目标:使用lombok实现JavaBean实体类

使用步骤:

1.导入lombok.jar包

2.idea软件安装lombok插件(小辣椒),idea2021版本后自带安装了这个插件

3.使用注解实现javaBean实体类功能(@Data/@NoArgsConstructor/@AllArgsConstructor

4.第一次运行程序带有lombok,会提示扫描注解lombok,点击确认

或者:

settings->Build->Compiler->Annotation Processing-> Default ->Enable annotation processing 勾选

alt+7 可以查看类的结构,所有成员

注意:@AllArgsConstructor 这个注解使用前提必须有成员变量,否则就多生成了无参构造器

lombok常用注解

@Getter和@Setter

作用:生成成员变量的get和set方法。

写在成员变量上,指对当前成员变量有效。

写在类上,对所有成员变量有效。

注意:静态成员变量无效。

@ToString:

作用:生成toString()方法。

该注解只能写在类上。

@NoArgsConstructor和@AllArgsConstructor

@NoArgsConstructor:无参数构造方法。

@AllArgsConstructor:满参数构造方法。

注解只能写在类上。

@EqualsAndHashCode

作用:生成hashCode()和equals()方法。

注解只能写在类上。

@Data

作用: 生成setter/getter、equals、canEqual、hashCode、toString方法

如为final属性,则不会为该属性生成setter方法。

注解只能写在类上。

注意: @Data不会给类添加构造方法(只有默认空参数构造方法)

案例:

package com.itheima.demo08lombok;


import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
    private String name;
    private int age;
    private String sex;

    // 我们自己写了setAge方法,那么lombok就不会再生成setAge
    public void setAge(int age) {
        if(age<0 || age>120){
            this.age = 18;
        }else{
            this.age = age;
        }
    }
}

如果是idea2021以下需要手动安装lombok插件

测试类

package com.itheima.demo07javabean;

/**
 * @Author: byj
 * @Date: 2025/7/23 - 07 - 23 - 15:48
 * @Description: com.itheima.demo07javabean
 * @version: 1.0
 */
public class Demo01Javabean {
    public static void main(String[] args) {
        // 使用空参数构造器创建对象
        Student s1 = new Student();
        // 使用set方法给成员变量赋值
        s1.setName("黄金屋");
        s1.setAge(18);
        // 使用get方法获取成员变量的值
        System.out.println(s1.getName()+"\t"+s1.getAge());

        // 使用满参数构造器创建对象
        Student s2 = new Student("颜如玉", 18);// 黄金屋	18
        // 使用get方法获取成员变量的值
        System.out.println(s2.getName()+"\t"+s2.getAge());// 颜如玉	18
        // 使用set方法,修改变量的值
        s2.setAge(20);
        System.out.println(s2.getName()+"\t"+s2.getAge());// 颜如玉	20
    }
}

运行后查看编译后的代码

8. static关键字

8.1. static关键字的概述

static修饰的成员在静态区中,被所有的对象所共享使用

8.2. static:修饰成员变量 

bean类:

package com.itheima._07static修饰成员变量;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;


@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {

 
    static String teachName;


    private String name;
    private int chinese;
    private int math;
}

   静态变量、类变量:全局只有一份
   调用语法方式1: 类名.静态变量名(推荐的)
   调用语法方式2: 对象名.静态变量名

   实例变量、对象变量:有多少个对象就有多少份
   调用语法: 对象名.实例变量名

package com.itheima._07static修饰成员变量;

/**
 * @Description Demo071
 * @Author byj
 * @Date 2025-05-22  17:48
 */
public class Demo071 {

    public static void main(String[] args) {
        //目标:证明实例变量有多份和静态变量全局一份

        //设置静态变量全局共享(所有对象共享)
        Student.teachName = "军哥";

        //创建第一个对象:小明
        Student s1 = new Student("小明", 99, 100);

        //创建第一个对象:小王
        Student s2 = new Student("小王", 66, 77);

        //输出数据:实例变量的数据不同,静态变量的数据相同
        System.out.println(s1.getName()+":语文成绩="+s1.getChinese()+",数学成绩="+s1.getMath()+",老师="+s1.teachName);
        System.out.println(s2.getName()+":语文成绩="+s2.getChinese()+",数学成绩="+s2.getMath()+",老师="+s2.teachName);

    }
}

8.3. static:静态变量内存结构

静态成员优先于非静态成员加载到内存中

 

 8.4. static修饰成员变量案例:统计在线人数

User:

package com.itheima.demo09static;

/**
    static修饰成员变量案例:统计在线人数
    每创建一个User对象,让统计人数+1
    count = 0;
    new User(); count++
    new User(); count++
    new User(); count++
 */
public class User {
    // 每个用户的姓名不同,定义为非静态成员
    String name;
    // 每个用户使用的统计变量,都是同一个,定义为静态成员
    static int count;

    public User(String name) {
        this.name = name;
        count++;
    }
}

 测试类:

package com.itheima.demo09static;

/**
 * @Author: byj
 * @Date: 2025/7/23 - 07 - 23 - 17:17
 * @Description: com.itheima.demo09static
 * @version: 1.0
 */
public class Demo02Count {
    public static void main(String[] args) {
        User u1 = new User("jack");
        User u2 = new User("rose");
        User u3 = new User("tom");
        User u4 = new User("jerry");
        System.out.println("统计直播间的在线人数: "+User.count);// 统计直播间的在线人数: 4
        new User("jerry");
        new User("jerry");
        System.out.println("统计直播间的在线人数: "+User.count);// 统计直播间的在线人数: 6
    }
}

8.5. static:修饰方法

bean类:
 

package com.itheima._08static修饰方法;

public class Student {

    //实例方法
    public void printHello(){
        System.out.println("实例方法");
    }

    //静态方法
    //   属于类的,只有一份
    //   调用语法:类名.方法名()  推荐方式
    //   调用语法:对象名.方法名()  不推荐
    public static void printStatic(){
        System.out.println("静态方法");
    }
}

测试类:
 

package com.itheima._08static修饰方法;

public class Demo081 {
    public static void main(String[] args) {

        //1.调用实例方法
        //创建对象
        Student s1 = new Student();
        //之后才能调用实例方法
        s1.printHello();

        //2.调用静态方法
        //直接调用
        Student.printStatic();
        //Student.printHello(); 报错,实例方法不可以通过类名调用,不属于类
    }
}

8.6. static:静态方法应用场景工具类方法

生成验证码工具类方法

CodeUtil

public class CodeUtil {

    //工具类构造器私有外部无法创建对象,节省内存
    private CodeUtil(){}

    /**
     * 生成验证码工具方法
     * @param num :验证码的长度
     * @return
     */
    public static String getCode(int num){

        // 1.定义一个char类型的数组,并进行静态初始化赋值
        char[] chars = {
                '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
                'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
                'u', 'v', 'w', 'x', 'y', 'z',
                'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
                'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
                'U', 'V', 'W', 'X', 'Y', 'Z'
        };
        //System.out.println(chars.length);// 62
        // 2.定义一个String类型的变量,初始值为"",记录验证码
        String code = "";
        // 3.定义一个for循环,循环num次
        for (int i = 0; i < num; i++) {
            // 4.在循环中,获取数组索引范围内的一个随机数[0-61]  nextInt(62)  (int)(Math.random()*arr.length) [0-61]
            int index = (int)(Math.random()*chars.length);
            // 5.根据索引,获取数组中指定的元素,赋值给String变量
            code+=chars[index];
        }
        return code;
    }
}

测试类:

package com.itheima._08static修饰方法;

public class Demo082 {

    public static void main(String[] args) {
        //CodeUtil codeUtil = new CodeUtil();

        //生成6位登录验证码
        String code1 = CodeUtil.getCode(6);

        //生成7位注册验证码
        String code2 = CodeUtil.getCode(7);
    }
}

8.7. static:注意事项

再次注意:静态成员优先于非静态成员加载到内存中

1.静态方法里面只能调用静态变量和方法,不能直接调用实例变量和方法

2.实例方法里面既可以调用静态变量和方法,也可以调用实例变量和方法

3.只有实例方法里面可以使用this,静态方法里面不可以使用this

package com.itheima.demo09static;

import com.sun.security.jgss.GSSUtil;


public class Animal {
    // 定义实例变量
    int a = 10;
    // 定义静态变量
    static int b = 20;

    // 定义实例方法
    public void show01(){
        System.out.println("非静态的show01方法!");
        // 2.实例方法里面既可以调用静态变量和方法,也可以调用实例变量和方法
        System.out.println(a);
        System.out.println(b);
        show02();
        method01();
        method02();
        // 3.只有实例方法里面可以使用this,静态方法里面不可以使用this
        // this就是我们创建对象
        System.out.println(this);
    }
    public void show02(){
        System.out.println("非静态的show02方法!");
    }

    // 定义静态方法
    public static void method01(){
        System.out.println("静态的method01方法!");
        // 1.静态方法里面只能调用静态变量和方法,不能直接调用实例变量和方法
        method02();
        System.out.println(b);

        //System.out.println(a);//Non-static field 'a' cannot be referenced from a static context
        //show01();// Non-static method 'show01()' cannot be referenced from a static context'
        
        // 静态方法加载到内存中的,还没有创建对象,this还未诞生
        //System.out.println(this);// 'com.itheima.demo09static.Animal.this' cannot be referenced from a static context
    }
    public static void method02(){
        System.out.println("静态的method02方法!");
    }

}


    静态成员优先于非静态成员加载到内存中
    静态成员随类的加载而加载到静态区中
    非静态的成员,只能创建对象,才会加载到堆内存中
 1.静态方法里面只能调用静态变量和方法,不能直接调用实例变量和方法
 2.实例方法里面既可以调用静态变量和方法,也可以调用实例变量和方法
 3.只有实例方法里面可以使用this,静态方法里面不可以使用this

 

9. 综合案例:电影信息展现 

 Movie:

package com.itheima._10综合案例电影信息展示;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @Description 电影类
 * @Author byj
 * @Date 2025-05-23  14:20
 */
@Data //生成get/set公共的访问方法
@NoArgsConstructor //生成无参构造函数方法
@AllArgsConstructor //生成全参构造函数方法
public class Movie {

    private int id; //电影编号
    private String name;//电影名称
    private double score; //电影评分
    private String director;//导演名称
}

MovieOperator:

package 基础案例.电影院;



import lombok.Data;

import java.util.Scanner;


@Data
public class MovieOperator {

    //   2.定义一个电影操作类MovieOperator
//       a.定义一个静态的数组,数组类型使用Movie
//        private static Movie[] movies = {
//            new Movie(1, "《三傻大闹宝莱坞》", 9.5, "陈凯歌"),
//            new Movie(2, "《哪吒》", 9.2, "饺子"),
//            new Movie(3, "《让子弹飞》", 9.0, "姜文"),
//            new Movie(4, "《九品芝麻官》", 10.0, "周星驰")
//        };


//    b.定义一个静态方法,展示系统中的全部电影信息(遍历数组,打印每一个电影信息)
//           方法定义三要素: 方法名 show  参数列表:()  返回值类型:void
//           1\t\t三傻大闹宝莱坞
//           2\t\哪吒
//           3\t\让子弹飞
//           4\t\九品芝麻官


//
//       c.定义一个静态方法,允许用户根据电影编号(id)查询出某个电影的详细信息打印
//           方法定义三要素: 方法名 find  参数列表:(int id)  返回值类型:void
//            电影编号:1
//            电影名称:三傻大闹宝莱坞
//            电影评分:9.5
//            电影导演:陈凯歌

    private static Movie[] movies = {
            new Movie(1, "三傻大闹宝莱坞", 9.5, "印度"),
            new Movie(2, "肖申克的救赎", 9.7, "美国"),
            new Movie(3, "霸王别姬", 9.6, "中国"),
            new Movie(4, "这个杀手不太冷", 9.4, "法国")
    };
    public static void show(){
        for (int i = 0; i < movies.length; i++) {
            System.out.println(movies[i].getName());
        }
    }



    public static void find(){
        int id;
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入要购买的电影票的id:");
        id = sc.nextInt();
        if(id<1||id>4){
            System.out.println("输入不合法");
        }
        else{

            System.out.print("购买成功!你的票是:\n");
            --id;
            System.out.println("电影编号:"+movies[id].getId());
            System.out.println("电影名称:"+movies[id].getName());
            System.out.println("电影评分:"+movies[id].getScore());
            System.out.println("电影国家:"+movies[id].getPlace());

        }



    }

}

测试类:

package 基础案例.电影院;

import java.util.Scanner;

public class Demo01Movie {

//    简易版电影信息展示系统
//需求
//   展示系统中的全部电影信息(每部电影展示:编号、名称、评分、导演)
//   允许用户根据电影编号(id)查询出某个电影的详细信息。
//目标
//   使用所学的面向对象编程实现以上2个需求。
//需求分析:


//   3.定义测试类
//       a.在测试类中调用show方法,展示系统中的全部电影信息
//       b.定义一个死循环,在死循环中获取用户输入的要查找id
//       对id进行一个合法性判断 if(id<1 || id>4>){ sout("输入的id不合法")}
//       id没有问题,调用find方法,允许用户根据电影编号(id)查询出某个电影的详细信息打印
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        Movie movie = new Movie();
        System.out.println("---------电影院---------");
        System.out.println("输入操作:\n1.查看全部电影\n2.购买电影票\n3.退出");
        int m = sc.nextInt();
        switch (m){
            case 1:MovieOperator.show();
                break;
            case 2:
               MovieOperator.find();
                break;
            case 3:
                break;

        }
    }
}

Movie:定义电影的基本信息结构,是整个系统的数据载体(实体类)。

MovieOperator(操作类):封装对电影数据的操作(展示、查询)

  • 静态数组movies:存储预设的电影数据,static修饰表示这是 “类共享” 的数据,不需要创建对象即可使用,且整个程序中只有一份。

  • 静态方法show():遍历数组,按格式打印所有电影的编号和名称,供用户快速浏览。

  • 静态方法find(int id):通过遍历数组查找指定id的电影,找到则打印详细信息,未找到则提示,避免了直接用id作为数组索引的越界风险。

  • 访问控制:方法用public static修饰,允许外部通过类名直接调用(如MovieOperator.show()),无需创建MovieOperator对象。

测试类:负责与用户交互(接收输入、展示菜单、调用功能)

本文标签: 面向对象 入门 基础 java