【Java学习—(7)类和对象(static静态变量的详细讲解)上 】又是不看后悔的一天

前面的章节知识(点击跳转即可哦)

1 数据类型

2 类型转换

3 运算符

4 逻辑控制

5 输入输出

6 方法的使用

—方法递归

7 数组的定义与使用



8 类和对象 - 上

8.1 类和对象的认识

对象就是真正存在的实体,可以具体到个体上。

在描述对象的时候,发现这些对象具有的一些共同的特征:

  1. 具有相同的属性 (比如都是人,都有五官,都会说话)
  2. 具有相同的行为 (都要吃穿住行)

因此把具有相同属性和行为的一类对象 抽象为类,使用类来描述这类对象的特性。

比如作者我自己DJL,我属于人的这一大类,要想找我肯定是 先是人 -> 再是我DJL


类 —> 抽象的概念,人类,植物,鸟类,就是无法具体到一个 个体

对象 —> 在某个类中的一个实体,真正存在的,当有了对象之后,这些属性就有了属性值,这些行为就有了相应的意义。

在这里插入图片描述


8.2 类和类的对象

类是描述某一对象的统称,对象是这个类的一个实例而已

这一类对象所具备的共同属性和方法都在类中定义

创建类的语法

class 类名称{
    //实例属性,成员属性
    //实例方法,成员方法
}

在Java中,一个源文件(*.Java)只可以存在一个主类,public class


看具体代码:

package ClassesAndObjects;

public class Test {
    public static void main(String[] args) {
        Person per = new Person();
        Person per1 = new Person();
        per.name = "DJL";
        per.age = 18;
        per.sex = "男";
        per.print();
        per1.print();
    }
}
class Person{
    String name;
    String sex;
    int age;
    //等等
    void print(){
        System.out.println("姓名:" + name + ",性别:" + sex + ",年龄:" + age);
    }
}

输出结果:

姓名:DJL,性别:男,年龄:18
姓名:null,性别:null,年龄:0

看到输出的第二行,姓名:null,性别:null,年龄:0,就可以知道成员变量都有默认值,默认值就是这个变量所在的类的默认值。


小结

  1. 类的命名使用有意义的大驼峰单词命名法,从第一个单词开始首字母就大写,多个单词都是首字母大写 。
  2. 类中定义的成员变量都有默认值。

8.3 类的实例化

类相当于一个蓝图,一个范本,是抽象的概念

有了类之后我们就可以根据类来产生一个具体的对象

//类名称 引用名称 = new 类名称();

引用名称是这个对象的引用,

new 类名称() 是对象,在堆中存储

当产生一个类的对象之后,我们就可以使用 ” . “操作符来使用该对象的属性和方法。


看代码:

package ClassesAndObjects;

public class Test {
    public static void main(String[] args) {
        Person per = new Person();
        per.print();
    }
}
class Person{
    String name = "DJL";
    String sex = "男";
    int age = 18;
    void print(){
        System.out.println("姓名:" + name + ",性别:" + sex + ",年龄:" + age);
    }
}

输出结果:

姓名:DJL,性别:男,年龄:18

成员变量可以在类定义时进行赋值,成员变量就地初始化。


8.3.1 关于引用数据类型的特殊值 null

null 在Java 中表示 ”空引用“,只有名字没有保存任何堆内存中的任何地址,如果直接使用值为 null 的引用去使用“ . ”操作符对任何属性和方法(成员变量和成员方法)都会报错。


看代码:

package ClassesAndObjects;

public class Test {
    public static void main(String[] args) {
        Person per = new Person();
        //此时name 的默认值为 null
        System.out.println(per.name.length());
    }
}
class Person{
    String name;
    String sex;
    int age;
    void print(){
        System.out.println("姓名:" + name + ",性别:" + sex + ",年龄:" + age);
    }
}

编译报错:

NullPointerException 代表调用了一个值为null的引用。


总结

类:一组具有相同特征对象的抽象,类中定义了所有该类对象所共同具备的属性和方法。

对象:某个类的一个具体的实体,使用new关键字创建一个对象。

所有类的对象都是引用数据类型,对于引用数据类型来说,默认值为 null。

NullPointerException 表示空指针异常,一定使用了一个值为null的引用去访问成员属性或成员方法了。


8.4 static 关键字

看见static就要想到,和对象无关,静态属性->表示共有的含义。

