『JavaSE』类和对象

面向对象和面向过程

我们知道Java是面向对象的编程语言,而C语言是面向过程的编程语言,那什么是面向对象,什么是面向过程呢?

  • C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题;面向过程注重的是过程,在整个过程中所涉及的行为,就是功能
  • Java是面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成;面向对象注重的是对象,也就是参与过程所涉及到的主体,是通过逻辑将一个个功能实现连接起来

我们来看两个例子更好的理解面向过程和面向对象

  • 蛋炒饭和盖浇饭的例子,我们可以将制作蛋炒饭的过程理解成面向过程的,在制作蛋炒饭的过程中,我们需要关注的是每一步该放什么,先炒鸡蛋,在放饭,调料等,出锅的时候加上葱花;而盖浇饭的制作就可以理解成是面向对象的,每一道菜都是一个对象,米饭也是一个对象,想吃什么就往米饭上加什么就可以了。
  • 再来一个高大上的例子来理解面向过程和面向对象。编年体史书和纪传体史书。我们可以将编年体通史理解成是面向过程的,它以年为顺序,记录每一年发生的大事,比如说《春秋》;而纪传体史书就可以理解成是面向对象的,纪传体史书针对具体的人物书写史书,比如说《史记》。

面向对象的特性

  • 最重要的三大特性封装、继承、多态
  • 其他特性抽象、组合、反射等

什么是类和对象?

对于类和对象的理解,我们可以借助C语言中的结构体。

  • 我们知道C语言中的结构体是自定制类型,而类可以理解成高配的结构体,因为结构体中只包含属性,而类中不仅包含属性还包含方法
  • 现在我们知道类是一种自定制类型,那对象就比较好理解了,对象就是根据类这个自定制类型创建的变量对象的创建过程,我们称之为类的实例化
  • 类的实例化过程,我们可以通过一个例子来加深理解,我们可以将类看做一幅建筑图纸,而对象就是根据这个图纸盖出的房子

下面看一个类和对象实例化的代码示例

public class Test {
    public static void main(String[] args) {
        Student student = new Student("sss", 24, "male");
        System.out.println(student.toString());
    }
}

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

    // 构造方法
    public Student(String name, int age, String gender)  {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "Student{" + this.name
                + ", " + this.age
                + ", " + this.gender
                + "};";
    }
}

运行结果如下
在这里插入图片描述


我们对上述代码简单分析一下

  • Student类中,name、age、gender称为类的属性,也叫字段、成员变量toString、Student称为类的方法,也叫成员函数
  • new Student("sss", 24, "male");就是对类进行实例化,即创建一个对象;而Student student创建一个对象的引用
  • 注意:Student()是一个特殊的方法,称为构造方法,方法名和类名相同,构造方法在类的实例化时会被自动调用,构造方法没有返回值,用于对象的初始化
    每一个类中一定至少有一个构造方法(没有明确定义,则系统会自动生成一个无参构造(若类中定义了构造方法,则默认的无参构造将不再生成)),构造方法支持重载,规则和普通方法一样构造方法之间可以相互调用
    在这里插入图片描述
  • this是当前对象的引用this的出现是因为对象的方法和属性是分开存储的,因为所有对象的方法都是一致的,只有属性不同,所以在类的实例化中,不会新开辟内存空间来存储方法,只会为属性开辟空间。因此如果一个对象调用方法时,方法为了区分是哪个对象,就引入了this关键字来表示当前调用对象的引用
  • @Override(注解)表示对父类toString方法的重写,Java中有一个特殊的类Object是所有类的祖宗,Java中其他所有的类都直接或间接继承自Object类,而toString是Object的方法toString会在println的时候自动调用,例如:System.out.println(student.toString());System.out.println(student);效果是一样的
    我们将对象转为字符串这样的操作称为序列化

下面我们来看一段代码,画一下其中其中变量的内存分布

public class Test {
    public static void main(String[] args) {
        Student student1 = new Student("fzy", 24, "male");
        System.out.println(student1);
        Student student2 = new Student("lyx", 18, "female");
        System.out.println(student2);
    }
}

class Student {
    private String name;
    private int age;
    private String gender;
    private final int holidays = 2;
    public static String nature = "people";
    public static final int tuition = 8000;

    // 构造方法
    public Student(String name, int age, String gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "Student{name: " + this.name
                + ", age: " + this.age
                + ", gender: " + this.gender
                + ", holidays: " + this.holidays
                + ", nature: " + nature
                + ", tuition: " + tuition
                + "};";
    }
}

