java面向对象

面向对象的开发,设计,特征

  1. 面向对象的开发:就是不断的创建对象,使用对象,指挥对象做事情
    面向对象的设计:就是设计与管理对象之间的关系
    面向对象的特征:封装、继承、多态

  2. 封装

    在开发项目的时候,需要不断的去声明类,在类中需要去封装属性和行为,但是针对于某一些属性,我们需要将它保护起来,不希望外界可以直接的访问,所以将这些属性用private关键字修饰,private代表的是私有的访问权限修饰符。这些属性只能在本类中直接访问,不能在其他类之外进行直接访问。

  3. getter、setter

    类的属性值为private的时候,在外部类要调用或者修改这些属性值,则需要通过调用对应的get和set函数来修改属性值。

内存分配

  1. 栈内存、堆内存、方法区内存

    • 定义在类中的实例变量一定是在堆内存中开辟的空间,因为new出来的部分一定存在于堆内存中。
    • 在JVM内存中,所有的方法,无论是静态方法还是普通方法(实例方法),都是在栈中分配内存空间。
    • 方法区内存中一般存放的是代码片段(java源文件编译之后的字节码文件),即各种用到的类的.class字节码文件。同时还有一个常量池,用于存放字符串数据。

    • 局部变量和实例变量的区别:局部变量是存在于方法体内部的变量(包含参数),局部变量如果是基本数据类型,则直接在栈中开辟空间,如果是引用数据类型,变量声明部分在栈中,实例创建部分在堆中,如果是实例变量,所有的内存都会在堆中开辟。
    int[] ints=new int[10];
    ints[0]=1;
    ints[1]=2;
    User user1=new User();
    
    
    • 数组类型是引用数据类型,会先在栈内存中开辟一个变量声明的内存空间,存放变量名及映射到堆内存的地址,然后在堆内存中进行实例创建空间的分配。后续的赋值则在分配的堆内存空间内进行划分。User用户类也是引用数据类型,先在栈内存中开辟user1的内存,并赋值为地址。然后在堆内存中会为user1开辟一个内存空间,用于存放user1的属性,比如userName,userAddress等。
    • Student student=new Student();在内存中做了哪些事情
      加载Student.class文件进内存;
      在栈内存为student开辟空间;
      在堆内存为学生对象开辟空间;
      根据构造方法初始化;
      通过构造方法对学生对象的成员变量赋值;
      学生对象初始化完毕,把对象地址赋值给student变量;
  2. 案例

  • 通过String类来说明不同变量在内存中的分配问题
/**
 * 通过==,如果比较的是基本数据类型,则比较的是值,如果比较的是引用数据类型,则比较的是内存地址值
 */

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

        //"hello world"存在方法区中的常量池中 所以str声明在栈内存中,值为“hello world”在方法区中的地址值
        String str="hello world";
        //str1声明部分在栈内存中 存放的是堆内存中的内存地址,同时堆内存又因参数 所以还会指向方法区内存中的常量池中"hello world"地址
        String str1=new String("hello world");
        String str2="hello world";
        String str3=new String("hello world");
        System.out.println(str==str1);//false

        System.out.println(str==str2);//true 因为"hello world“都是位于常量池的同一个地址

        System.out.println(str1==str3);//false
    }
}

static关键字

  1. 静态关键字 static:

    可以修饰方法,属性,不能修饰类,被静态关键字static修饰的属性和方法,会成为类级别的元素,会随着类的加载而加载,JVM在加载字节码文件的时候,也会加载被static修饰的元素。
    静态变量内存是在方法区中的,而静态方法内存是在栈内存中。因为所有方法的内存都是分配在栈内存中。
    写在方法体内的变量是局部变量,没法加static形成类级别,static只能修饰实例变量成为静态变量,静态变量会随着类的加载而加载,在JVM解析字节码文件的时候,该变量的内存空间就会被开辟出来,静态变量的内存空间会被开辟在方法区内中。
    成员变量:实例变量、静态变量
    局部变量:方法体内的变量(包括参数中的变量)

  2. 静态代码块:

    在类加载的时候将会被执行的语句体,而且只加载一次,如果第二次解析这个类,将不会被加载,并且会在主函数执行之前执行。

public static void main(String[] args) {

    System.out.println("main 执行了!");

}
static {
    System.out.println("static 执行了!");
}

​ 输出结果:

static 执行了!
main 执行了!

静态变量与成员变量的区别

  • 所属不同

    静态变量属于类,也称为类变量;

    成员变量属于对象,也称为实例变量;

  • 内存中位置不同

    静态变量存储在方法区中的静态区

    成员变量存储在堆内存中

  • 内存出现时间不同

    静态变量随着类的加载而加载,随着类的消失而消失

    成员变量随着对象的创建而存在,随着对象的消失而消失

  • 调用不同
    静态变量可以通过类名调用,也可以通过对象调用

    成员变量只能通过对象名调用

toString()方法

当一个类并没有继承任何特定的一个父类的时候,该类会继承一个object类(所有类的父类)可以点击object查看源码中的toString方法:

public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

所以当我们每次System.out.println(类名)的时候,会输出当前类名+@+哈希值。eg:

User@4554617c

如果我们重写了toString方法,那么当我们再次System.out.println(类名)的时候,
就会出现toString重写方法里面输出形式.

User{userName='张三', idCard='123'}
posted @ 2021-07-17 23:45  ins1mnia  阅读(30)  评论(0编辑  收藏  举报