方法( Method)又称函数,是定义在类中的具有特定功能的一段逻辑程序。或者理解为:为了完成某项功能,封装的一系列代码的集合。
定义方法的好处:
可将功能代码进行封装,提高了代码的复用性。
语法结构:
修饰符 (static) 返回值类型 方法名(参数列表){
方法体;
}
(访问)修饰符:
方法允许被访问的权限范围,可以是public、protect、private也可以什么都不写(default)。其中public表示该方法可以被其他任何代码调用,其余见下表:
Java关键字控制范围:
访问控制修饰符的访问权限测试如下:
分别测试:同一个类、同一个包下的子类和非子类、不同包下的子类、不同包下的非子类。
1、同一个类中:
package Report13Test;
public class Father {
//创建四个方法,以不同的修饰符进行修饰
//1、public修饰
public void test1(){
System.out.println("这是public修饰的方法");
}
//2、protected修饰
protected void test2(){
System.out.println("这是protected修饰的方法");
}
//3、默认的default修饰
void test3(){
System.out.println("这是default修饰的方法");
}
//4、private修饰
private void test4(){
System.out.println("这是privated修饰的方法");
}
//在同一个类下进行调用
public static void main(String[] args) {
Father f = new Father();
f.test1();//这是public修饰的方法
f.test2();//这是protected修饰的方法
f.test3();//这是default修饰的方法
f.test4();//这是privated修饰的方法
}//可见,在同一个类中,四种修饰符修饰的成员都能够访问到。
}
2、同一包下的子类:
package Report13Test;
public class Son extends Father {
public static void main(String[] args) {
Son s = new Son();
s.test1();//这是public修饰的方法
s.test2();//这是protected修饰的方法
s.test3();//这是default修饰的方法
//s.test4();会报错
}
}
同一包下的非子类:
package Report13Test;
class Other {
public static void main(String[] args) {
Father o = new Father();
o.test1();//这是public修饰的方法
o.test2();//这是protected修饰的方法
o.test3();//这是default修饰的方法
//o.test4();同理,会报错
//可见,同一个包下的非子类,四种修饰符中只有private修饰的成员不能访问到。
}
}
3、不同包下的子类
package Reprot13Test1;
import Report13Test.Father;
//验证不同包中,子类几种访问修饰符的访问权限
public class Son2 extends Father{
public static void main(String[] args) {
Son2 s2 = new Son2();
s2.test1();//这是public修饰的方法
s2.test2();//这是protected修饰的方法
//s2.test3();//报错
//s2.test4();//报错
//可见,在不同包中的子类,父类中通过private、default修饰的成员,是无法访问到的。
}
}
4、不同包下的非子类
package Reprot13Test1;
import Report13Test.Father;
public class Other2 {
public static void main(String[] args) {
Father f2 = new Father();
f2.test1();//这是public修饰的方法
//f2.test2();报错
//f3.test3();报错
//f4.test4();报错
//可见,在不用包下的非子类中,仅有public修饰的成员可以被访问到。
}
}
以上,四种访问修饰符测试完毕。
static:
表示该方法是一个静态方法,属于类,不属于对象,可以直接使用类名访问。
后文将详细描述。
返回值类型:
基本数据类型:int double 等
引用类型:String、数组等
方法名:
要符合Java的命名规范。一般采用第一个单词首字母小写,其他单词首字母大写的形式,如getScore。
参数列表:
参数的类型和个数,可以有0个或多个参数。当有多个参数时,以逗号分隔。
方法体:
是方法的具体执行内容。
它包括局部变量的声明以及所有合法的Java指令。方法体中声明的局部变量的作用域在该方法内部。若局部变量与类的成员变量同名,则类的成员变量被隐藏。
一些注意点:
1.方法只有被调用时,才会被执行。且方法在调用的时候,要给定对应类型的参数,方法如果有返回值那么那么方法体中需要有return关键字返回对应类型的具体值。
2.定义方法时,方法的结果一定要返回给调用者,交由调用者处理。
3.任何一个方法(函数)都是以 return语句结尾的,所以方法体中必须要有 return语句。
若方法没有具体返回值,那么利用关键字void来指明返回类型。返回类型为void的return语句可以省略不写,编译器自动补上。
4.方法中一旦执行 return语句,就说明方法结束了。
5.方法中只能调用方法,不能在方法内部定义另外一个方法。
6.参数值类型和返回值类型没有直接关系。
7.程序调用方法是在栈中进行的。(栈:先进后出,后进先出。)
8.方法的返回值最多只能有一个,不能返回多个值。
9.若方法的返回值类型为void,则方法不能使用return来返回值。
10.返回值要和方法返回值匹配。例如,你定义了一个返回值为Int的方法,就不能return 一个字符串类型的返回值。
11.调用带参方法时,必须保证实参的数量、类型、顺序与形参一一对应。
定义一个方法前,问自己两个问题来确定目标:
1.这个方法的结果是什么,从而确定返回值的类型。
2.这个方法是否需要参数参加运算,从而确定形参的个数和参数的类型。
例子:
package day11_2;
import java.util.Scanner;
/**
* @author Huey
* @date 2020-11-2
*
*/
public class StaticWork {
public static void main(String[] args) {
MethodDemo01.main(args);
printWall();
getSum(1);
getScore();
}
/*说个小技巧,按住Ctrl后,把鼠标移到main函数调用的getScore()方法上时,你会发现字体变蓝了,并且下方出现了一条下划线,点击它,会跳转到getScore()方法的位置。*/
public static void printWall(){
for(int a =1;a<=9;a++){
int b=1;
for(;b<=a;){
System.out.print(a+"*"+b+"="+a*b+"\t");
b++;
}
System.out.println();
}
}
public static void getSum(int a) {
System.out.println("求1-?之间的和,请输入一个大于1的整数:");
Scanner scanner = new Scanner(System.in);
int num = scanner.nextInt();
int sum = 0;
for(int i = 1;i <= num;i ++){
sum += i;
}
System.out.println(sum);
}
public static void getScore() {
// TODO Auto-generated method stub
Scanner scanner = new Scanner(System.in);
System.out.println("请输入学生的分数:");
//输入学生的分数 赋值给变量score
int score = scanner.nextInt();
if(score>=90&&score<=100){
System.out.println("优秀");
}else if(score>=80&&score<90){
System.out.println("良好");
}else if(score>=60&&score<80){
System.out.println("及格");
}else if(score>=0&&score<60){
System.out.println("不及格");
}else{
System.out.println("输入错误");
}
scanner.close();
}
}
下面是MethodDemo01.java的源码
package day11_2;
public class MethodDemo01 {
public static void main(String[] args) {
System.out.println("因为MethodDemo01类的修饰词是public,所以支持在同一个包下进行跨类调用");
}
}
运行结果:
因为MethodDemo01类的修饰词是public,所以支持在同一个包下进行跨类调用
1*1=1
2*1=2 2*2=4
3*1=3 3*2=6 3*3=9
4*1=4 4*2=8 4*3=12 4*4=16
5*1=5 5*2=10 5*3=15 5*4=20 5*5=25
6*1=6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36
7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49
8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64
9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81
求1-?之间的和,请输入一个大于1的整数:
100
5050
请输入学生的分数:
99
优秀
方法的重载
在同一个类中,方法名相同,参数列表不同,叫做方法的重载。
package day10_30;
//方法的重载
//遵循就近原则,即优先选择参数列表与实参类型相近的方法
public class MethodDemo01 {
public static void main(String[] args) {
System.out.println(sum(1,2));
System.out.println(sum(50));
}
public static double sum(double a,int b){
return a + b;
}
public static long sum(long a,int b){
return a - b;
}
public static int sum(int a,int b){
return a * b;
}
// 自定义一个方法叫sum。 功能:求和
public static int sum(int num){
int s = 0;
for(int i = 1;i <= num;i ++){
s += num;
}
return s;
}
}
运行结果:
2
2500
常见的名词解释:
参数列表:
参数的类型和个数。
方法签名:
方法名 + 参数列表
变量:
成员(全局)变量:
声明/定义在类里面的变量称之为成员变量,作用域为当前整个类。
局部变量:
定义在局部的变量称为局部变量。局部变量可以和全局变量重名。方法体中声明的局部变量的作用域在该方法内部,若局部变量与类的成员变量同名时,类的成员变量被隐藏。
在内存中的位置:成员变量在堆内存中,因为对象的存在,才在内存中存在;局部变量存在栈内存中。
package day10_30;
//方法的重载
//遵循就近原则,即优先选择参数列表与实参类型相近的方法
public class MethodDemo01 {
int a;//全局变量
public static void main(String[] args) {
System.out.println(sum(1,2));
System.out.println(sum(50));
speak();
eat();
//静态函数的调用就是通过函数名直接调用
}
public static char speak(){
return 'k';
}
public static void eat(){
System.out.println("今天中午去哪个食堂恰饭?");
}
public static double sum(double a,int b){
return a + b;
}
public static long sum(long a,int b){
return a - b;
}
public static int sum(int a,int b){
return a * b;
}
// 自定义一个方法叫sum。 功能:求和
public static int sum(int num){
int s = 0;
for(int i = 1;i <= num;i ++){
s += num;
}
return s;
}
}
运行结果:
2
2500
今天中午去哪个食堂恰饭?
static静态关键字:
可以用来修饰:变量,方法,代码块
静态变量:用static来修饰的变量。
静态方法:
用static来修饰的方法,通过类名来调用。
注意:静态方法只能访问静态成员(成员变量和方法),非静态方法既可以访问静态成员也可以访问非静态成员。
使用时要注意:主函数得是静态的
原因: 因为静态方法和静态数据成员会随着类的定义而被分配和装载入内存中,而非静态方法和非静态数据成员只有在类的对象创建时在对象的内存中才有这个方法的代码段。倘若静态引用了非静态的,这种做法是JVM不允许的。因为根本无法从内存中找到非静态的代码段,必定会报错。
静态代码块:静态代码块中的内容,在类加载期间执行,且只执行一次。常用来初始化静态变量。
类变量?实例变量?
静态static优先于对象的存在,即静态会随着类的加载而加载,消失而消失,可见其生命周期最长。故静态的成员变量也叫类变量,非静态的成员变量也叫实例变量(实例变量生命周期随着对象的消失而消失。)。
当成员(包括成员变量和方法)被静态修饰后,就多了一个调用方式,除了可以被对象调用外,还可以直接被类名调用。调用格式:类名.成员
可以把所有成员都定义为静态吗?
对象在被用完后会被回收,但是静态static的数据生命周期特别长,用完后还会一直存在,用不着的情况下还存在,就成了垃圾。所以,不要把所有成员都定义为静态static。
总结下静态static优劣之处:
优点:把对象的共享数据进行单独空间的存储,节省了空间。且可直接被类名调用。
劣处:生命周期太长,会出现垃圾。且访问有局限性(静态只能访问静态)。
package day11_2;
public class StaticDemo {
public static void main(String[] args) {
//引用静态方法时,可以用类名.方法名或者对象名.方法名的方式。
System.out.println(Life.getStatic());//使用类名加前缀访问静态方法
Life l = new Life();
System.out.println(l.getNum());//使用实例化对象名访问静态方法
}
public static class Life{
private static int a;
private int b = 0;
static{//静态代码块,又称静态初始器,由static和{}组成,只在类装载的时候(第一次使用类的时候)执行一次,往往用来初始化静态变量。
a = 6;
}
public static int getStatic(){//静态方法,只能访问静态数据成员
return a;
}
public int getNum0(){//非静态方法
return b;
}
public int getNum(){//非静态方法可以访问静态方法和非静态方法
getStatic();
getNum0();
b = a;//非静态方法可以访问非静态数据成员和静态成员
return b;
}
}
}
运行结果:
6
6
个人学习笔记,若有误还望不吝赐教。