class是一种自定义的引用数据类型。

1. 定义类

java代码映射成现实事物的过程就是定义类的过程。

  1. public class 类名{
  2. 属性定义
  3. 修饰符 数据类型 变量名 =
  4. 方法定义
  5. 修饰符 返回值类型 方法名(参数列表){
  6. }
  7. }

2. 使用类

实现引用类型的步骤

  • 1: 导入包 , 类都是在同一个文件夹,不需要导入包
  • 2: 创建引用类型的变量
  • 3: 变量.方法

    1. // 1:导包
    2. import com.henry.Phone;
    3. public class TestPhone{
    4. public static void main(String[] args){
    5. // 2: 创建引用类型的变量
    6. Phone p = new Phone();
    7. System.out.println(p); //输出内存的地址
    8. //3: 变量.类型中的功能
    9. //变量 p.的方式,调用类中的属性
    10. //属性就是变量 , 赋值和获取值
    11. p.color = "土豪金";
    12. p.brand = "爱立信";
    13. p.size = 5.0;
    14. //获取属性值
    15. System.out.println(p.color+" "+p.brand+" "+p.size);
    16. }
    17. }

    3. Attribute 成员变量

    成员变量和局部变量的区别

  • 区别一:定义的位置不同

    • 定义在类中的变量是成员变量
    • 定义在方法中或者{}语句里面的变量是局部变量
  • 区别二:在内存中的位置不同
    • 成员变量存储在heap中
    • 局部变量存储在stack中
  • 区别三:声明周期不同
    • 成员变量随着对象的出现而出现在堆中,随着对象的消失而从堆中消失
    • 局部变量随着方法的运行而出现在栈中,随着方法的弹栈而消失
  • 区别四:初始化不同

    • 成员变量因为在堆内存中,有默认的初始化值
    • 局部变量没有默认的初始化值,必须手动的给其赋值才可以使用。

      4. Constructor 构造函数

      A. 构造方法的特点:

  • 构造方法没有返回值类型。也不需要写返回值。因为它是为创建对象的,对象创建完,方法就执行结束。

  • 构造方法名称必须和类型保持一致。
  • 每一class类都必须有一个构造方法,构造方法不写也有。编译的时候,javac,系统会自动检查类中是否有构造方法,如果没有编译器就会自动添加一个构造方法

    1. class Person {
    2. // Person的成员属性age和name
    3. private int age;
    4. private String name;
    5. // Person的构造方法,拥有参数列表
    6. Person(int a, String nm) {
    7. // 接受到创建对象时传递进来的值,将值赋给成员属性
    8. age = a;
    9. name = nm;
    10. }
    11. }

    B. 构造方法的内存加载过程

    有一个Person类,创建Person 对象new Person()
    1、首先会将main方法压入栈中,执行main方法中的 new Person(23,”张三”);
    2、在堆内存中分配一片区域,用来存放创建的Person对象,这片内存区域会有属于自己的内存地址(0x88)。然后给成员变量进行默认初始化(name=null,age=0)。
    3、执行构造方法中的代码(age = a ; name = nm;),将变量a对应的23赋值给age,将变量nm对应的”张三赋值给name,这段代码执行结束后,成员变量age和name的值已经改变。执行结束之后构造方法弹栈,Person对象创建完成。将Person对象的内存地址0x88赋值给p2。

    C. 构造方法的重载

    1、一个类中可以有多个构造方法,多个构造方法是以重载的形式存在的
    2、构造方法是可以被private修饰的,作用:其他程序无法创建该类的对象。

    1. //让一个类不能被实例化
    2. class Person {
    3. private int age;
    4. private String name;
    5. // 私有无参数的构造方法,即外界不能通过new Person();语句创建本类对象
    6. private Person() {
    7. }
    8. }

    D. 构造方法和一般方法区别

  1. 格式不同: 构造方法没有返回值,一般方法必须有返回值。
  2. 作用不同:构造方法在对象创建时就执行了,而且只执行一次。一般方法是在对象创建后,需要使用时才被对象调用,并可以被多次调用。
  3. 调用方式不同:构造方法new对象时调用, 或者this() super() 语句调用。普通方法需要对象调用或者直接用类调用静态方法。

    E. this在构造方法之间的调用

  • 构造方法之间的调用,可以通过this关键字来完成。
  • 构造方法调用格式:this(参数列表);

    1. class Person {
    2. private int age;
    3. private String name;
    4. private Person(String name) {
    5. this.name = name;
    6. }
    7. public Person(String name, int age) {
    8. this(name);
    9. this.age = age;
    10. }
    11. }

    F. super在构造方法之间的调用

    子类的构造方法必须调用父类的构造方法且必须在第一句就调用super()。 即子类在初始化时,必须先到父类中去执行父类的初始化动作。这样,才可以使用父类中的内容。
    构造方法第一行,写this()还是super()?this() 是调用本类的构造方法,super()是调用父类的构造方法, 且两条语句不能同时存在。无论如何,子类的所有构造方法,直接或间接必须调用到父类构造方法;

    1. class Student extends Person {
    2. String id;
    3. public Student(String name, int age, String id){
    4. super(name, age);
    5. this.id = id;
    6. }
    7. }

    5. final

    final是个修饰符,它可以用来修饰类,类的成员,以及局部变量。

  • 修饰类:final修饰类不可以被继承,但是可以继承其他类。

  • 修饰方法: final修饰的方法不可以被覆盖,但子类可以调用。
  • 修饰局部变量:
    1. 修饰基本类型变量:final修饰的变量称为常量,这些变量只能赋值一次。
    2. 修饰应用类型变量:引用类型的变量值为对象地址值,地址值不能更改,但是地址内的对象属性值可以修改。
  • 修饰成员变量:需要在创建对象前赋值,否则报错。当没有显式赋值时,多个构造方法的均需要为其赋值。

    1. class Demo {
    2. //直接赋值
    3. final int m = 100;
    4. //final修饰的成员变量,需要在创建对象前赋值,否则报错。
    5. final int n;
    6. public Demo(){
    7. //可以在创建对象时所调用的构造方法中,为变量n赋值
    8. n = 2016;
    9. }
    10. }

    6. static

    对于一个Student类,每个student都有一个共同的属性— schoolName。如果让每个实例都单独分配一块空间去存储相同的内容,那么会造成极大的内存浪费。因此,如果一个类所有实例都可以共享一个属性值,那么上面的问题也就迎刃而解了。 此时,static的概念就被引入。

    A. 特点

  • 被static修饰的成员变量属于类,不属于这个类的某个对象。

  • 被static修饰的成员可以并且建议通过类名直接访问。
  • 被static修饰的method只能调用 static method 和 static attribute
  • 由于上面原因,static method中不能使用this关键字。

    B. static的内存

  1. 静态变量,静态方法,静态块等都是类级别的属性,而不是单纯的对象属性。他们在类第一次被使用时被加载(记住,是一次使用,不一定是实例化
  2. 当一个对象初始化时总是先加载自己的静态成员.

image.png

C. static的使用场景:

  • 一般我们把共性数据定义为static属性
  • 如果静态方法中引用到了静态的其他成员,那么这个方法需要声明为static方法
  • 如果一个方法不会操作类中的任何成员,那么这个方法应该被声明为static方法

    D. static 在多态中调用

    在多态调用中,我们必须弄清楚编译看谁,运行看谁

  • 对于方法,编译都看 = 左边的父类, 父类有成员变量或方法则编译成功,没有则失败。
    运行: 静态方法看父类中的静态方法。非静态方法看子类的重写方法

  • 对于所有成员变量,编译运行全看父类。

    7. Anonymous Object

    匿名对象是指创建对象时,只有创建对象的语句,却没有把对象地址值赋值给某个变量。

    1. public class Person{
    2. public void eat(){
    3. System.out.println();
    4. }
    5. public static Person getPerson(){
    6. return new Person(); //匿名对象作为方法返回值
    7. }
    8. public static void main(String[] args){
    9. new Person().eat();
    10. }
    11. }