Java的面向对象
02-面向对象基础-2
2021-07-01 2565 0
简介
1. 对象数组的内存解析
2. 匿名对象
理解:我们创建的对象,没有显式的赋给一个变量名,即为匿名对象
特征:匿名对象只能调用一次。
使用:如下
//NoNameObj.java package com.ylaihui.oop1; public class NoNameObj { public static void main(String[] args) { // 每次 new 都会产生一个新的对象 new Phone().sendMessage(); new Phone().playGame(); new Phone().setPrice(11.11); System.out.println(new Phone().getPrice()); // 实际开发中经常见到如下用法 PhoneMall pm = new PhoneMall(); pm.show(new Phone()); } } class PhoneMall{ public void show(Phone p){ p.sendMessage(); } } class Phone{ double price; public void playGame(){ System.out.println("PlayGames!"); } public void sendMessage(){ System.out.println("send message!"); } public void setPrice(double price){ this.price = price; } public double getPrice(){ return price; } }
3. Java中方法的重载
重载(overload)
定义:在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可。
说明: 具体应用中调用了哪个方法,跟方法中传入的实际参数类型和个数有关。简单可以记忆为:"两同一不同":
两同是指(同一个类)相同方法名
参数列表不同:参数个数不同,参数类型不同
2. 举例:
Arrays类中重载的sort() / binarySearch()
3.判断是否是重载
满足方法名相同但是形参的个数不同或者参数的类型不同就可构成重载,与方法的权限修饰符、返回值类型、形参变量名、方法体都没有关系
4. 在通过对象调用方法时,如何确定某一个指定的方法:
首先要看方法名,然后看方法的参数列表
错误的例子
//OverLoadTest.java package com.ylaihui.oop1; public class OverLoadTest { // 如下三个方法构成重载, 两同 一不同 public void getSum(double a, double b){ System.out.println(a + b); } public void getSum(int a, double b){ System.out.println(a + b); } public void getSum(double a, int b){ System.out.println(a + b); } public static void main(String[] args) { OverLoadTest t = new OverLoadTest(); t.getSum(1, 1); // error 自动类型提升,但是不知道调用哪个方法 } }
将后两个 getSum 方法的形参中的 double -> String
//OverLoadTest.java package com.ylaihui.oop1; public class OverLoadTest { // 如下三个方法构成重载, 两同 一不同 public void getSum(double a, double b){ System.out.println(a + b); } public void getSum(int a, String b){ System.out.println(a + b); } public void getSum(String a, int b){ System.out.println(a + b); } public static void main(String[] args) { OverLoadTest t = new OverLoadTest(); t.getSum(1, 1); // 2.0, 自动类型提升 } }
4. 可变参数的形参
1.可变个数形参是jdk 5.0新增的内容
2.具体使用:
2.1 可变个数形参的格式:数据类型 ... 变量名
2.2 当调用可变个数形参的方法时,传入的参数个数可以是:0个,1个,2个,...
2.3 可变个数形参的方法与本类中方法名相同,形参不同的方法之间构成重载
public void show(String ... strs)
public void show(String s)
public void show(String s, String s2)
2.4 可变个数形参的方法与本类中方法名相同,形参类型也相同的数组之间不构成重载。换句话说,二者不能共存。
public void show(String [] strs)
public void show(String ... strs)
二者不能共存, 实现的功能相同 ---- Duplicate method show(String[]) in type ...
2.5 可变个数形参在方法的形参中,必须声明在末尾,那也就是可变个数形参在方法的形参中,最多只能声明一个可变形参。
public void show(String ...strings, int i) {
// The variable argument type String of the
// method show must be the last parameter
}
如果允许不放在末尾,那么调用方法的时候,比如调用show并传入参数 show("aa", "bb", "cc", i);, 不能知道 这个可变参数到底是几个,到哪个参数结束 (自左至右解析参数)
4.1 可变参数形参的重载
//MethonArgsTest1.java package com.ylaihui.oop1; public class MethonArgsTest1 { public void show(int i){ System.out.println("show int"); } public void show(String ... strs){ System.out.println("show strings"); } public static void main(String[] args) { MethonArgsTest1 t = new MethonArgsTest1(); t.show("aaa"); t.show("aaa", "bbb"); } }
show strings
show strings
有个确定的方法,那么优先执行确定参数个数的,如果没有,那么会调用 可变参数的方法
//MethonArgsTest.java package com.ylaihui.oop1; public class MethonArgsTest { public void show(int i){ System.out.println("show int"); } public void show(String s){ System.out.println("show string"); } public void show(String ... strs){ System.out.println("show strings"); } public static void main(String[] args) { MethonArgsTest t = new MethonArgsTest(); // show string (有个确定的方法,那么优先执行确定参数个数的,如果没有,那么会调用 可变参数的方法) t.show("aaa"); t.show("aaa", "bbb"); } }
show string
show strings
5. 参数的值传递机制
方法的形参的传递机制:值传递
1.实参和形参的概念
形参:方法定义时,声明的小括号内的参数
实参:方法调用时,实际传递给方法(形参)的数据
2.值传递机制:
如果参数是基本数据类型,此时实参赋给形参的是实参真实存储的数据值。
如果参数是引用数据类型,此时实参赋给形参的是实参存储数据的地址值。(类似C++中的指针)
//ValueTransTest.java package com.ylaihui.oop1; class Obj{ int id; } public class ValueTransTest { public static void main(String[] args) { Obj o1 = new Obj(); o1.id = 1001; Obj o2 = o1; //赋值以后,o1和o2的地址值相同,都指向了堆空间中同一个对象实体。 o2.id = 1002; System.out.println(o1.id); // 1002 System.out.println(o2.id); // 1002 } }
5.1 基本数据类型的值传递
//ValueTransTest1.java package com.ylaihui.oop1; public class ValueTransTest1 { public void swap(int a, int b) { int temp = a; a = b; b = temp; } public static void main(String[] args) { int a = 10; int b = 20; ValueTransTest1 v = new ValueTransTest1(); v.swap(a, b); System.out.println("a = " + a + ",b = " + b); } }
5.2 引用数据类型的值传递
//ValueTransTest2.java package com.ylaihui.oop1; class Data{ int m; int n; } public class ValueTransTest2 { void swap(Data data) { int temp = data.m; data.m = data.n; data.n = temp; } public static void main(String[] args) { Data data = new Data(); data.m = 10; data.n = 20; ValueTransTest2 v = new ValueTransTest2(); v.swap(data); System.out.println("data.m = " + data.m + ", data.n = " + data.n); } }
data.m = 20, data.n = 10
7. 方法的递归
递归方法的使用
1.递归方法:一个方法体内调用它自身。
2. 方法递归包含了一种隐式的循环,它会重复执行某段代码,但这种重复执行无须循环控制。
递归一定要向已知方向递归,否则这种递归就变成了无穷递归,类似于死循环。
//例4:斐波那契数列
//例5:汉诺塔问题 、 爬楼梯问题
//例6:快排
//RecursionTest.java package com.ylaihui.oop1; public class RecursionTest { public static void main(String[] args) { // 例1:计算1-100之间所有自然数的和 // 方式一: int sum = 0; for (int i = 1; i <= 100; i++) { sum += i; } System.out.println(sum); // 方式二: RecursionTest test = new RecursionTest(); int sum1 = test.getSum(100); System.out.println(sum1); System.out.println("*****************"); int value = test.f(10); System.out.println(value); } // 例1:计算1-n之间所有自然数的和 public int getSum(int n) {// 3 if (n == 1) { return 1; } else { return n + getSum(n - 1); } } // 例2:计算1-n之间所有自然数的乘积:n! public int getSum1(int n) { if (n == 1) { return 1; } else { return n * getSum1(n - 1); } } //例3:已知有一个数列:f(0) = 1,f(1) = 4,f(n+2)=2*f(n+1) + f(n), //其中n是大于0的整数,求f(10)的值。 public int f(int n){ if(n == 0){ return 1; }else if(n == 1){ return 4; }else{ return 2*f(n - 1) + f(n - 2); } } }
5050
5050
*****************
10497
8 思考题
1. 什么是方法的重载?
2. 说明Java方法中的参数传递机制的具体体现?
3. 成员变量和局部变量在声明的位置上、是否有默认初始化值上、是否能有权限修饰符修饰上、内存分配的位置上有何不同?
4. 谈谈return关键字的使用
答案
1. 什么是方法的重载?
“两同一不同”:同一个类;参数列表不同。
如何调用确定的方法:方法名、参数列表
2. 说明Java方法中的参数传递机制的具体体现?
基本数据类型:数据值
引用数据类型:地址值 (含变量的数据类型)
3. 成员变量和局部变量在声明的位置上、是否有默认初始化值上、是否能有权限修饰符修饰上、内存分配的位置上有何不同?
成员变量:
在类中, 有默认初始化值,可以添加权限修饰符,在堆中分配
局部变量:
在方法中、方法的形参、代码块内、构造器形参、构造器内,无默认初始化值,不可以使用权限修饰符修饰, 在栈中分配
4. 谈谈return关键字的使用
① 结束方法 ② 针对于有返回值的方法,return + 返回数据