在这里插入图片描述


static关键字

C语言中,我们知道static关键字有三个作用

  • 修饰局部变量,修改局部变量生命周期为程序整个运行期间
  • 修饰全局变量,修改全局变量的链接属性,将全局变量的作用域限制在当前.c文件
  • 修饰函数,修改函数的链接属性,将函数的作用域限制在当前.c文件

Java中static关键字的作用和C语言中截然不同,下面来具体看一下:

  • 修饰属性:表示该属性为类属性(静态属性),和对象无关,不论实例化出多少个对象,类属性只有一份。可以通过类.属性来访问,也可以通过对象.属性来访问。
    静态属性在普通方法、构造代码块、静态方法和静态代码块中都可以访问普通属性只能在普通方法和构造代码块中访问
  • 修饰方法:表示该方法为类方法(静态方法),与对象无关,静态方法中不能使用this(当前对象的引用)和super(当前对象父类对象的引用)
    可以直接调用静态方法而无需实例化对象静态方法可以访问静态属性,并可以修改静态属性静态方法不能直接使用非静态属性和调用非静态方法
  • 修饰代码块静态代码块,用于初始化静态属性,静态代码块不管实例化出多少个对象,都只会执行一次,且是最先执行
    静态代码块执行完毕后,再执行普通代码中内容,最后执行构造方法
  • 修饰内部类被static修饰的内部类可以直接作为一个普通类来使用,而不需实例一个外部类

代码块

什么是代码块
代码块就是使用{}定义的一段代码,根据代码块定义的位置以及关键字,可以分为以下四种

  • 普通代码块定义在方法中的代码块
public class Test {
    public static void main(String[] args) {
        // 普通代码块
        {
            System.out.println("这是一个普通代码块!");
        }
    }
}

在这里插入图片描述

  • 构造代码块(实例代码块):定义在类中的代码块,构造代码块一般用于对象的初始化构造代码块先于构造函数执行构造方法可以传参和重载,更加灵活。相比之下,构造代码块只能做规定的初始化
public class Test {
    public static void main(String[] args) {
        // 普通代码块
        {
            System.out.println("这是一个普通代码块!");
        }

        Student student = new Student("sss", 24, "male");
        System.out.println(student);
    }
}

class Student {
    private String name;
    private int age;
    private String gender;
    public static String nature = "people";

    // 构造代码块
    {
        this.name = "hello, world!";
        System.out.println("这是一个构造代码块!");
    }

    // 构造方法
    public Student(String name, int age, String gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
        System.out.println("这是一个构造方法!");
    }

    @Override
    public String toString() {
        return "Student{" + this.name
                + ", " + this.age
                + ", " + this.gender
                + "};";
    }
}

在这里插入图片描述

  • 静态代码块使用static修饰的构造代码块,用于初始化静态成员属性,先于构造代码块执行,无论生成多少个对象,静态代码块只执行一次。
public class Test {
    public static void main(String[] args) {
        // 普通代码块
        {
            System.out.println("这是一个普通代码块!");
        }

        Student student1 = new Student("sss", 24, "male");
        System.out.println(student1);
        Student student2 = new Student("hehe", 18, "female");
        System.out.println(student2);
    }
}

class Student {
    private String name;
    private int age;
    private String gender;
    public static String nature = "people";

    // 静态代码块
    static {
        nature = "hello, world!";
        System.out.println("这是一个静态代码块!");
    }

    // 构造代码块
    {
        this.name = "hello, world!";
        System.out.println("这是一个构造代码块!");
    }

    // 构造方法
    public Student(String name, int age, String gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
        System.out.println("这是一个构造方法!");
    }

    @Override
    public String toString() {
        return "Student{" + this.name
                + ", " + this.age
                + ", " + this.gender
                + "};";
    }
}

在这里插入图片描述

  • 同步代码块

匿名对象

  • 没有引用的对象称为匿名对象
  • 匿名对象只能在创建对象时使用
  • 如果一个对象只使用一次,后面就不需要了,可以考虑使用匿名对象

代码演示

public class Test {
    public static void main(String[] args) {
        new Student("sss", 24).show();
    }
}

class Student {
    private String name;
    private int age;

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

    public void show() {
        System.out.println("name: " + this.name
            + ", age: " + this.age);
    }
}

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值