Java阶段二——面向对象OOP(基础)

  • 方法区:加载的类的模板结构。

类的内存解析:

  • **堆:**存放new出来的对象,对象中存放的是对象的成员变量(起初是默认值)。没有new,就不会新开辟空间。
  • **栈:**存放的是对象名,代表的是对象的首地址。调用成员变量时,会给对中的成员变量赋值。
  • **方法区:**用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的

代码等数据。

成员变量 VS 局部变量:

  • **成员变量:1、**类内-方法体外声明的变量。2、随对象的创建,存储在堆空间。3、随着对象的创建而创建,随着对象的消亡而消亡。4、能用权限修饰符修饰。5、有默认值,所以不用必须显式赋值。
  • 局部变量:1、方法体内等位置声明的变量。2、存储在栈空间。3、随着方法对应的栈针入栈,局部变量在栈中分配,随着方法对应的栈针出栈,局部变量消亡。4、不能用任何权限修饰符进行修饰。5、在使用局部变量前,必须显式赋值。

  • **任何一个类都可以作为另一个类中属性的类型。**作为引用数据类型。

例如,员工的生日属性。首先,需要先创建Mydate类,包含了生日的年、月、日属性。

接着,在另一个类中声明birthday时,可以直接使用Mydate类作为生日的数据类型。

接着,创建对象,调用属性。

二、方法

方法的声明

  • public void eat();
  • public void sleep(int hour);
  • public String interests(String hobby);   //调用该方法时要传入形参,并有一个变量接收返回值
  • public int age();   //调用该方法时,要有一个变量接收返回值。

在声明方法时,要不要提供返回值类型(要不要有返回值)以及要不要传形参,则具体问题具体分析。

方法注意事项

  • 必须先声明后使用,且方法必须定义在类的内部
  • 调用一次就执行一次,不调用不执行。
  • 方法中可以调用类中的方法或属性,不可以在方法内部定义方法。

return关键字的作用

  • 作用
    1
    :结束一个方法。
  • 作用2
    :结束一个方法的同时,可以返回数据给方法的调用者。
  • return后面不能再声明执行语句。

Q:如果main和方法在同一个类中,在main中不声明对象调用方法的情况下,方法要用static修饰???(后面待解决)

例如,

这样的话,方法会报错。当方法声明时加上static后,可以不用创建对象调用。例如:

方法调用的内存解析

每一个方法对应一个栈针。

  • 方法 没有被调用 的时候,都在 方法区 中的字节码文件(.class)中存储。
  • 方法 被调用 的时候,需要进入到 栈内存 中运行。方法每调用一次就会在栈中有一个 入栈 动作,即
  • 给当前方法开辟一块独立的内存区域,用于存储当前方法的局部变量的值。
  • 当方法执行结束后,会释放该内存,称为 出栈 ,如果方法有返回值,就会把结果返回调用处(例如在main方法中调用某个方法,该方法的返回值是返回到main中),如果没有返回值,就直接结束,回到调用处继续执行下一条指令。
  • 栈结构:先进后出,后进先出。

三、对象数组

数组的元素可以是基本数据类型,也可以是引用数据类型。当
元素是引用类型中的类
时,我们称为对象数组。

例如,我们要查看20个学生对象的基本信息,其中,每个学生对象都包含多个属性,“学生”就可作为一个类作为引用数据类型。20个学生组成对象数组,其中每个元素即每个学生的数据类型是“学生”。

**格式举例:**Student[ ] students=new Student[20];

当我们需要为每个学生对象的属性赋值等操作时,需要再次创建对象。即students[i]=new Student()。

案例一:

定义类Student,包含三个属性:学号number(int),年级state(int),成绩score(int)。 创建20个学生对象,
* 学号为1到20,年级和成绩都由随机数确定。
* 问题一:打印出3年级(state值为3)的学生信息。
* 问题二:使用冒泡排序按学生成绩排序,并遍历所有学生信息

public class student_Test {
    public static void main(String[] args) {
        Student[] students=new Student[20];//创建对象数组。
        for(int i=0;i<students.length;i++){
            students[i]=new Student();//要为20个学生依次new对象,堆中
            students[i].number=i+1;
            students[i].state=(int)(Math.random()*6+1);//[1,6]
            students[i].score=(int)(Math.random()*101);//[0,100]
        }
        int state=3;
        for(int i=0;i<students.length;i++){
            if(state==students[i].state){
                System.out.println(students[i].printStudents());
            }
        }
        //局部变量存放在栈中。属性(成员变量)在堆中
        for(int i=0;i<students.length-1;i++){
            boolean flag=true;//元素已经是排好序的
            for(int j=0;j<students.length-1-i;j++){
                if(students[j].score>students[j+1].score){
                    Student temp=students[j];//这里使用students[j].score是错误的,因为我们要把学生的所用属性进行一个交换。
                    students[j]=students[j+1];
                    students[j+1]=temp;
                    flag=false;//设为false,证明元素在该轮交换了一次
                }
            }
            if(flag){ //如果为true,则表明在i轮后,并未再次进行交换,元素已经有序,此时可以跳出循环了
                break;
            }
        }
        System.out.println();
        for(int i=0;i<students.length;i++){
            System.out.println(students[i].printStudents());
        }

    }
}

案例二:


1
)定义矩形类
Rectangle
,包含长、宽属性,
area()
返回矩形面积的方法,
perimeter()
返回矩形周长的

方法,
String getInfo()
返回圆对象的详细信息(如:长、宽、面积、周长等数据)的方法


2
)在测试类中创建长度为
3

