Java解析----详解类和对象

🔥Java解析----详解类和对象

🔥文章前提:

❓ Java是一门面向对象的语言,至于什么是对象,本篇博客将围绕这个主题展开,下面开始详解Java中类和对象的知识 👇

📙文章目录:👇

1.初步认识类和对象

2.类和类的实例化

3.类的成员

4. 封装

5. 构造方法

6. 认识代码块

7. 补充说明

8.练习

1.初步认识类和对象

❓ 类和对象之间存在着怎么样的关系呢👇
在这里插入图片描述
1️⃣ C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。
2️⃣ JAVA是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。
3️⃣ 面向过程注重的是过程,在整个过程中所涉及的行为,就是功能。
面向对象注重的是对象,也就是参与过程所涉及到的主体。是通过逻辑将一个个功能实现连接起来
❗️ 面向过程:
1.把冰箱打开 2. 把大象放入 3. 冰箱关起来
❗️ 面向对象: 打开冰箱,储存,关闭都是对冰箱的操作,是冰箱的行为。冰箱就是一个对象,所以只要操作冰箱所具备的功能,都要定义在冰箱中
【面向对象概念】
1️⃣. 面向对象是思考问题的一种思考方式,是一种思想。比如:概念与实例。理论与实践。名和实等等。
2️⃣. 类就是一类对象的统称。对象就是这一类具体化的一个实例。
3️⃣. 面向对象的好处:将复杂的事情变简单了,只要面对一个对象就行。
【面向对象设计】
1️⃣面向对象设计把握一个重要的经验:谁拥有数据,谁对外提供操作这些数据(私有)的方法!(被动的一方是数据的拥有者,主动的一方是执行者)
2️⃣开发时:找对象,建对象,用对象,并维护对象之间的关系。
⭐️简而言之 👇
面向对象就是用代码(类)来描述客观世界的事物的一种方式. 一个类主要包含一个事物的属性和行为

2.类和类的实例化

类就是一类对象的统称。对象就是这一类具体化的一个实例。
💨 简单的例子:👇
我们做月饼的模子就是一个类,而通过这个模子可以做出月饼,那么在这个例子当中,类就是那个模子,而月饼就是那个对象,所以月饼就是一个实体。一个模子可以实例化无数个对象
💨 总的来说:👇
类相当于一个模板,对象是由模板产生的样本。一个类,可以产生无数的对象。
声明一个类就是创建一个新的数据类型,而类在 Java 中属于引用类型, Java 使用关键字 class 来声明类。我们来看以下简单的声明一个类。👇

基本语法 👇

// 创建类
class <class_name>{  
    field;//成员属性
    method;//成员方法
}
// 实例化对象
<class_name> <对象名> = new <class_name>();

❗️ class为定义类的关键字,ClassName为类的名字,{}中为类的主体。类中的元素称为:成员属性。类中的函数称为:成员方法

类的声明分为两步:👇

1️⃣ class定义类 👇
在这里插入图片描述
2️⃣ 由定义的类去实例化对象 👇
在这里插入图片描述
在这里插入图片描述

❓ 我们来看一下在内存上类的定义是怎样的 👇
在这里插入图片描述
类的实例化

用类类型创建对象的过程,称为类的实例化👇

  1. 类只是一个模型一样的东西,限定了类有哪些成员.
  2. 一个类可以实例化出多个对象,实例化出的对象 占用实际的物理空间,存储类成员变量
  3. 做个比方。类实例化出对象就像现实中使用建筑设计图建造出房子,类就像是设计图,只设计出需要什么东
    西,但是并没有实体的建筑存在,同样类也只是一个设计,实例化出的对象才能实际存储数据,占用物理空间

❓ 那么如何访问到对象中的属性呢

        System.out.println(person.age);
        System.out.println(person.name);

0
null

👉 我们看到成员成员变量的访问,是由指向类的引用类型+(.)便可以访问到对应的成员变量

