博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java自学笔记 — 面向对象1
阅读量:3898 次
发布时间:2019-05-23

本文共 3458 字,大约阅读时间需要 11 分钟。

类和对象

文章目录

1. 什么是类?什么是对象?

  • : 从真实的事物上抽象出来的一种概念
  • 对象:和类对应,是一种存在的实物

以地球为例子,讲一讲在地球中的类和对象的关系:

在这个地球上,我们常见的有:动物、植物、人类,为什么把人类单独提出来,因为我觉得人类太伟大了,哈哈!进入正题

请大家思考一下,动物!植物!人类!是某一个具体的事物吗?平常我们会见到很多动物,比如:狗,猫,猪…这些其实都是看得见,摸得着的实物。动物这一词,其实就是指从这些实物上抽象出来的一个名词,在Java中把这种抽象出来的叫做类。

以人为例:

: 人类

对象:黄种人、黑种人、白种人。( “人类” 只是对这三种人的一个抽象 )

2. 属性和方法

以人为例:

  • 属性:也叫成员变量,指类自带的一些特征。比如,头发颜色,体重,身高…
  • 方法:也叫成员方法,自带的一些动作。比如,跑步、吃饭、睡觉…

在这里插入图片描述

小结:

  • 从上图,可以看到类是一个抽象概念,如果你要使用类的方法或属性,必须创建类的对象,用类的对象来完成对应的操作(比如:增删查改类的属性,或调用方法…)
  • 类拥有属性和方法,但是都没有具体的值,同样也是抽象的概念。只有用;类创建了对象,才能有具体的值。

3.对象的创建

* 创建对象的两种形式

创建对象也叫做实例化

在这里插入图片描述

* 属性的初始化:

创建对象后,对于不同的成员变量(属性),会按照默认的初始化方式进行初始化

在这里插入图片描述

举例说明:

Person类的定义

// 法1Person p1 = new Person();// 法2Person p2 = null;p2 = new Person();/*	注意:	通过两种方式初始化的 p1、p2对象中,属性都是默认的初始化属性	如:name = null、age = 0*/// 为这个人类对象赋值p1.name = "猪八戒";p1.age = 250;

* 创建对象的本质 和 引用:

在内存空间的堆区域中,申请一块内存。用于存放该对象的 特有的信息 (属性/成员变量)

new Person();new Person().name = "匿名对象";// 这两次的 new,实际上在内存中开辟了两块内存,创建了不同的对象

new person() :是去堆区域中申请了一块儿内存。但是并没有名字(引用),我们把这种对象,叫做匿名对象。(想想一下中国皇帝培养的死侍,几乎都用的代号,匿名的)

用 “ new Person()” 创建的匿名对象,只能用一次!!!所以我们用引用来存放 “ new Person(); ”申请的堆内存的地址信息,这样我们可以通过引用来找到它该对象。通过引用,可以多次使用该对象

引用:

  • 存放在stack(栈内存)中

  • 存放的是 heap(堆内存) 的地址 (对象的堆内存地址值)

  • 若对象无引用,则该对象就是匿名对象

  • 想要获取、修改对象的属性,要通过引用定位到对象对应的堆内存

// 申明一个Person类型的引用变量:p1,指向new出来的Person对象Person p1 = new Person(); // 通过p1中的内存地址,找到了Person对象的内存空间,给name属性赋值p1.name = "张飞";

引用的本质: 引用存放的是地址值,不是对象。而是通过地址值指向了相应的对象( 完成了相应的绑定 )。

在这里插入图片描述注意:

  • 引用类型变量用于存放对象的地址,可以给引用类型赋值为null,表示不指向任何对象。
  • 当某个引用类型变量为null时,会无法访问该对象(因为它没有指向任何对象)。此时,如果通过引用访问成员变量或调用方法,会产生NullPointerException 的异常。

4. 执行Person 类代码的内存分析

  1. Java代码:

    Person p1 = new Person(); p1.name = "张飞";
    • 写完person类的代码,并且保存 —— person.java是保存在硬盘上的。但是,CPU是不能直接访问硬盘中的数据,所以要将数据加载到内存中
    • 内存中,有栈区堆区。而,Java代码加载进内存的时候,是存放在方法区。(加载进内存的时候,实际上已经是字节码文件)
    • 加载进内存后,就可以运行了:
      • 找main方法,它是程序的入口。找到main方法后,给它分配一块栈内存空间
      • 执行代码 Person p1main方法分配的那块那块内存空间中,开辟一块新内存。
      • 执行代码 new Person():在堆内存中,开辟一块内存空间,存放属性 (属性初始化为默认值: name=null,age = 0)
      • 进行 “=” 操作:将 new Person()创建对象分配的那块内存的地址信息,赋值给 p1引用的栈内存中。
      • 执行代码 p1.name = “张飞”:通过p1引用存放的堆内存地址,在堆内存中,找到该对象,然后为其name属性进行赋值