Rectangle[]
数组,用来装
3
个矩形对象,并给
3
个矩形对象的长分别赋值


10,20,30
,宽分别赋值为
5,15,25
,遍历输出

案例二 内存解析:

area()方法和perimeter()方法调用都将返回值返回到getInfo()中, 然后依次出栈。

四、方法的重载

定义

在同一个类中,允许存在一个以上的同名方法,只要它们的参数列表不同即可。【参数列表不同,意味着参数个数或参数类型的不同 ,和形参名、修饰符、返回值类型都没有关系。】

Q:编译器是如何确定调用的是某个具体的方法呢?

答:编译器先通过方法名确定一波重载的方法,再根据形参列表确定具体的某一方法。

注意:下图中,打印出的值为什么中间这个是具体的值,其它是地址值?

因为println是有一系列重载的方法,如下图,其中这个数组arr1和arr2(引用类型了)就对应Object。Object类型默认是打印地址值。

五、可变个数的形参

格式: 方法名(参数类型… 参数名)

  • 可变个数形参的方法在调用时,可赋的实参个数可以是0个、1个或多个。

  • 可变个数形参的方法与同名的方法之间,彼此构成重载 。

  • 可变参数方法的使用与方法参数部分使用数组是一致的,二者不能同时声明,否则报错。

  • 方法的参数部分有可变形参,需要放在形参声明的最后.

  • 在一个方法的形参中,最多只能声明一个可变个数的形参.

场景举例:

六、方法的值传递机制(重要)

1、(复习)对于方法内声明的局部变量来说:

如果出现赋值操作,

  • 如果是基本数据类型的局部变量,则把数据值传递过去。
  • 如果是引用数据类型(有数组或对象)的局部变量,则把其地址值传递过去。

2、方法的参数传递机制

  • 如果形参是基本数据类型的变量,则将实参保存的数据值传递给形参。
  • 如果形参是引用数据类型的变量,则将实参保存的地址值传递给形参。

3、内存解析:

Java面试题: JAVA中的参数(变量)传递机制是什么?答:值传递。看传的是什么值了。(不是引用传递。)

答案:

//方法一:
public void method(int a,int b){
        a=a*10;
        b=b*20;
        System.out.println("a="+a);
        System.out.println("b="+b);
        System.exit(0);//正常终止当前运行的Java虚拟机,main函数后面的代码则不会再运行了。
    }

//方法二:暂时先不理解了,等后续再看!!

public static void method(int a, int b) {
    PrintStream ps = new PrintStream(System.out) {
    @Override
    public void println(String x) {
        if ("a=10".equals(x)) {
        x = "a=100";
      } else if ("b=10".equals(x)) {
        x = "b=200";
        }
        super.println(x);
        }
        };
    System.setOut(ps);
}

七、方法的递归

举例:

注意:

1. 递归调用会占用大量的系统堆栈,内存耗用多,在递归调用层次多时速度要比循环 慢的

多 ,所以在使用递归时要慎重。

2. 在要求高性能的情况下尽量避免使用递归,递归调用既花时间又 耗内存 。考虑使用循环迭

代。

八、面向对象的特征一:封装性

内聚,指一个模块内各个元素彼此结合的紧密程度;耦合指一个软件结构内不同模块之间互连程度 的度量。内聚意味着重用和独立,耦合意味着多米诺效应牵一发动全身。

1、为什么要封装?

理论上:

  • 高内聚:类的内部数据操作细节自己完成,不允许外部干涉;
  • 低耦合:仅暴露少量的方法给外部使用,尽量方便外部调用。

通俗来讲,就是把该隐藏的隐藏起来,该暴露的暴露出来。这就是封装性的设计思想。

2、如何实现数据封装?

  • 使用4种权限修饰符:public 、 protected 、 缺省 、 private

其覆盖范围如下:(这里的子类估计就是继承那种的子类)

  • 具体修饰结构
    • 外部类:public、缺省
    • 成员变量、成员方法、构造器、成员内部类:public、protected、缺省、private

3、封装作用

可以使用4种权限修饰符修饰类及类的内部成员,当这些成员被调用时,体现其可见性的大小。【问什么是封装性呢?】

4、案例

public class AnimalTest {
 **自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**

**深知大多数Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**

**因此收集整理了一份《2024年Python开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**

![img](https://img-blog.csdnimg.cn/img_convert/e17f43897798e4ecce9519e32b800904.png)

![img](https://img-blog.csdnimg.cn/img_convert/53aaa6772b81879a04d53a955df1a8ee.png)

![img](https://img-blog.csdnimg.cn/img_convert/ef13295c3442ccc456839597be723d55.png)

![img](https://img-blog.csdnimg.cn/img_convert/4b8cc56380084cec46b464526312f59a.png)

![img](https://img-blog.csdnimg.cn/img_convert/6c361282296f86381401c05e862fe4e9.png)

![img](https://img-blog.csdnimg.cn/img_convert/9f49b566129f47b8a67243c1008edf79.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!**

**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**

**如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注:Python)**

.(img-gWmGvHwx-1713594724853)]

[外链图片转存中...(img-8ufLXjgk-1713594724853)]

[外链图片转存中...(img-Xe0ZLLIx-1713594724854)]

![img](https://img-blog.csdnimg.cn/img_convert/6c361282296f86381401c05e862fe4e9.png)

![img](https://img-blog.csdnimg.cn/img_convert/9f49b566129f47b8a67243c1008edf79.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!**

**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**

**如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注:Python)**

![](https://img-blog.csdnimg.cn/img_convert/5ea1483ada3a9ac91af5fe36a2d80e44.jpeg)
  • 18
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值