❗️ 成员变量没初始化基本类型默认数值为:0,引用类型默认值:null

成员变量的初始化:👇

      person.age = 11;
      person.name = "bit";

❓ 那么如何访问到对象中的方法呢 👇

        person.eat();
        person.print();

bit正在吃饭
姓名bit年龄11

❓ 一个类实例化多个对象 👇

     Person person = new Person();
     Person person1 = new Person();

实例化多个对象时的内存情况 👇
在这里插入图片描述
❗️ 由于 person1person2 是两块不同的内存,改变成员变量不会相互影响 👇

        person.age = 11;
        person.name = "bit";
        person1.age = 19;
        person1.name = "by";
        System.out.println(person.age);
        System.out.println(person.name);
        System.out.println(person1.age);
        System.out.println(person1.name);

11
bit
19
by

❗️ 注意事项

  • new 关键字用于创建一个对象的实例.
  • 使用 . 来访问对象中的属性和方法.
  • 同一个类可以创建对个实例

3.类的成员

3.1.字段/属性/成员变量

👉 在类中, 但是方法外部定义的变量. 这样的变量我们称为 “字段” 或 “属性” 或 “成员变量”(三种称呼都可以, 一般不会严格区分).
注意事项👇

  • 使用 . 访问对象的字段.
  • “访问” 既包含读, 也包含写.
  • 对于一个对象的字段如果没有显式设置初始值, 那么会被设置一个默认的初值.

默认值规则

1️⃣ 对于各种数字类型, 默认值为 0.
2️⃣ 对于 boolean 类型, 默认值为 false.
3️⃣ 对于引用类型(String, Array,以及自定制类), 默认值为 null

在这里插入图片描述
❗️ 注意事项:

1️⃣ null 在 Java 中为 “空引用”, 表示不引用任何对象. 类似于 C 语言中的空指针. 如果对 null 进行 . 操作就会引发异常
2️⃣ person2 可以引用指向 person 这个引用所指向的对象
3️⃣ 引用多次指向对象,引用仅指向最后一个对象
4️⃣ 引用不一定在栈上

3.2 方法 (method)

方法------> 用于描述一个对象的行为.
方法中还有一种特殊的方法称为:构造方法 (construction method)
在实例化对象的时候会被自动调用到的方法, 方法名字和类名相同, 用于对象的初始化.
虽然我们前面已经能将属性就地初始化, 但是有些时候可能需要进行一些更复杂的初始化逻辑, 那么就可以使用构造方法.

3.3 static 关键字

我们看这样一个代码

class Person{
    public static int count;
}
public static void main(String[] args) {
        Person person = new Person();
        person.count = 1999;
        System.out.println(person.count);
        Person person1 = new Person();
        System.out.println(person1.count);
    }

1999
1999

❓ 我们看到两个结果都是 1999 ,按照上面所说两个对象的成员变量是两块不同的内存空间,不会互相影响,当 person1 没有初始化时默认数值应该为: 0 但是程序结果却是 1999,这两个count难道是同一个吗,这是为什么呢

👉 count 类型为静态成员变量

被 static 修饰成员变量也叫做类变量,是被放到方法区中的

方法区:👇

1.存储代码片段
❗️ 所以可以得出结论:静态成员变量是属于类的

访问静态成员变量需要用类去访问(类名.静态成员变量/方法) 👇

Person.count = 10;

访问静态方法 👇

public static void staticfunc(){
        System.out.println("静态方法");
    }
