• Java类和对象(二)


    作者:爱塔居的博客_CSDN博客-领域博主

    专栏:JavaSE

    🍓🍓🍓🍓🍓

    今天也要好好学习呀~冲!


    前言

    面对对象程序三大特性:封装、继承、多态。

    一、封装

    在类和对象阶段,主要研究的就是封装特性。

    1.1 封装的概念

    封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互,简单来说就是套壳屏蔽细节。

    比如:我们的电脑,真正工作的是CPU、显卡、内存等。而对于计算机使用者来说,不用关心内部核心不见,不用关心主板线路布局,CPU内部设计等,所以计算机厂商在出厂时在外部套上壳,只提供开关机、键盘插件、鼠标等,让用户可以与计算机进行交互。所以,我们所能看到的是:

    1.2 访问限定符

    🍧🍧Java中主要通过类和访问权限来实现封装:类可以将数据以及封装数据的方法结合在一起,更符合人类对事物的认知。而访问权限用来控制方法或者字段能否直接在类外使用。

    学完访问限定符,我们就能解决之前的一个困惑啦~什么时候要加public?

    什么时候要加什么访问修饰符,为什么要加访问修饰符,这种问题就可以迎刃而解了! 

    范围

    private

    默认权限

    protected

    public

    1

    同一包中的同一类

    2

    同一包中的不同类

    3

    不同包中的子类

    4

    不同包中的非子类

    【说明】

    1、protected主要是用在继承中

    2、默认权限指的是什么都不写的情况

    3、访问权限除了可以限定类中的成员可见性,也可以控制类的可见性

    4、一般情况下成员变量设置为private,成员方法设置为public

    1.3 软件包

    1.3.1 包的概念

    🌳🌳软件包:为了更好地管理类,把多个类收集在一起成为一组。包是对类、接口等的封装机制的体现,是一种对类或者接口等的很好的组织方式。而且,在同一个工程中允许存在相同名称的类,只要处于不同的包即可。

    1.3.2 导入包中的类

    java中已经提供了很多现成的类供我使用,例如Date类:可以使用java.util.Date导入java.util这个包中的Date类。

    1. public class Test {
    2. public static void main(String[] args) {
    3. java.util.Date date=new java.util.Date();
    4. System.out.println(date.getTime());
    5. }
    6. }

     不过,直接用import语句导入包的写法会比较简便一些,效果是一样的在。

    1. import java.util.Date;
    2. public class Test {
    3. public static void main(String[] args) {
    4. Date date=new Date();
    5. System.out.println(date.getTime());
    6. }
    7. }

    如果需要使用java.util中的其他类,可以使用import java.util.*

    1. import java.util.*;
    2. public class Test {
    3. public static void main(String[] args) {
    4. Date date=new Date();
    5. Scanner scanner=new Scanner(System.in);
    6. int a=scanner.nextInt();
    7. System.out.println(date.getTime());
    8. }
    9. }

    比如这个代码中,我们需要用到Date类和Scanner类,这两个类都是java,util中的类。所以,用import java.util.*; 就可以啦。不过,还是更建议指定要导入的类名,否则还是容易出现冲突的情况。

    1. import java.util.*;
    2. import java.sql.*;
    3. public class Test {
    4. public static void main(String[] args) {
    5. // util 和 sql 中都存在一个 Date 这样的类, 此时就会出现歧义, 编译出错
    6. Date date = new Date();
    7. System.out.println(date.getTime());
    8. }
    9. }

    编译错误: 

     1.3.3 自定义包

    🌹基本规则:

    1.在文件的最上方加上一个package语句指定该代码在哪个包中

    2.包名需要尽量指定成唯一的名字,通常会用公司的域名的颠倒形式

    3.包名要和代码路径相匹配,例如创建com.baidu.www的包,那么会存在一个对象的路径com/baidu/www来存储代码

    4.如果一个类没有package语句,则该类被放在一个默认包中

    src相当于是java中默认的包。

    🍓🍓操作步骤

    在src处右键,找到NEW(第一行),选择Package选项,在弹出的对话框中输入包名回车即可。

    如果回车后,是一行,那么也很正常。

     

    勾选 Tree Appearance,点击Compact Middle Packages即可 。

    新建一个类

     说明当前类在哪个包底下。

    1.3.4 常见的包

    1. java.lang: 系统常用基础类 (String Object), 此包从 JDK1.1 后自动导入。
    2. java.lang.reflflect:java 反射编程包 ;
    3. java.net: 进行网络编程开发包。
    4. java.sql: 进行数据库开发的支持包。
    5. java.util: java 提供的工具程序包。
    6. java.io:I/O 编程开发包。

    二、static成员

    在java中,被static修饰的成员,称之为金泰成员,也可以称为类成员,其不属于某个具体的对象,是所有对象所共享的。

    2.1 static修饰成员变量

    🍹🍹成员变量分为:

    1.静态成员变量/类变量或者类成员

    2.非静态成员变量/普通成员变量

    static修饰的成员变量称为静态成员变量。静态成员变量最大的特性:不属于某个具体的对象,是所有对象共享的。

    🌺【静态成员变量特性】

    1.不属于某个具体的对象,是类的属性,所有对象共享的,不存储在某个对象的空间中。

    1. class Student{
    2. public String name;
    3. public int age;
    4. String classroom="1班";
    5. public void show(){
    6. System.out.println(name+" "+age+" "+classroom);
    7. }
    8. public Student(String name, int age) {
    9. this.name = name;
    10. this.age = age;
    11. }
    12. }
    13. public class Test {
    14. public static void main(String[] args) {
    15. Student student1=new Student("张三",12);
    16. Student student2=new Student("张三",12);
    17. Student student3=new Student("张三",12);
    18. System.out.println();
    19. }
    20. }

     

    在代码19行处取断点,Debug运行一下是这个样子的。

     然后,我们把刚才的代码改一下,把我们的班级改成静态成员变量:

    1. class Student{
    2. public String name;
    3. public int age;
    4. static String classroom="1班";
    5. public void show(){
    6. System.out.println(name+" "+age+" "+classroom);
    7. }
    8. public Student(String name, int age) {
    9. this.name = name;
    10. this.age = age;
    11. }
    12. }
    13. public class Test {
    14. public static void main(String[] args) {
    15. Student student1=new Student("张三",12);
    16. Student student2=new Student("张三",12);
    17. Student student3=new Student("张三",12);
    18. System.out.println();
    19. }
    20. }

    Debug的结果是这个样子: 可以看出,静态成员变量并没有存储到某个具体的对象中。静态成员变量存在方法区中。

    2.既可以通过对象访问,也可以通过类名访问,但一般更加推荐使用类名访问。

    这是通过对象访问:

    1. class Student{
    2. public String name;
    3. public int age;
    4. static String classroom="1班";
    5. public void show(){
    6. System.out.println(name+" "+age+" "+classroom);
    7. }
    8. public Student(String name, int age) {
    9. this.name = name;
    10. this.age = age;
    11. }
    12. }
    13. public class Test {
    14. public static void main(String[] args) {
    15. Student student1=new Student("张三",12);
    16. Student student2=new Student("张三",12);
    17. Student student3=new Student("张三",12);
    18. System.out.println(student1.classroom);
    19. }
    20. }

    输出结果:

     通过对象访问,编译器是不报错的,只是会有警告。而且,我们会发现当我们写代码的时候,不会主动跳出classroom。因为,我们上面说过,静态变量不在对象里面。

     下面是通过类名访问:

    1. class Student{
    2. public String name;
    3. public int age;
    4. static String classroom="1班";
    5. public void show(){
    6. System.out.println(name+" "+age+" "+classroom);
    7. }
    8. public Student(String name, int age) {
    9. this.name = name;
    10. this.age = age;
    11. }
    12. }
    13. public class Test {
    14. public static void main(String[] args) {
    15. Student student1=new Student("张三",12);
    16. Student student2=new Student("张三",12);
    17. Student student3=new Student("张三",12);
    18. System.out.println(Student.classroom);
    19. }
    20. }

    输出结果一样:

     3.类变量存储在方法区中

    4.生命周期伴随类的一生。随类的加载而创建,随类的卸载而销毁 

    2.2 static修饰成员方法

    🍏🍏成员方法分为:

    1.静态成员方法/类方法

    2.非静态成员方法

    一般类中的数据成员都设置为private,而成员方法设置为public。

    Java中,被static修饰的成员方法称为静态成员方法,是类的方法,不是某个对象所特有的。静态成员一般是通过静态方法来访问的。

    1. public class Student{
    2. // ...
    3. private static String classRoom = "Bit306";
    4. // ...
    5. public static String getClassRoom(){
    6. return classRoom;
    7. }
    8. }
    9. public class TestStudent {
    10. public static void main(String[] args) {
    11. System.out.println(Student.getClassRoom());
    12. }
    13. }

    【静态方法特性】

    1.不属于某个具体的对象,是类方法

    2.可以通过对象调用,也可以通过类名,静态方法名(...)方式调用,更推荐后者

    3.不能在静态方法中访问任何非静态成员变量。

    4.静态方法中不能调用任何非静态成员变量,因为非静态方法有this参数,在静态方法中调用时候无法传递this引用。

    2.3 static成员变量初始化

    静态成员变量一般不会放在构造方法中初始化。构造方法中初始化的是与对象相关的实例属性。

    静态成员变量的初始化分为两种:就地初始化和静态代码块初始化。

    三、代码块

    3.1 代码块概念以及分类

    使用{}定义的一段代码称为代码块。

    根据代码块定义的位置以及关键字,又可分为以下四种:

    1.普通代码块
    2.构造块
    3.静态块
    4.同步代码块

    3.2 普通代码块

    普通代码块:定义在方法中的代码块

    1. class Student{
    2. public static void main(String[] args) {
    3. {
    4. int a=10;
    5. System.out.println(a);
    6. }
    7. int a=100;
    8. System.out.println(a);
    9. }
    10. }

    输出:

    这种方法很少见。 

    3.3 构造代码块

    构造块:定义在类中的代码块(不加修饰符),也叫实例代码块。构造代码块一般用于初始化实例成员变量

    1. public class Student{
    2. //实例成员变量
    3. private String name;
    4. private String gender;
    5. private int age;
    6. private double score;
    7. public Student() {
    8. System.out.println("I am Student init()!");
    9. }
    10. //实例代码块
    11. {
    12. this.name = "bit";
    13. this.age = 12;
    14. this.sex = "man";
    15. System.out.println("I am instance init()!");
    16. }
    17. public void show(){
    18. System.out.println("name: "+name+" age: "+age+" sex: "+sex);
    19. }
    20. }
    21. public class Main {
    22. public static void main(String[] args) {
    23. Student stu = new Student();
    24. stu.show();
    25. }
    26. }

     3.4 静态代码块

    使用 static 定义的代码块称为静态代码块。 一般用于初始化静态成员变量。
    1. public class Student{
    2. private String name;
    3. private String gender;
    4. private int age;
    5. private double score;
    6. private static String classRoom;
    7. //实例代码块
    8. {
    9. this.name = "bit";
    10. this.age = 12;
    11. this.gender = "man";
    12. System.out.println("I am instance init()!");
    13. }
    14. // 静态代码块
    15. static {
    16. classRoom = "bit306";
    17. System.out.println("I am static init()!");
    18. }
    19. public Student(){
    20. System.out.println("I am Student init()!");
    21. }
    22. public static void main(String[] args) {
    23. Student s1 = new Student();
    24. Student s2 = new Student();
    25. }
    26. }

    🍓🍓🍓

    注意:

    1.静态代码块不管生成多少个对象,其只会执行一次

    2.静态成员变量是类的属性,因此是在JVM加载类时开辟空间并初始化的。

    3.如果一个类中包含多个静态代码块,在编译代码时,编译器会按照定义的先后次序依次执行

    4.实例代码块只有在创建对象时才会执行

    总结

  • 相关阅读:
    运算符重载
    python使用execjs利用jsdom来执行含有document的js代码方案(上)
    OpenMP的调度-以泊松方程求解为例子
    第六章 :Spring Boot web开发常用注解(一)
    C++ Reference: Standard C++ Library reference: C Library: cmath: asin
    CF803B Distances to Zero(模拟+思维)
    基于pion生态的SFU实时音视频发布服务(二)
    FreeRTOS的学习(二)——队列的介绍和操作
    Java基于微信小程序的青少年健康心理科普平台
    C语言·对文件的输入输出(万字详解)
  • 原文地址:https://blog.csdn.net/m0_65683419/article/details/127814368