static的作用有:

  1. 修饰属性,类属性,类变量
  2. 修饰方法,类方法,工具方法
  3. static修饰代码块,静态代码块
  4. static修饰内部类,静态内部类(3和4暂时先不说,后面会补)

8.4.1 static修饰属性

static修饰的属性称为类属性,类变量,所有对象共享。

那为什么要引入这个static变量呢

比如我们在创建一个类中,这个类中有一个成员变量是sex,所有的对象在堆中存储自己的sex属性,当这个类中的很多对象的sex属性都是男性时,那这个属性的值是很多对象所共有的,就可以使用static修饰这个属性,该属性就被称为静态属性


static String sex = "男";

当一个成员变量被static关键字修饰,他就表示类的属性,该类的所有对象共享这个属性,所有对象的属性值大家都一样。

static修饰的属性在JVM的方法区存储,所有该类对象共享此属性。

static修饰的属性与对象无关,直接通过类名称就可以访问,无需通过对象进行访问

调用new Person() 来产生Person的对象,先要有Person类才能产生对象。

首先将Person类加载到内存中,Person中的所有static变量就会被加载到方法区中。

package ClassesAndObjects;

public class Test {
    public static void main(String[] args) {
        System.out.println(Person.sex);
    }
}
class Person{
    String name = "张三";
    int age = 18;
    static String sex = "男";
}

输出结果为:


那么问大家一个问题,在Java中,能否在一个方法的内部定义一个static变量

答案是 不能,在方法中定义的变量都是局部变量,局部变量都是存储在栈中的,static变量存储在方法区,不可能定义一个既在栈中,又在方法区的变量。


final 和 static 有什么区别?

class Person{
    String name = "张三"final int age = 18;   //称为成员常量,都在堆中存储,每个对象在堆中都有这个常量
    static String sex = "男"//静态变量,在方法区存储,类的所有对象共享这个属性
}

final int age = 18;   //称为成员常量,都在堆中存储,每个对象在堆中都有这个常量

age 这个属性,成员常量,在类定义的时候就赋值为 18,不可更改,Person的所有对象都有age属性,值都一样,既然这样的话,就可以把这个属性定义为 static final,存储在方法区,全局唯一。


在类中定义常量,一般都会使用全局常量,static final 共同修饰。

常量的命名规则

所有单词全部大写,多个单词使用下划线分割。

eg: static final String MY_SEX = “男”;


总结

  1. static变量称为 类属性,在方法区存储,该类的所有对象共享此变量
  2. 若在类中定义了常量(定义时赋值),一般我们使用 staticfinal共同修饰,称为全局常量
  3. 要使用类属性,通常直接通过 类名称.属性名称(类属性与对象无关,包括该类的null引用),不推荐使用对象来调用,不规范。

8.4.2 static 修饰方法

static 修饰方法,是静态方法,用于类方法,工具方法

static 修饰的方法也是通过类名称直接方法,没有对象就可以访问。

public static void main(String[] args){}

为什么主方法是个静态方法

主方法是一个程序的入口,如果主方法是成员方法,那他就需要通过对象进行调用,但是程序的入口都没有,对象肯定不会产生。

程序从主方法开始执行,主方法是静态方法,就可以直接调用,无需产生对象。


static : 静态,没有对象就能访问的属性和方法,静态方法没有该类对象就能访问

成员域:成员方法和成员变量必须通过对象来调用,必须得有对象才能访问


a. 在静态方法中只能调用静态方法或者静态属性,static家族之间可以相互调用。不能直接调用成员方法和成员属性,必须通过对象来调用

b. 在成员方法中既可以调用成员方法,也可以调用静态方法(此时已经产生了该类对象,一定是可以访问静态域)。

例如:工具类的方法设计为static方法

Arrays.sort(int[])

Arrays.coppyOf()

都是通过Arrays提供的操作数组的方法,设计为static方法


8.5 封装

面向对象一共有三大特性:封装,继承和多态。

封装:具有保护性和易用性(封装就有很多种表达形式)。private实现属性或方法的封装只是封装的其中一种。

对于银行卡这个类,银行卡的卡号,密码,余额三个属性,如果这三个属性直接暴露在外面,是不合理的,不安全。 所以不能让这些属性可以提供对象直接访问,这就是封装的保护性