public class TestDemo {
    public static void main(String[] args) {
        Person.staticfunc();
    }

❗️ 由于静态成员变量的使用不需要实例化对象,所以静态成员变量是不依赖对象的,普通的成员变量需要引用去访问,所以普通成员变量是依赖对象的

❗️ 有关静态成员变量/方法中的注意事项 👇

一、 在普通方法中不可以定义静态的变量
在这里插入图片描述
1.static 定义的变量属于类,不可以在方法中出现
2.eat方法的调用,需要对应的对象引用来调用。但是如果可以定义static变量,Person类就可以调用

二、 在静态方法中不可以定义静态变量

1.static 定义的变量属于类,不可以在方法中出现

❗️ 以上两条总结:静态变量是不可以定义在方法中的

三、 普通方法可以调用静态方法

public void print(){
        staticfunc();
        System.out.println("姓名"+name+"年龄"+age);
    }

静态方法类就可以调用所以可以在普通方法中调用

四、 静态方法中不可以调用普通方法

public static void staticfunc(){
        print();//erro
        System.out.println("静态方法");
    }

静态方法不需要对象的调用,所以在静态方法中定义的普通方法没法调用

❗️ 一个对象存储到哪里与是否被 final 修饰无关

❓ 面试题:main 方法为什么是静态的???

👉main方法是不是静态的都可以,看 JVM 底层加载如何去实现

总结:👇

🔥 在代码中尽量少使用 static,这样的代码称为祖传代码,容易存在一些不合理的代码,代码不好修改

4.封装

❓ 如果在定义的类中随意更改了一个成员变量的名字,会导致在使用时出现未定义这样的问题,那应该怎么去解决呢 👇

在类的调用者看来,让他看不来成员变量的名字就可以了 👇

封装------->private

private int age;

可以看到把 age 改成 privat 类后程序报错了 👇
在这里插入图片描述
❗️ 这里修改的不是成员变量的名字,而是变量的属性,这里的 age 已经被封装起来,即当前属性只可以在当前类中使用

❓ 那应该如何使用 age 呢 👇

需要公开的时 set 和 get 接口在类中完成初始化和打印

4.2 getter和setter方法

快捷键 Alt + ins
在这里插入图片描述
选择Getter and Setter得到以下代码 👇

public int getAge() {
        return age;
    }
public void setAge(int age) {
        this.age = age;
    }

☝️ 在这其中赋值,返回数值都是可以的

❗️ 这样做的目的是使成员变量 / 方法更加安全,类的使用人员只需要关心接口
即可👌

如图样式使用即可:👇

public static void main(String[] args) {
        Person person = new Person();
        person.setAge(10);
        System.out.println(person.getAge());
    }

👉 总结:
1️⃣ private 不光能修饰字段, 也能修饰方法
2️⃣ 通常情况下我们会把字段设为 private 属性, 但是方法是否需要设为 public, 就需要视具体情形而定. 一般我们希望一个类只提供 “必要的” public 方法, 而不应该是把所有的方法都无脑设为 public.

5. 构造方法

5.1 基本语法

构造类型:👇

方法名和类名是相同的,且构造方法比较特殊,没有返回值

❓ 那构造方法是用来干什么的,这就需要我们了解一个对象的产生【对象的实例化】

实例化对象课以分为如下几部:👇

  • 为对象分配内存
  • 调用合适的构造方法

☝️ 这两步完成后对象才真正产生了

❗️ 注意:👇

构造方法不止一个

不带参数的构造方法:👇

class Person{
    public Person(){
        System.out.println("Person():不带参数的构造方法");
    }
}
public class TestDemo {
    public static void main(String[] args) {
        Person person = new Person();
    }
}

当由类实例化对象时就会调用构造方法:👇
在这里插入图片描述

Person():不带参数的构造方法

❗️ 当没有指定的构造方法时,编译器默认生成一个不带参数的构造方法,也就是说一个类至少有一个构造方法

❗️ 这里如果封装 Person 在其他类中不可以被调用,只可以在该类里进行操作

private Person(){
        System.out.println("Person():不带参数的构造方法");
    }

在这里插入图片描述

☝️ 会引发错误

调用带有参数的构造方法:👇

public Person(String name){
        this.name = name;
        System.out.println(this.name);
    }
public class TestDemo {
    public static void main(String[] args) {
    Person person1 = new Person("bit");
    }
}

bit

❗️ 如果当前类有其他的构造方法,那么编译器不会帮我们生成不带有参数的构造方法
❗️ 构造方法之间可以构成重载

5.2 this关键字

this 表示当前对象引用(注意不是当前对象). 可以借助 this 来访问对象的字段和方法

👉 因为 this 只是走完了对象实例化的第一步分配内存空间,第二步还没进行,所以这里是表示对象的引用

❓ 面试问题:

this 和 super 的区别:

super后期讨论

❓ 先看 this 有什么作用 👇

