Java 面向对象基础

目录

  • [1. 面向对象](#1. 面向对象)
  • [2. 类与对象](#2. 类与对象)
  • [3. 面向对象在内存中的执行原理](#3. 面向对象在内存中的执行原理)
  • [4. 类和对象注意事项](#4. 类和对象注意事项)
  • [5. this 关键字](#5. this 关键字)
  • [6. 构造器](#6. 构造器)
    • [6.1 什么是构造器?](#6.1 什么是构造器?)
    • [6.2 构造器作用](#6.2 构造器作用)
    • [6.3 构造器应用场景](#6.3 构造器应用场景)
  • [7. 封装性](#7. 封装性)
    • [7.1 什么是封装?](#7.1 什么是封装?)
    • [7.2 封装的设计规范](#7.2 封装的设计规范)
    • [7.3 封装的书写](#7.3 封装的书写)
  • [8. 实体JavaBean](#8. 实体JavaBean)

正文开始

1. 面向对象

要想了解面向对象,我们首先要了解对象是什么,咱们这里讨论的可不是你的男/女朋友,而是在 Java 语言中非常重要的知识点。

我们真实生活中,有着各种各样的事物,比如一个人、一棵树、一本书等等。我们编程肯定是为了来解决现实中的问题,所以当我们把构成问题的事物数字化,得到的就是它的"对象",对象是为了描述某个事物在解决问题中的行为

面向对象编程,就是把解决一个问题所需要的数据和处理方法交给对象,让对象来处理问题。这样开发更符合人类的思维习惯,使得编程更加简单直观。

2. 类与对象

类是对问题共性的描述,而对象是对问题个性的描述 。可以将类看作是图纸,对象就是根据图纸做出来的实物。

比如一个类描述的是"人",包括了"姓名"、"年龄"、"性别"。而依托于这个类,创建出的一个对象"姓名:wwangxu"、"年龄:20"、"性别:男"。这就是通过"人"这张图纸(类),做出了"姓名为wwangxu"的这个实物(对象)。

类由属性和方法组成:

  • 属性:该事物的特征,比如一个人的年龄、性别等。
  • 方法:该事物的行为,比如吃饭、走路、睡觉等。

类必须依托对象才可以使用,而对象的各种操作都是在类中定义的。可以理解为:没法直接使用图纸来进行图纸中的操作,而必须把事物造出来才能操作,并且造出来的实物的使用方法都是在图纸中指出的。

下面我们来看一下类与对象在程序中的具体实现:

java 复制代码
// 对象的定义格式
类名称 对象名称 = new 类名称();

// 通过对象访问类中的属性
对象名称.属性

//通过对象访问类中的方法
对象名称.方法(实参列表)

我们引入一个具体的例子来学习一下:

Student.java

java 复制代码
//定义类
public class Student{
    //类的属性
    String name;
    int age;

    //类的方法
    public void Judgment()
    {
        if(age >= 18)
        {
            System.out.println("成年了");
        }
        else
        {
            System.out.println("未成年");
        }
    }
}

test.java

java 复制代码
public class test {
    public static void main(String[] args) {
    	//定义对象1
        Student s1 = new Student();
        //通过对象访问类中的属性
        s1.name = "wwangxu";
        s1.age = 19;
        //通过对象访问类中的方法
        s1.Judgment();
        
		//定义对象2
        Student s2 = new Student();
        s2.name = "xiaoming";
        s2.age = 15;
        s2.Judgment();
    }
}

类的定义有以下要求:

  • 类必须编写在后缀为.java的文件中;
  • 一个.java文件中,可以有多个类,但public修饰的类只能有一个;
  • public修饰的类名必须与其对应的.java文件的文件名相同
  • 同一个包中不能有文件名重复的类

3. 面向对象在内存中的执行原理

想要更深入的了解面向对象,我们就需要学习面向对象编程的过程在内存中是如何实现的

部分 java 程序会存储在以下区域中:

  • :存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中。
  • :存放new出来的对象,注意创建出来的对象只包含各自的成员变量,不包括成员方法。
  • 方法区:可以看做是一块独立于Java堆的内存空间,可存储方法。

下面我们根据此图来详细学习(图源黑马程序员课件)

  • 主函数中第一句Student s1 = new Student()原理为:

    • Student s1表示的是在栈内存中,创建了一个Student类型的变量,变量名为s1
    • new Student()会在堆内存中创建一个对象,而对象中包含学生的属性名和属性值,同时系统会为这个Student对象分配一个地址值0x4f3f5b24。
    • 栈内存中的变量s1存储的就是这个地址值,再次调用该变量时,就是通过这个地址来找到对象。
  • 当执行s1.name=“播妞”时,其实就是通过s1找到对象的地址,再通过对象找到对象的name属性,再给对象的name属性赋值为播妞;

  • 当执行s1.printTotalScore()时,先通过s1找到对象的地址,再通过对象找到类的地址,再通过方法区中的方法来执行该方法。

  • 对象 s2 及其他操作同上。

4. 类和对象注意事项

  • 类名的命名建议使用英文单词,并且每个单词首字母大写,使用驼峰命名法,例如:Student、Apple...
  • 类中定义的变量也称为成员变量(对象的属性),类中定义的方法也成为成员方法(对象的行为)
  • 成员本身存在默认值,各类型初始值如下:
类型 默认值
byte、short、char、int、long 0
float、double 0.0
boolean false
数组、String null
  • 一个.java文件中,可以有多个 class类,但只能有一个被 public 修饰,且该类名必须与文件名相同
  • 对象与对象之间的数据不会互相影响,但当多个变量指向同一个对象时,多个变量所保存的地址是相同的,此时他们之间会相互影响
  • 如果某个对象没有一个变量引用他,那么该对象无法操作,该对象会成为所谓的垃圾对象

5. this 关键字

在类与对象中,this 关键字较为常用,我们先来了解一下它的含义。

this 就是一个变量 ,用在成员方法中,可以拿到当前类的对象

由上图我们可以看到,this 就是拿到我们当前类的对象,它存储的內容与定义对象的变量相同,而且哪一个对象调用成员方法中的 this,this 指向的就是哪个对象。

了解了 this 的含义,那他的使用场景有哪些呢?

当我们的成员方法需要传参时,而这时它的形参名与该类的成员变量名有冲突时,可以使用 this 来避免错误。

例如:

java 复制代码
public class Student{
	// 成员变量
	// 代表通过所需要的分数
	double sorce;
	
	// 成员方法
	// 判断是否通过
	public void checkPass(double sorce)
	{
		if(sorce > sorce)
		{
			System.out.println("恭喜你通过了!");
		}
		else{
			System.out.println("很遗憾,你落选了");
		}
	} 
}

上述代码我们可以看到一个问题:该成员方法的目的是比较用户传进来的成绩和通过的分数,来判断用户是否通过,但成员方法的形参名与成员变量名有冲突,所以这时就不得不使用 this 关键字,可修改为以下代码:

java 复制代码
public class Student{
	// 成员变量
	// 代表通过所需要的分数
	double sorce;
	
	// 成员方法
	// 判断是否通过
	public void checkPass(double sorce)
	{
		// this 代表该对象
		// this.sorce 就代表该对象的成员变量,也就是该类中定义的那个 sorce
		// 而 sorce 遵循就近原则,代表形参
		if(sorce > this.sorce)
		{
			System.out.println("恭喜你通过了!");
		}
		else{
			System.out.println("很遗憾,你落选了");
		}
	} 
}

6. 构造器

6.1 什么是构造器?

构造器是一种特殊的方法,但这个方法没有返回值类型,并且方法名必须和类名相同。

例如:

java 复制代码
public class Student{
	public Student() {
		System.out.prinln("这是一个无参数构造器");
	}
	public Student(int age) {
		System.out.println("这是一个有参数构造器");
	}
}

6.2 构造器作用

构造器既然与类名相同,也就代表着,当我们创建对象时,对应的构造器也会执行

例如:

可以看到,当我们创建对象时,根据传参的不同,会执行相应的构造器,换句话说:new 对象就是在执行构造器

6.3 构造器应用场景

构造器是在创建对象时起作用的,所以可以在创建对象时给对象的属性做一些初始化操作,例如:

可以看到,当我们在创建对象时,通过有参构造器,就可以进行传参并初始化对应的成员变量。

构造器在使用时应注意以下几点:

  • 在一个类中,若不书写构造器,Java 会自动生成一个无参数构造器;
  • 一旦定义了有参数构造器,Java 便不会提供无参数构造器,此时建议自己写一个无参数构造器

7. 封装性

面向对象有三个核心的特性:封装性、继承性、多态性。下面我们来了解以下封装性

7.1 什么是封装?

封装就是用类设计对象处理某一个事物的数据时,把要处理的数据,以及处理数据的方法,都设计到一个对象中去。不恰当的说,就是自己的问题自己解决。

比如:在设计学生类时,我们把学生的各种信息以及需要用到的方法都封装到一个类中。

java 复制代码
public class Student {
    String name;
    double score;

    public void CheckPass()
    {
        if(score > 60)
        {
            System.out.println("及格了");
        }
        else{
            System.out.println("没及格");
        }
    }
}

7.2 封装的设计规范

封装的设计规范可以总结为:合理隐藏、合理暴露

我们将一系列信息封装成一个类,是为了让用户使用这个类来解决问题,我们更希望用户能够调用一个接口便能解决一个复杂问题,而不是把一个复杂问题交给用户自己去做。就如同车企做一台汽车,车企让用户通过油门、刹车、方向盘等方式来操控汽车,而不是让用户直接控制发动机、点火装置、行车电脑等内部的设备,因为这样不仅操作复杂,还非常危险。

7.3 封装的书写

首先我们介绍一个修饰符private,被该修饰符修饰的变量或者方法,只能在本类中被访问。

例如:

java 复制代码
public class Student {
    private int i = 1;
    int j = 2;
    public void Print(){
        System.out.println(i);// 输出1
        System.out.println(j);// 输出2
    }
}

class Tree {
    Student st = new Student();
    public void Print(){
        System.out.println(st.i);// 报错
        System.out.println(st.j);// 输出2
    }
}

如上述代码所示,private int i就相当于把变量i封装在Student对象的内部,不对外暴露,也就不能直接访问这个变量了。

我们可以通过对外暴露一个方法,通过该方法来间接访问变量,这样既不会直接暴露成员变量,又可以访问它。

例如:

java 复制代码
public class Student {
	private int score;
	// 赋值
	public void setScore(double score){
		this.score = score;
	}
	// 获取
	public void getScore(){
		return score;
	}
}

上述代码中,我们将变量score隐藏起来,通过方法setScore(double score)就可以来接收用户的输入,通过方法getScore()就可以来获取变量的值,这样合理隐藏,合理暴露的编程思想使得代码更为安全。

8. 实体JavaBean

在面向对象编程中,我们会经常书写一种特殊的类------实体JavaBean类,它有如下特点:

  • 这个类中的成员变量都要私有,并且要对外提供getXXX、setXXX方法
  • 类中必须要有一个公共的无参的构造器

例如:

java 复制代码
public class Student {
    //所有成员变量都要私有化
    private String name;
    private int id;
    private double score;

    //类中必须提供一个公共的无参构造器
    public Student() {
    }

    //为每个成员变量提供Getter和Setter
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public double getScore() {
        return score;
    }

    public void setScore(double score) {
        this.score = score;
    }
}

实体类中除了有给对象存取数据的方法,就没有其他功能了,所以实体类的作用就是来封装数据

实际开发中,我们将数据单独通过实体JavaBean类来封装,处理数据的方法又通过另一个类来封装。这样就实现了数据和数据业务处理相分离。

例如:

本文结束


相关推荐
阿乾之铭1 分钟前
Spring Boot框架中的IO
java·spring boot·log4j·1024程序员节
程序猿阿伟7 分钟前
《C++中的魔法:实现类似 Python 的装饰器模式》
java·c++·装饰器模式
Mr. zhihao9 分钟前
装饰器模式详解:动态扩展对象功能的优雅解决方案
java·开发语言·装饰器模式
zyhomepage9 分钟前
科技的成就(六十四)
开发语言·人工智能·科技·算法·内容运营
Ethan Wilson16 分钟前
C++/QT可用的websocket库
开发语言·c++·websocket
2401_8576009516 分钟前
商场应急管理:SpringBoot技术解决方案
java·spring boot·后端
想做白天梦28 分钟前
多级反馈队列
java·windows·算法
潇雷29 分钟前
算法Day12|226-翻转二叉树;101-对称二叉树;104-二叉树最大深度;111-二叉树最小深度
java·算法·leetcode
一颗甜苞谷37 分钟前
开源一套基于若依的wms仓库管理系统,支持lodop和网页打印入库单、出库单的源码
java·开源