5. 参数

1. 分类

  • 形参:

    ​ 形参出现在函数定义中,在整个函数体内都可以使用, 离开该函数则不能使用

    void setName(String s){
    name = s;};
  • 实参:

    ​ 调用该方法时,用的是实参(地址值)

    p1.setName("张飞");
  • 可变长参数:

    ​ Java1.5版本的新特性,在定义方法时不知道以后要用的时候会传多少个参数。那么就用可变长参数,参数个数:0~n个

    ​ 如果参数既有固定参数,又有可变长参数,那么可变长参数放在参数列表的末尾

    // 方法名(参数类型...参数名);// 把该参数看做一位数组来使用showInfo(String...args){
    for(int i; i < args.length; i++){
    System.out.println( args[i]); }}// 调用p1.show(); // 无参数p1.show("参数1"); // 一个参数p1.show("参数1","参数2"); // 两个或者多个参数

2. 参数的传递

形参和实参,在栈内存中,都有独立的空间。再方法调用完后,形参就会被释放掉。

1) 基本数据类型作为参数时:

​ 基本数据类型,作为参数时,栈内存存放的是实际值,形参在方法体中,不论如何改变形参中的值,都不能影响实参的值 (因为形参和实参,是两块不同的内存空间)。

public class p{
int num = 5; // 实参 // 方法中的参数,是形参。 void test(int num){
num = 200; } // 传递实参 new p().test(num); System.out.println(num); // num = 5}

2) 引用数据类型作为参数时:

引用数据类型,作为参数时,**栈内存存放的是地址值**,而不是实际参数。地址值指向的才是实际的值。

​ 在调用方法时,形参在栈内存中指向的,和实参指向的是同一个内存空间。所以,方法体中 给形参赋值,就是给指向的那块内存空间做出修改。

​ 实际参数会改变。

public class p{
int[] arr = int[]{
10, 20}; // 实参 // 方法中的参数,是形参。 void test(int[] arr){
arr = [200, 10]; } // 传递实参 new p().test(arr); System.out.println(arr); // arr =[200, 10, 3]}

参数传递的内存分析图:

在这里插入图片描述

引用数据类型,作为参数时还有一种情况要注意:

​ 在方法体中,虽然实参的地址值传递给了形参。但是,形参又重新指向了其他对象(堆内存空间),这时候,不管形参怎么变都不会影响实参的值。

6. 方法调用时内存结构

以上面的代码为例子:

void test(int[] arr){
arr = [200, 10]; }// 方法的调用new p().test(arr);
  • 再调用方法时,JVM会为其在栈内存分配一个对应的空间,该控件称为栈帧
  • 一个栈帧,对应一个正在调用的方法,方法调用完毕后,栈帧被释放
  • 栈帧 — 这块栈内存中,存储着形参、局部变量等数据。随着栈帧的释放而释放

转载地址:http://gquen.baihongyu.com/

你可能感兴趣的文章
easy_sql
查看>>
班委考评怎么玩?
查看>>
震惊!PC端QQ也能防撤回?
查看>>
cmake入门那些坑
查看>>
git常用
查看>>
基础算法第4天_skiplist_跳表介绍
查看>>
重学C++之路_#1_概述_总体介绍
查看>>
重学C++之路_#1_基础用法
查看>>
重学C++之路_#1_异常处理
查看>>
C/C++指针回顾
查看>>
算法之排序--插入排序O(n**2)
查看>>
算法之排序--希尔排序
查看>>
转:C++ NULL二义性问题,C++11引入nullptr原因
查看>>
C神奇国度--Branchless code--Bit Twiddling Hacks
查看>>
linux那些锁、无锁操作
查看>>
javascript深入浅出图解作用域链和闭包
查看>>
this指向以及apply,call,bind三者的区别
查看>>
javascript深入理解-从作用域链理解闭包
查看>>
captcha.js一个生成验证码的插件,使用js和canvas生成
查看>>
javascript深入理解--作用域,作用域链,闭包的面试题解
查看>>