  1. this.data 调用当前对象的属性
  2. this.func() 调用当前对象的方法
  3. this() 调用当前对象的构造方法

1️⃣ 调用当前对象的属性 👇

public Person(String name){
        this.name = name;
        System.out.println(this.name);
    }

2️⃣ 调用当前对象的方法👇

public void eat(){
        System.out.println("吃饭");
    }
    public void print(){
        this.eat();
    }

3️⃣ 调用当前对象的构造方法

public Person(){
        this("bit");//调用带有一个参数的构造方法
        System.out.println("Person():不带参数的构造方法");
    }
    public Person(String name){
        this.name = name;
        System.out.println(this.name);
    }

❗️ 先调用带有参数的构造方法,再调用不带参数的构造方法

❗️ this() 必须放在第一行,也就是说只能写一个 this()

❗️ this() 只能存放在构造方法中

6. 认识代码块

6.1 什么是代码块

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

  • 普通代码块
  • 构造块
  • 静态块
  • 同步代码块

6.2实例代码块

{//定义在类中
        System.out.println("实例代码块");
    }

6.3静态代码块

static {
        System.out.println("静态代码块");
    }

6.4代码块的使用

❓ 知道了如何定义代码块,那它怎样被调用呢

Person person = new Person();

静态代码块
实例代码块

👉 在实例化对象时候就被调用了,并且静态代码块先运行,然后是实例代码块,最后是构造方法

❗️ 实例化多个对象时,静态代码块只被执行一次

