Java

[Java]重学Java-初学面向对象与对象初始化

2021-04-11  本文已影响0人  AbstractCulture

面向对象是什么?

在前面的章节中,我们设计程序总是趋向于设计过程来解决问题,更加准确的来说,通过"算法+数据结构"来设计程序。如果是求解一个简单的问题,这样做是完全没有问题的。但是现实生活中,人们的需求总是变化莫测,所以需要一种复用性更强的方式来设计程序,这个时候,OOP(Object-oriented programming)则以面向对象方式闪亮登场了。
OOP其实不是Java语言的专属,在其他语言上,你也可以看到面向对象的影子,例如:C#TypeScriptC++等都是经典的面向对象编程语言。
在面向对象的世界里面,程序都是一个个对象组成的,通过对象间的消息传递来完成作业。

对象到底是什么?

这个一个很大的课题,这里简单讲讲一些基本的概念.

面向对象的三大基本原则

封装

封装的概念比较容易理解,先以一个生活的例子作为举例:
一台电视机,内部可能有很多复杂的设计结构和硬件设备,那么直接让用户去操作这些内部的零件可能会造成很大的困扰,于是厂商就提供了一系列的按钮、遥控器来让用户更好地操作电视机。
这其实就是一个封装的过程,内部细节对用户屏蔽,用户只需要知道,通过这个"按钮"我可以达成怎样的效果即可。这在程序中的体现则是:调用一个工具类的方法,我需要输入什么,它会给我输出什么.

继承

继承是为了更好地扩展与复用,通过继承可以直接得所扩展的类的所有能力(通常称为父类),如此一来可以避免重复性的工作;同时,继承也意味这这组对象拥有部分相同的特征,那么它们的"类型"也是一致的.

例如,在Java中,你会常常看到这样的写法.

User person = new Person();

Java只支持单继承.

多态

多态的方式可以有很多种不同的呈现:

这里引用《Java编程思想》中的一句话:发送消息给对象时,如果程序不知道接收的具体类型是什么,但最终执行是正确的,这就是对象的“多态性”(Polymorphism)。面向对象的程序设计语言是通过“动态绑定”的方式来实现对象的多态性的。

类之间的关系

public class User{
    /**
     * 角色列表
     */
    private List<Role> roles;
}

什么是Java对象?

谈起Java中的对象,不得不提起类.要生产一个对象,首先得描述一个模板,就像工厂里面,我们想造一个手机壳,那么我们首先得设计一个模具,再根据这个模具加工出手机壳。
类与对象之间的关系也是如此:
类中可以描述一个对象的特征:例如field(成员变量)constructor构造器method方法class-类型.
程序中可以通过new关键字来触发构造器,进而获取一个对象,通过调用方法,可以改变对象的状态.

new与构造器

使用new关键字来生产一个对象,在new的过程中,会自动触发构造器方法.
其中,对于构造方法的概述为:

  1. 构造器方法与类名一致.
  2. 一个类可以声明多个构造器方法.
  3. 构造器方法支持多态性.
  4. 构造器方法不需要声明返回值.
  5. 搭配修饰符可以控制构造器方法的使用范围.

口说无凭,我们通过代码进行讲解:

package com.tea.modules.model;

public class User 
    /**
     * 用户名称
     */
    private String userName;
    /**
     * 密码
     */
    private String password;
    /**
     * 这是一个构造器方法
     */
    public User(){
        System.out.println("一个User对象被创建出来了");
    }
}
User user = new User();
new

我们这里验证了一个问题,使用new去生产对象实例的时候,会自动触发构造器方法,这个过程也称为初始化.

错误示范

User user;
System.out.println(user.toString());

无参构造器

定义Java类的时候,如果你不需要自定义创建对象的过程,你完全可以不写构造器方法,编译器会为你自动创建一个无参的构造器.
如果显式声明了构造器,那么编译器便不会为你创建构造器了.

static

被static修饰的方法代表静态方法,它不归属于对象,而是类.
在类中定义static初始化方法,往往只会执行一次,因为加载出类(对象的模板)之后,就可以直接根据模板来生产对象了,也就是说,要得到一个User对象,必须先加载出一个User.class.

static方法无法通过this关键字进行调用,需要使用"类名.方法"的方式进行调用.

// 静态方法
Math.pow(1, 2);

new的时候,底层做了什么事情?

为了更好的了解这个问题,我们将User类的age属性声明为int(当然实际开发中不提倡这样做),这里为了重写toString方法,我使用了lombok进行自动生成.

package com.tea.modules.model;
import lombok.Data;


@Data
public class User {
    private String userName;
    private String password;
    private int age;
    
    static {
        System.out.println("我是一个静态方法,我是类加载的时候就会发生的事件");
    }
    
    {
        System.out.println("我是一个初始化时执行的方法,我比构造器的优先级要高");
    }
    
    public User(){
        System.out.println("一个User对象被创建出来了");
    }
}
package com.tea.modules.java8.oop;

import com.tea.modules.model.User;

/**
 * 理解面向对象思想-对象的构造器与初始化
 * @author jaymin
 * @since 2021/4/10 16:15
 */
public class OOPDemo {

    public static void main(String[] args) {
        User user = new User();
        System.out.println(user.toString());
    }
}
result 编译后的指令
  1. 我们知道,要生产对象就需要找到类,我们定义的java类最终会编译为一个.class文件,JVM首先要将这个文件加载到内存中,得到一个User.class对象.
  2. 执行被static修饰的代码块.
  3. 执行new关键字的相关操作,为当前对象分配内存空间.
  4. 对对象中的所有字段设置为零值(引用类型置为null,基础类型置为默认值,比如int的默认值为0).
  5. 执行代码块,即在字段定义处的初始化动作.
  6. 执行构造器(constructor)方法.
  7. 你获得了一个对象的引用.
pic

深入浅出new关键字

「JVM」 - 对象初始化

上一篇下一篇

猜你喜欢

热点阅读