Java学习 (四) 面向对象--类与方法
关于面向对象的知识点
1、 java类 以及类成员
属性
方法
构造器
代码块
内部类
2、面向对象特征
封装
继承
多态
3、 其他关键字使用
this \ super \ package \ import \static \ final\ interface\ abstract
一、类的组成
1、定义类
vi Phone.java
public class Phone{//类的属性String name;double price;//方法1public void call(){System.out.println("打电话");}//方法2public void sendMessage(String message){System.out.println("发消息"+ message);}//方法3public void playGame(){System.out.println("打游戏");}
}
我们在一个java文件种定义了一个类,但是通常不会直接把main放到这个地方,我们会有一个测试文件去用main方法去调用这个文件下的类,上面的手机就相当于是一个对象
2、定义类测试文件
vi PhoneTEST.java
public class PhoneTEST {public static void main(String[] args) {//创建Phone对象//所有对象声明都是new开头Phone p1 = new Phone();//通过Phone的对象,调用其内部声明的属性或者方法//格式: 对象.属性 或者对象.方法p1.name = "huawei mate50";p1.price = 6999;System.out.println("name= " + p1.name + ",price " + p1.price);//调用方法p1.call();p1.sendMessage("123123");}
}
3、面向对象的操作过程
1、 创建类,并设计类的内部成员(属性、方法)
2、 创建类对象,比如 Phone p1 new Phone();
3、通过对象,调用其内部声明的属性或者方法,完成功能
4、面向对象内存解析
栈 方法内定义的变量放到栈中
堆 new 出来的结构(比如数组的实体,对象的实体),包括对象中的属性 (name age 那些都算)
方法区 存放类的带模板,比如Phone类的模板
1、创建类一个对象时的结构
我们调用一个main方法,就会压入一个栈帧
方法内声明的变量,是存放在栈帧里面的 p1
我们new 了一个对象,new的对象是放在堆里面的
通过栈帧指向了,实体的地址
当给对象内的值赋值时,会同构栈帧内的地址,找到实体的地址,修改实体堆内的数据
2、创建类的多个对象,属性赋值
上图是前3行代码的效果
p2也new 了一个对象,会在堆中再建一个实体存储对象
也是在main栈帧中使用
p1 p2 修改互不影响,但是也存在例外
我们在代码最后面新增了一个p1赋值给p3
会在栈帧中新增p3,但是和数组一样,只要你不new,就不会创建新的实体地址,只会指向
5、关于成员变量和局部变量
在类中定义的是成员变量,在方法内定义的是局部变量
二、方法
1、方法的重载
在同一个类中,允许存在一个以上的同名方法,只要他们的参数列表不同即可,满足这一的多个方法,彼此之间构成方法的重载
注意:方法的重载与形参的名称、权限修饰符、返回值类型都没有关系
public class OverloadTest{public void add(int i , int j){}public void add(int j , int i){}public void add(String i , int j){}
}
如上,只要形成不一致,那么就允许重复定义,但不允许定义两个重复的方法
编译器会查看方法名是否一致,形参是否一致
2、可变个数形参的方法
默认情况下形成个数为固定的,在调用方法时,可能会出现方法的形参的类型是确定的,单是参数的格式不确定,就可以定义可变个数形成
public class OverloadTest{mainoverloadtest.add(1,2,3,4,5)//定义可变个数的形参数//支持重载public void add(int ... nums){}}
说明
可变长形参的使用
public class Main {public static void main(String[] args){Main test = new Main(); //声明当前类//引用类下的方法,会返回一些数据,通过info接受,传参中第一个是分隔符,后面是多个字符String info = test.add1("-","hello","world","you");System.out.println(info);}public String add1(String operator, String ... nums){//定义一个接收所有nums的变量String result = "";//当我拿到了传入的多个值时,需要使用循环来遍历形参中的值for (int i = 0; i < nums.length;i++)//当if(i == 0){result += nums[i];}else{result += (operator +nums[i]);}return result;}}
3、方法值传递机制
1、基本数据类型
上面代码中存在一个误导,我们在使用基本数据类型的局部变量的时候
做了int n = m 的操作, 在基本数据类型中,这里不存在什么栈名和堆实体的关系,我们对m发生了修改,也和n没有关系,是之间传个变量
2、引用数据类型 数组
之前学过引用类型的,数组、对象
如果是引用数据类型,才会两者都发生改变
3、引用数据类型 对象
总结
如果是基本数据类型的变量,则将变量保存的数据值传递出去
如果是引用数据类型的变量,则将此变量保存的地址传递出去
4、参数传递说明
如果形参是基本数据类型,那么将实参赋值给形参
如果形参是引用类型,则将实参的地址值传给形参
5、递归方法
在方法中自己调用自身的方法,就是递归
直接递归 a -》a方法
间接递归 a-》b-》c-》a
没有尽头的递归就会出线栈溢出
案例 利用递归计算自然数从何
递归方法图解
递归注意