再比如对于饮水机这个类,对于饮水机是怎样工作的,流程是什么,对于用户来说,用户是不关注的,只需要一按(方法,方法的内部把饮水机的属性进行调配与运转),就能够出来需要的热水。封装的易用性


在Java中,所谓的权限修饰符,指的就是你修饰的属性,方法,类,可见的范围有多大。

一共有四大访问修饰符,可见的范围从小到大依次为:

private < default < protected < public

  1. private:代表私有的,被private修饰的属性和方法,只在当前类的内部可见,出了类的 { },对外部就完全隐藏了,外部不知道其存在。
  2. default:包访问权限,不需要写这个关键字,什么权限也没有
  3. protected:继承访问权限
  4. public:公共的,公开的。被public修饰的属性和方法,在当前程序中都是可见的,都是可以使用的

看代码:

package ClassesAndObjects;

public class Test {
    public static void main(String[] args) {
        Card card = new Card();
        System.out.println(card.cardNum);
        //card.cardNum此时会报错,因为main存在于 Card类的外部,所以无法访问card.cardNum
    }
}
//被private修饰,表示私有的
class Card{
    private int cardNum = 123456; //卡号
    private double money = 214.4; //余额
    private String passworfd = "123"; //密码
    //在类的内部,private修饰的是可见的
}

那我们想在类的外部去使用这些私有属性,就要使用类提供的getter(取值)和setter(修改值)

对于哪些属性需要提供getter,让外部可见,哪些属性需要提供setter,让外部修改,-都要根据这个属性的特征来决定

看代码:

package ClassesAndObjects;

import java.util.Scanner;

public class Test {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        Card card = new Card();
        System.out.println(card.getCardNum());
        System.out.println(card.getMoney());
        //修改密码
        card.setPassworfd(scanner.nextLine());
        System.out.println(card.getPassworfd());
    }
}

class Card{
    private int cardNum = 123456; //卡号
    private double money = 214.4; //余额
    private String passworfd = "123"; //密码

    public int getCardNum() {
        System.out.println("查看卡号");
        return cardNum;
    }

    public double getMoney() {
        System.out.println("查看余额");
        return money;
    }

    public String getPassworfd() {
        System.out.println("查询密码");
        return passworfd;
    }

    public void setPassworfd(String passworfd) {
        this.passworfd = passworfd;
        System.out.println("修改密码成功");
    }
}

在IDEA实际应用的时候,可以通过 右键 看到 Generate,快捷键是 Alt+insert,来快速生成getter和setter。

那private关键字能否修饰一个外部类?

不能,类定义出来就是要产生对象的,让外部进行使用,private修饰一个类,定义后,外部根本不知道,怎么进行使用


default:包访问权限,不需要写这个关键字,什么权限也没有

关于包访问权限,以后的代码都在一个项目中实现,不可能把所有类都放在一个文件夹下,这个时候就需要“包”,包实际上就是文件夹。

所谓的包访问权限,就是当前文件夹下可见。

创建包时,建议 包命名使用全小写,多个单词下划线分割

package person;  //表示在这个包中

public class Person{   //表示 Person这个类在person这个包中
    public static void main(String[] args){
        
    }
}

包访问权限指的是 权限啥也没写,默认就是包访问权限。

对于包访问权限来说,只有当前包的内部可见(子包,子文件夹都不可见)

包(文件夹)最大的意义在于 不同的包中类可以重名,类的全名称是 包名.类名

person.Person 和 test.Person,这两个类名字可以重复,因为在两个不同的包下。


总结

static 和对象无关,表示一个类的属性和方法

  1. static属性表示共享变量的概念,存放在方法区,所有该类的对象共享此变量,直接使用类名称访问。(也可以通过对象访问,但是不规范)
  2. static方法表示工具方法,直接通过类名称访问,与具体的某个对象无关(Arrays.copyOf等等)
  3. static不能直接修饰一个外部类,会编译出错

静态方法中不能直接调用非静态方法或属性(除非产生对象),但是可以访问静态变量和方法。

成员方法中,既可以调用成员变量或方法,也可以调用静态变量和方法。

private: 当前类的内部可见,出了这个类就无法使用

当一个属性被private封装后,外部使用必须通过该类提供的getter 和 setter方法(其实就是普通的成员方法,只是命名上有规则)


要是对大家有所帮助的话,请帮我点个赞吧。

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值