 Person person = new Person();
Person person1 = new Person("bit");

静态代码块
实例代码块
实例代码块

❗️ 不用实例化对象时,静态代码块也可以被执行 👇

public static int count;
Person.count = 10;
静态代码块

可以利用代码块对成员变量赋值 👇

{
        this.age = 99;
        System.out.println("实例代码块");
    }
    static {
        count = 99;
        System.out.println("静态代码块");
    }

❗️ 如果都是静态的,那么和定义的顺序是有关系的
❗️ 类的定义顺序:字段在前,其他在后
❗️ 上图代码当 cout 没有初始化默认数值为 99

7.补充说明

7.1 toString方法

❓ 当程序打印引用类型 person 时:👇

public static void main(String[] args) {
        Person person = new Person();
        System.out.println(person);
    }

Person@1b6d3586

☝️ 这里得到的时被哈希加密过的地址

❓ 我们看下编译器底层是如何实现的 👇

按住Ctrl键鼠标左击:println 👇
在这里插入图片描述
同样的方法点击valueOf:👇
在这里插入图片描述同样的方法点击toString:👇
在这里插入图片描述
👉 我们便知道了上图的地址是如何得出的了,是一个toString实现的

模拟实现一下这个toString 👇

class Person{
    public String toString(){
        return "by";
    }
}

❓ 当重新自定义一个toString的时候,程序打印的结果是什么呢

public class TestDemo {
    public static void main(String[] args) {
        Person person = new Person();
        System.out.println(person);
    }

by

❗️ 我们发现这次程序的运行没有运行编译器的object toString 而是运行了我们自己的toString方法,是因为发生了动态绑定,动态绑定后期介绍

❗️ 注意这里的toSring名字要完全一样,才会调用自己的

👉 我们也可以让编译器帮我们生成这样的 toSting ,这里可以用到快捷键

Alt + ins 👇
在这里插入图片描述
点击 toString 编译器自动生成 👇(按住Ctrl可以多选)
在这里插入图片描述
生成的代码:👇

@Override//重写
    public String toString() {
        return "Person{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }

介绍两个概念:👇

  1. 系列化:对象 --> 字符串
  2. 反序列化: 字符串—> 对象

7.2匿名对象

匿名只是表示没有名字的对象

  • 没有引用的对象称为匿名对象.
  • 匿名对象只能在创建对象时使用.
  • 如果一个对象只是用一次, 后面不需要用了, 可以考虑使用匿名对象.
public class Main { 
 public static void main(String[] args) { 
 new Person("caocao",19).show();//通过匿名对象调用方法
 } 
} 

8.练习

8.1.模拟实现计算器

全部代码:👇

class Calculator{
    private int num1;
    private int num2;
    public int getNum1() {
        return num1;
    }

    public void setNum1(int num1) {
        this.num1 = num1;
    }

    public int getNum2() {
        return num2;
    }

    public void setNum2(int num2) {
        this.num2 = num2;
    }
    public int add(){
        return num1+num2;
    }
    public int del(){
        return num1-num2;
    }
    public int cheng(){
        return num1*num2;
    }
    public double chu(){
        return (num1*1.0)/num2;
    }
}
public class TestDemo2 {
    public static void main(String[] args) {
        Calculator calculator = new Calculator();
        calculator.setNum1(3);
        calculator.setNum2(2);
        System.out.println(calculator.add());
        System.out.println(calculator.del());
        System.out.println(calculator.cheng());
        System.out.println(calculator.chu());
    }
}

运行结果:👇

5
1
6
1.5

8.2.交换两个数值

class MyValue {
    public int val;
}

public class TestDemo3 {


    public static void swap(MyValue myV1, MyValue myV2) {
        int tmp = myV1.val;
        myV1.val = myV2.val;
        myV2.val = tmp;
    }

    public static void main(String[] args) {
        MyValue myValue1 = new MyValue();
        myValue1.val = 10;

        MyValue myValue2 = new MyValue();
        myValue2.val = 20;

        swap(myValue1, myValue2);

        System.out.println(myValue1.val + " " + myValue2.val);
    }
}

20 10

以上就是 Java 类和对象的知识,如果有所帮助还请一键三连,谢谢大家的支持!!!
💞💞💞💞💞💞💞💞💞💞💞💞💞💞💞💞💞💞💞💞💞💞💞💞

  • 9
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
Java 是一种面向对象编程语言,具有强大的面向对象编程特性。在 Java 中,所有的数据都通过对象进行存储和操作。面向对象编程的核心思想是将代码组织成对象,并让这些对象互相协作,完成程序的功能。 以下是 Java 面向对象编程的主要特性: 1. 封装 封装是将数据和行为包装在一个单独的单元中,以便于控制和管理。在 Java 中,可以使用类和接口来实现封装。 2. 继承 继承是指一个类从另一个类继承属性和方法。继承使得代码重用更加容易,也可以提高代码的可维护性和可扩展性。 3. 多态 多态是指同一方法可以被不同的对象调用,产生不同的结果。在 Java 中,多态可以通过方法重载和方法重写来实现。 4. 抽象 抽象是将对象的共同特征抽象出来,形成一个抽象类或接口。抽象类不能被实例化,只能被继承,而接口只能被实现。 5. 接口 接口是一种特殊的抽象类,它只包含方法声明,不包含方法实现。在 Java 中,一个类可以实现多个接口,从而实现多重继承的效果。 面向对象编程的优点包括: 1. 模块化:面向对象编程使得代码更加模块化,易于维护和修改。 2. 代码重用:通过继承和多态,可以实现代码的重用,减少了代码的冗余。 3. 可扩展性:面向对象编程使得程序更加可扩展,可以通过添加新的类来扩展程序的功能。 4. 可靠性:面向对象编程使得代码更加可靠,可以通过封装和抽象来保证代码的正确性和一致性。 总之,Java 面向对象编程使得代码更加模块化,易于维护和修改,同时也提高了代码的可重用性、可扩展性和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦の澜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值