##################################################
目录
##################################################
类/方法/返回值
——————————
什么是类的方法
发现问题 要解决问题 找到解决问题的方法 执行这个方法 解决针对的问题
在 C 中 就是函数 不过到这里 换了个名。。
问题就好像需求
我们分析 然后想出解决方案
然后写出解决方法
最后变成一个可以解决问题的程序
方法就是 解决问题的方法
我们把解决某个问题的过程 拆成一个个步骤
然后封装进方法中 这个方法 就是我们解决问题的实现
调用方法 即 解决问题
方法就是做某件事 解决某个问题 实现某个功能
方法就是一个功能模块 代码块
——————————
何谓无参
无参 就是没有参数
无参方法就是不带参数的方法
参数是什么? 这个在 C 中叫变元 函数的传值调用
无参方法 简单的理解 就是单纯调用方法而不用方法传值
带参就是利用方法传值
二者最大的区别就是
无参方法 括号里是空的
带参方法 括号里是 参数、参数列表、对象参数、数组参数 等
——————————
类就是 单个文件/功能模块
%%%%%
类 是由一组具有 相同属性/成员属性 共同行为/成员方法 的 实体/对象 抽象而成的
对象的执行操作是通过编写类的方法实现的
所以类就是一个 功能模块 !
作用就是 做一件事
%%%%%
例如 手机
手机有
音量键
关机键
颜色
颜色是粉色
按下音量键 就会发出声音
按下关机键 就会锁屏
现在我们来定义一个手机类:
MobilePhone code:
public class MobilePhone {
/* 手机类 */
/* 手机属性 */
String color = "粉色";
/* 手机行为 */
public void makeASound() {
/* 发出声音方法 */
System.out.println ( "苍茫地天涯是我滴爱.." );
}
public String lockScreen() {
/* 锁屏方法 */
String lock_screen = "黑屏!";
return lock_screen;
}
}
可以看到 MobilePhone 类定义了两个 行为/方法
发出声音
开始锁屏
当我们按下 音量键 时就会发出声音
当我们按下 锁屏键 时就会锁屏黑屏
手机能发声锁屏的内部实现就相当于类中的方法 能不能抽象出来?
这个就是面向对象的优点!!类的优点!
类就是现实生活中的手机 跟手机这个现实东西相对应
类中的 行为/方法 就是现实中手机的功能 也是一一对应
现在呢绕过来这个弯了吧?
类的每一个方法都实现了一个功能
当我们在其她类中创建这个类的对象时 就可以通过访问对象调用这个类的功能了!
而不用再考虑这个功能是怎么实现的 哪怕你调用千百次 对象待你还是第一次..
类的方法定义了类的某些功能 而方法的具体实现封装在类中 由此实现信息隐藏!
——————————
调用类的方法
%%%%%
定义了方法就要拿来使用
Java 中类是程序的基本单元 每个对象需要完成特定的应用程序功能
当需要某一对象执行一项特定操作时 通过调用该对象的方法来实现
调用类的无参方法:
对象名.方法名();
另外 在 同一个类中/相同的类 的 不同成员方法 之间 也可以进行相互调用
就是说 就是同一个类中 不需要实例化对象 就能直接调用访问本类的方法
访问本类无参方法:
方法名();
%%%%%
现在我们可以调用上面那个类的方法了
plan:
MobilePhone /* MobilePhone.java */
String color /* 手机颜色 */
int electric /* 手机电量 */
makeASound() /* 发出声音 */
lockScreen() /* 锁屏方法 */
playVideo() /* 播放视频 */
getColor() /* 得到颜色 */
playColor() /* 输出颜色 */
electricQuantity() /* 手机电量 */
Main /* Main.java */
main(String[] args) /* 程序入口 */
MobilePhone code:
public class MobilePhone {
/* 手机类 */
/* 手机属性 */
String color = "粉色";
int electric = 78;
/* 手机行为 */
public void makeASound() {
/* 发出声音方法 */
System.out.println ( "苍茫地天涯是我滴爱.." );
}
public String lockScreen() {
/* 锁屏方法 */
String lock_screen = "黑屏!";
return lock_screen;
}
public String playVideo() {
/* 播放视频 */
return "苍老师:亚麻跌..";
}
public String getColor() {
/* 得到颜色 */
return color;
}
public String playColor() {
/* 说出颜色 */
/* 正大光明的调用本类方法 */
return "这是一个"+ getColor() +"的三星手机";
}
public int electricQuantity() {
/* 手机电量 */
return electric;
}
}
Main code:
public class Main {
/* 主要类 */
public static void main(String[] args) {
MobilePhone phone = new MobilePhone(); /* 实例化 phone 对象 */
phone.makeASound(); /* 播放声音 */
System.out.println ( phone.lockScreen() ); /* 调用 phone.lockScreen() 并输出字符串返回值 */
String YaMaDie = phone.playVideo(); /* 调用 playVideo() 并接受字符串返回值 */
System.out.println ( phone.playColor() ); /* 得到颜色 */
System.out.println ( YaMaDie + "当前电量为 : "
+ phone.electricQuantity() + "%" ); /* 手机电量 */
}
}
这次我们在 CentOS 7 上编译文件:
创建编写 Main.java 文件:
创建编写 MobilePhone.java 文件:
编译两个 .java 源文件得到两个字节码文件:
运行包含 main() 的 .class 字节码文件:
我们可以看到 类的成员方法相对独立地完成了某个功能
她们之间可以相互调用 仅仅使用成员方法的名称即可!
在本例子中 playColor() 就调用了成员方法 getColor()
我们调用 playColor() 就自动调用了 getColor()
因为都是本类的成员方法 直接引用方法名即可
如果要调用其她类的方法
就必须创建这个类的一个对象后 才能通过点操作符访问其她类的成语方法
例如 Main.main() 中实例化的 phone 对象:
MobilePhone phone = new MobilePhone();
在 Main.main() 中调用 MobilePhone.makeASound() 方法:
phone.makeASound();
如果方法还有个返回值 调用时便可以得到返回值
例如 playVideo() 就返回一个字符串
"苍老师:亚麻跌.."
我们不仅可以直接输出 还可以接收值:
String YaMaDie = phone.playVideo();
然后使用:
System.out.println ( YaMaDie + "当前电量为 : " + phone.electricQuantity() + "%" );
当然也可以直接输出:
System.out.println ( phone.lockScreen() );
这两种处理返回值类型的方式是最常见的
我们也看到了 除了 String 还能返回其她类型 例如 int 什么的 自己慢慢试吧!。。
另外 涉及到类的方法调用 都可以用这种方式:
在同一个类中的方法 直接引用方法名 就能调用该方法
而对于不同类的方法 首先实例化创建该类的一个对象 然后通过 对象名.方法() 来调用
——————————
常见的错误
非常容易犯的错误
一定要细心:
方法的返回值若为 void 则该方法中就不能存在 return 语句!
一个方法只能返回一个值!!!
不存在嵌套方法这种骚操作。。
不能在方法外直接写程序逻辑代码!。。
%%%%%
方法的返回值若为 void 该方法中就不能存在 return 语句!
错误代码段示例:
public class Test {
public void test() {
return "测试 这是个错误例子";
}
}
编译报错:
[lilian@CentOS javaTest]$ javac Test.java
Test.java:5: 错误: 不兼容的类型: 意外的返回值
return "测试 这是个错误例子";
^
1 个错误
[lilian@CentOS javaTest]$
%%%%%
一个方法只能返回一个值!!!
错误 code 如下:
public class Test {
public double test() {
double A = 1.0, B = 2.2;
return A, B;
}
}
BUG 如下:
[lilian@CentOS javaTest]$ javac Test.java
Test.java:5: 错误: 不兼容的类型: 意外的返回值
return "测试 这是个错误例子";
^
1 个错误
[lilian@CentOS javaTest]$ javac Test.java
Test.java:7: 错误: 需要';'
return A, B;
^
Test.java:7: 错误: 不是语句
return A, B;
^
2 个错误
[lilian@CentOS javaTest]$
%%%%%
不存在嵌套方法这种骚操作。。
error code:
public class Test {
public String test() {
return "你怎么穿着品如的衣服..";
public String tTest() {
return "品如都没衣服穿了.. 我求求你别骚了..";
}
}
}
base bug:
[lilian@CentOS javaTest]$ javac Test.java
Test.java:7: 错误: 非法的表达式开始
public String tTest() {
^
Test.java:7: 错误: 需要';'
public String tTest() {
^
2 个错误
[lilian@CentOS javaTest]$
%%%%%
不能在方法外直接写程序逻辑代码!。。
error code:
public class Test {
boolean PinRu = true;
if (PinRu == true)
System.out.println ( "品如:我真没衣服穿了.." );
if (PinRu == false)
System.out.println ( "品如:本姑娘要穿婚纱!" );
public void test() {
System.out.println ( "品如:我冷..求条裤衩" );
}
}
base bug:
[lilian@CentOS javaTest]$ javac Test.java
Test.java:5: 错误: 非法的类型开始
if (PinRu == true)
^
Test.java:5: 错误: 需要<标识符>
if (PinRu == true)
^
Test.java:5: 错误: 需要';'
if (PinRu == true)
^
Test.java:5: 错误: 非法的类型开始
if (PinRu == true)
^
Test.java:6: 错误: 需要';'
System.out.println ( "品如:我真没衣服穿了.." );
^
Test.java:6: 错误: 需要<标识符>
System.out.println ( "品如:我真没衣服穿了.." );
^
Test.java:6: 错误: 非法的类型开始
System.out.println ( "品如:我真没衣服穿了.." );
^
Test.java:7: 错误: 非法的类型开始
if (PinRu == false)
^
Test.java:7: 错误: 需要<标识符>
if (PinRu == false)
^
Test.java:7: 错误: 需要';'
if (PinRu == false)
^
Test.java:7: 错误: 非法的类型开始
if (PinRu == false)
^
Test.java:8: 错误: 需要';'
System.out.println ( "品如:本姑娘要穿婚纱!" );
^
Test.java:8: 错误: 需要<标识符>
System.out.println ( "品如:本姑娘要穿婚纱!" );
^
Test.java:8: 错误: 非法的类型开始
System.out.println ( "品如:本姑娘要穿婚纱!" );
^
14 个错误
[lilian@CentOS javaTest]$
——————————
示例一个专门计算平均值的计算器程序
这次我们将代码都写在一个文件中
一个文件两个类也是可以滴!只要保证只有一个类是公开的即可!
Main.java code:
import java.util.Scanner;
public class Main {
/* 主要类 */
public static void main(String[] args) {
/* 对比一下 如果还不明白就别学 Java 了!!!去学 HTML 吧!!! */
Scanner input = new Scanner(System.in);
Calc cc = new Calc();
System.out.print ( "有几个数 <<< " );
cc.cal = input.nextInt(); /* 接收输入 存储在 Calc 类的 cal 成员变量中 */
System.out.printf ( "请输入 %d 个整数 以空格分隔 以回车结束\n<<< ", cc.cal );
for ( int i = 0; i < cc.cal; i ++ )
/* 循环将输入存储进 Calc 类的 valueList 数组 */
cc.valueList[i] = input.nextInt();
cc.showSum(); /* 输出总和 返回的 int 值不处理 丢掉! */
cc.showAverage(); /* 输出平均值 */
}
}
class Calc {
/* 计算器类 */
int valueList[] = new int[100]; /* 存储的数组 下标是 0~99 范围为 100 个数 */
int cal; /* 接收用户输入 */
double sum, average; /* 相加总和, 平均值 */
public int theSum() {
/* 计算总和 */
int j = 0;
for ( int i = 0; i < valueList.length - 1; i ++ )
/* 循环条件原本是 cal 但是这里使用 .length 获取数组长度 */
j += valueList[i]; /* 等同于 j = j + valueList[i] */
sum = j; /* 不将 j 声明在循环内部 出了循环还能使用 i 出了循环自动销毁 */
return j;
/* 返回的是 本方法内部的私自的一个变量
* 不过 返回的是 值 和 值类型 并没有返回这个变量的名字
* 所以 这个名字不重要 重要的要返回数据和数据类型
* 给你数据就不错了 爱咋处理就咋处理 我这个爆脾气方法不管啦!叫哪吒还是闰土啥的 随你!
*/
}
public void showSum() {
/* 显示总和 */
System.out.println ( "总和为 >>> " + theSum() ); /* 输出返回的 int 值 */
}
public double theAverage() {
/* 计算平均 */
average = sum / cal; /* 计算平均值 */
return average;
}
public void showAverage() {
/* 显示平均值 */
System.out.println ( "平均值为 >>> " + theAverage() );
}
}
CentOS 7 demo:
[lilian@CentOS javaTest]$ javac Main.java
[lilian@CentOS javaTest]$ java Main
有几个数 <<< 4
请输入 4 个整数 以空格分隔 以回车结束
<<< 10
20
30
40
总和为 >>> 100
平均值为 >>> 25.0
[lilian@CentOS javaTest]$ java Main
有几个数 <<< 4
请输入 4 个整数 以空格分隔 以回车结束
<<< 10 20 30 40
总和为 >>> 100
平均值为 >>> 25.0
[lilian@CentOS javaTest]$
##################################################
变量作用域
——————————
权限/作用域/生命周期/访问权限
什么叫作用域?
什么叫域?
域 就是一个区域 一个范围
作用域 就是在这个 区域/范围 内起作用
一旦超出这个范围 就不起作用了
那么 显而易见
变量的作用域 就是说在这个 区域/范围 内生效
一旦超出这个范围 就不生效了
也就是变量的生命周期 一旦超出这个作用域就销毁不再使用的变量
当然 也可以理解为 权限
何为权限:
在网上 很多珍贵资源我们不能下载 因为我们不是会员 没有会员权限
中南海我们也不能随便进去 。。你想被当成间谍吗? 我们不是内部人员 也没有进入权限
豪华酒吧我们得不到豪华的服务 因为我们没有VIP卡
邻居家的床我们不能随便上 因为我们无权使用 我们不是主人 除非被邀请但是 游乐场里的 玩具梯子 什么的公共器材我们可以自由使用 这是公有物品
看出了什么? 一些资源只能被授权的人使用 不在这个范围内 就无权使用
这就是权限!
——————————
成员变量和局部变量
%%%%%
Java 中用类来组织程序 类中可以定义变量和方法
在类的方法中 同样也可以定义变量
。。废话,我们在学类和对象之前 不都是在 test 类 的 main() 中定义变量吗!!
自从我们学了类和对象 知道还可以 定义在类中 && 定义在方法外
这样这个类的所有方法都能使用
而我们定义在方法中 那么离开这个方法后 就不能再使用此方法的内部变量了
现在知道了在不同的位置定义的变量有什么不同了吗?
%%%%%
成员变量
同一个类中的方法可以直接调用该类定义的成员变量
权限是 同一个类中
我们想到了什么? 对,就是类的属性
类的属性就是成员变量 同一个类中的方法都能访问调用成员变量
当然 其她的变量想要访问 创建一个此类的对象 就能通过点操作符来访问了
%%%%%
局部变量
局部变量的 权限/作用域 仅仅在定义该变量的方法内
就是说 只有方法自己才能使用自己内部定义的变量 其她方法的请求均拒绝访问
只有在定义她的那个方法中才能使用
就是说 自己的方法 该方法内声明的变量 只有在这个方法内才能访问
其她的方法无权访问
——————————
成员变量与局部变量的不同
%%%%%
作用域不同
第一就是 作用域不同了
局部变量的作用域仅限于定义她的方法 在该方法外不能访问
成员变量的作用域在整个类中都是可见的 所有成员方法都可以使用
如果访问权限允许 还可以在类外部调用成员变量
%%%%%
初始值不同
第二就是 初始值不同!!
成员变量 如果在类定义中没有赋初始值 Java会自动分配一个默认值
还记得默认值类型吗?
基本数据类型值为 0
引用类型的值为 null
but 不会给局部变量赋初始值!局部变量必须先定义赋值后再使用!
%%%%%
命名不同
第三就是 命名不同了。。
在同一个方法中 不允许存在同名的局部变量!
但是在不同的方法中 允许存在同名的局部变量。。
but 在同一个类中。。 成员变量。。 你 tm 敢同名试试。。 你连编译器都骗过不去!
另外
局部变量可以和成员变量同名 似的 没听错 局部变量可以和成员变量起一样的名字
然后 若被调用 局部变量具有更高的优先级!
%%%%%
成员变量就是全局变量
第四 成员变量 又叫全局变量
全局变量/局部变量 明白了吧?
至于为什么叫 成员变量 因为 成员变量/成员方法 啊!。。
这个你自己随便叫 全局变量/成员方法/局部变量 啥的 随便叫
不过 公共场合 例如 项目中 就要按规范的来
%%%%%
循环体中的局部变量
第五 控制流程语句代码块中的局部变量
是不是有点不明白?不过 你看看这段 code:
public class Test {
public void test() {
for ( int i = 0; i < 3; i ++ ) {
/* i 的 作用域/生命周期 仅仅在 { 循环体 } 之间 */
System.out.println ( "错误示例.." );
}
System.out.println ( i ); /* 出了循环体 i 就被销毁了! */
}
}
会提示无法解析变量 i 的错误:
[lilian@CentOS javaTest]$ javac Test.java
Test.java:11: 错误: 找不到符号
System.out.println ( i ); /* 出了循环体 i 就被销毁了! */
^
符号: 变量 i
位置: 类 Test
1 个错误
[lilian@CentOS javaTest]$
因为 这是在 for 循环块中声明定义的变量 只能在 for 块中使用
一旦超过退出这个结构 结构内的变量 i 就会自动随着结构销毁在内存中
所以找不到变量 i
当然 在其她的程序流程控制上也是一样的 例如 if、while、do-while、switch 等
这些都是萌新常常犯的错误!