1.跳转控制语句之return
return: 返回具体的结果(结束方法)
但是一般return很少单独使用,需要在有具体返回值类型的方法中使用!
return 一般都是结合方法使用
return 结果值;
例 :
class ReturnDemo{
public static void main(String[] args){
//for循环
System.out.println("程序开始了....") ;
for(int x =1 ; x <= 10 ;x ++){
if(x == 3){
return ; //方法结束,没有输出3.
//如果是break ;循环结束,程序依然需要继续往下执行!
}
System.out.println(x) ;//总共输出了1,2
}
System.out.println("程序结束了 Over....") ;
}
}
2. 方法
2.1 方法定义和格式
使用功能代码块{}(代码块)将核心功能使用{}包起来,并为之起一个名字(符号标识符的规则)即可!
Java中方法的定义格式:
分两种情况:
1)有具体返回值类型的方法定义
2)没有具体返回值类型的方法定义
2.1.1 有具体返回值类型的定义和调用
1) 定义
public static 返回值类型 方法名(形参类型1 变量名1,形参类型2 变量2....){
//功能业务操作
return 结果;
}
解释:
权限修饰符:现在方法访问权限:公共的/公开的,访问权限足够大,public
static:面向对象在讲,目前来说必须带上static
返回值类型:数据类型 (目前使用的基本类型)
方法名:见名知意,满足标识符的规则...(小驼峰)
形式参数类型:数据类型(目前使用的基本类型)
变量名:定义参数名称 (见名知意)满足标识符的规则...(小驼峰)
2) 调用
有返回值类型方法调用:赋值调用
返回值类型 变量名 = 方法名(实际参数名1,实际参数名2....);
使用变量名即可!
例: 定义一个求两个数之和的方法,并调用.
import java.util.Scanner;
class FunctionDemo{
pulic static void main(String[] args){
//创建键盘录入对象
Scanner sc = new Scanner(System.in);
//提示并录入对象
System.out.println("请您输入第一个数:");
int a = sc.nextInt();
System.out.println("请您输入第二个数:");
int b = sc.nextInt();
//赋值调用,推荐使用
int result = add(a,b);
System.out,println("两个数的和是:"+result);
}
//定义方法,两个方法要不在同一个大括号
public static int add(int x,int y){
int z = a+b;
return z;
}
}
3) 方法定义和调用注意事项
(1) 方法和方法是平级关系,在一个方法中不能定义嵌套另一个方法,即不能在同一个方法的大括号里.
(2) java是强类型语言,定义方法的时候,形参必须携带数据类型.
(3) 调用方法时,实参不用带数据类型.
(4) 定义方法时,左{和;不能共存,否则没有意义.
2.1.2 没有具体返回值类型的定义和调用
1) 定义
固定写法(使用void替代返回值类型,java的规定)
public static void 方法名(参数类型1 变量名1,参数类型2 变量名2....){
输出语句/或者数据交换...
}
2) 调用
单独调用(推荐)
方法名(实际参数列表) ;
例 : 使用方法改进输出几行几列的"*"
class FunctionDemo1{
public static void main(String[] args){
//调用方法,单独调用
print(4,5);
print(8,7);
}
//定义方法
public static void print(int a, int b){
//for循环,外层循环控制行数
for(int x =1,x <= a,x++){
//内层循环,控制列数
for(int y = 1,y <= b,y++){
System,out.print("*");
}
System.out.println();
}
}
}
2.2 方法重载(OverLoad)
2.2.1重载定义
多个方法名相同,参数列表不同,与返回值无关.
参数列表不同:
1)参数个数不同
2)参数类型不同
3)考虑类型顺序
public static int sum(double a,int b){}
public static int sum(double a,int b,int c){}
public static double sum(int a,double b){}
public static float sum(float a,float b){}
public static float Sum(float a,float b){} :不是重载
例 : 调用方法求两个数之和,3个数,4个数…
class FunctionDemo2{
public static void main(String[] args)}{
//分别调用方法,赋值调用
int result1 = sum(10,11,);
System.out.println("结果是:"+result1);
int result2 = sum(10,11,12);
System.out.println("结果是:"+result2);
int result3 = sum(10,11,12,13);
System.out.println("结果是:"+result3);
}
//按照方法重载概念,分别定义方法
public static int sum(int a , int b){
return a+b ;
}
public static int sum(int a , int b,int c){
return a+b+c ;
}
public static int sum(int a , int b,int c,int d){
return a+b+c+d ;
}
}
3. 数组
数组:引用数据类型 Java内存分配
栈内存:
存储局部变量:
局部变量:在方法定义中或者方法声明上的变量;
生命周期:随着方法调用而存在,随着方法调用结束而消失! :基本数据类型
public static int add(int a,int b){
return a+b;
}
方法需要加载进栈---->压栈
出栈的方式---->弹栈
栈结构特点:先进后出
堆内存: new 出来的东西都在这里面存储
举例:
Scanner sc = new Scanner(System.in) ;
一个数组,动态初始化
int[] arr = new int[3] ;
方法区:
字节码文件区域/static静态区域/常量池
本地方法区/寄存器:本地系统和cpu有关系
3.1 数组定义和格式
能够存储同一种类型的容器,在同一数组中,元素的数据类型必须一致!
数组定义格式:
数据类型[] 数组名称;
数据类型 数组名称[] ; // 两种格式都可以
数据类型:学习基本数据类型
例 : int[] arr;/ int arr[];
两个明确:
1)明确返回值类型:int
)明确参数类型以及参数个数:
例 : int[]数组,int元素 2个参数
3.2 数组的初始化
3.2.1 动态初始化
我们给定数组的长度,元素由系统(Jvm)默认初始化
数据类型[] 数组名称 = new 数据类型[长度] ; 推荐第一种
数据类型 数组名称[] = new 数据类型[长度] ;
例:
int[] arr = new int[3] ;
int arr[] = new int[3] ;
3.2.2 索引值
我们通过索引值(即元素的下角标)来访问数组中的元素.
格式: 数组名称[索引值].
索引值从0开始计数.
3.2.3 静态初始化
静态初始化:我们给出具体的元素内容,系统默认分配长度
数据类型[] 数组名称 = new int[]{元素1,元素2,元素3,.....} ;
数据类型 数组名称[] = new int[]{元素1,元素2,元素3,.....} ;
简化格式:书写代码简单
数据类型[] 数组名称 = {元素1,元素2,元素3,.....} ;
数据类型 数组名称[] = {元素1,元素2,元素3,.....} ;
例:
int[] arr = new int[]{1,2,3,4,5,6} ;
简化格式:
nt[] arr = {1,2,3,4,5,6} ;
3.2.4 注意事项
数组的初始化: 动态和静态初始化只能二选一,不能"动静结合"初始化.
例:
int[] arr = new int[3]{1,2,3} ; 错误的!不能动静结合
3.3 引用过程中的异常及解决方法
程序在使用过程中,经常会出现"异常";
程序有问题
1)编译时期异常:jvm检查语法不通过; 语法格式存在问题
举例:
同一个变量被定义多次
数组格式写错
...
2)运行时期异常:开发者:代码书写不严谨导致的问题
java.lang.ArrayIndexOutOfBoundsException:数组角标越界异常
出现的原因:访问了数组中不存在的角标(索引值)
如何解决:检查代码,更改索引值
java.lang.NullPointerException:空指针异常
引用类型的默认值都是null;
String s = null ; 字符串是一种特殊的引用类型
出现的原因:某一个对象已经为空了,null(没有堆内存地址),这个时候还要去访问元素或者调用这个对象的方法,那么就出现空指针;
解决:
使用逻辑判断语句,对该对象进行非空判断
例 :
// 进行非空判断
if(arr!=null){
System.out.println(arr[0]) ;
}else{
System.out.println("对不起,您的对象已经null了,无法访问....") ;
}
3.4 数组的实际应用
3.4.1 数组的遍历
arr.length: 表示数组的长度, 索引值最大值 = arr.length-1;
class ArrayTest{
public static void main(String[] args){
// 创建数组,静态初始化
int[] arr = {1,2,3,5,8,9};
// 调用方法,遍历数组
printArray(arr);
}
//创建遍历方法
public static void printArray(int[] arr){
System.out.print("[");
// 使用循环,遍历数组
for(int a = 0; a < arr.length; a++){
if(a == arr.length-1){
System.out.println(arr[a]+"]");
}else{
System.out.print(arr[a]+",");
}
}
}
}
3.4.2 数组的逆序
class ArrayTest1{
public static void main(String[] args){
// 创建数组,静态初始化
int[] arr = {1,2,3,5,8,9};
//调用方法,逆序数组
reverse(arr);
// 调用方法,遍历数组
printArray(arr);
}
//创建逆序方法
public static void reverse(int[] arr){
//创建循环,完成逆序,从两头开始,向中间逼近
for(int start = 0,end = arr.length-1; start<end; start++,end--){
int temp = arr[start]; // 引入中间变量,完成元素互换
arr[start] = arr[end];
arr[end] = temp;
}
}
//创建遍历方法
public static void printArray(int[] arr){
System.out.print("[");
// 使用循环,遍历数组
for(int a = 0; a < arr.length; a++){
if(a == arr.length-1){
System.out.println(arr[a]+"]");
}else{
System.out.print(arr[a]+",");
}
}
}
}
3.4.3 数组中的最大(小)值
class ArrayTest2{
public static void main(String[] args){
// 创建数组,静态初始化
int[] arr = {1,2,3,5,8,9};
// 调用方法
int result = arrayMax(arr);
System.out.println("最大值是:"+result);
}
// 创建方法求最值
public static int arrayMax(int[] arr){
//假设第一个元素就是最大值,和后边元素进行比较.最小值同理
int max = arr[0] ;
//创建循环
for(int a=1; a<arr.length; a++){
if(arr[a]>max){
max = arr[a];
}
}
return max;
}
}
3.4.4 数组中元素的查询
例 : 查询目标数在数组中第一次出现的索引值
class ArrayTest3{
public static void main(String[] args){
// 创建数组,静态初始化
int[] arr = {1,2,3,5,8,9};
// 调用方法,赋值调用
int result1 = getIndex(arr,2);
System.out.println("目标数第一次出现索引值是:"+result1);
}
//创建方法,获得索引值
public static int getIndex(int[] arr, int target){
// 假设不存在目标值
int index = -1;
// 遍历数组,找到目标值的索引值
for(int a = 0; a< arr.length; a++){
if(arr[a] == target){
index = a;
break;// 找到第一次出现的,就break结束循环
}
}
return index;
}
}
3.4.5 数组高级排序—冒泡排序法
冒泡排序思想:
从第一个开始,依次和后一个进行比较,如果前面的大,则交换位置.一共比较arr.length - 1次,得到最大值.
再从头进行比较,得出第二大的值.少比较一次
...
直至完成排序
class ArrayTest4{
public static void main(String[] args){
// 创建数组,静态初始化
int[] arr = {9,10,7,3,8,13};
//调用方法排序
bubbleSort(arr);
// 调用方法遍历
printArray(arr);
}
//创建排序方法
public static void bubbleSort(int[] arr){
//外层循环,控制比较几轮
for(int x = 0; x<arr.length-1; x++){
//内层循环,控制每一轮比几次
for(int y = 0; y < arr.length-1-x; y++){
//条件判断
if(arr[a]>arr[a+1]){
int temp = arr[a];
arr[a] = arr[a+1];
arr[a+1] = temp;
}
}
}
}
//创建遍历方法
public static void printArray(int[] arr){
System.out.print("[");
// 使用循环,遍历数组
for(int a = 0; a < arr.length; a++){
if(a == arr.length-1){
System.out.println(arr[a]+"]");
}else{
System.out.print(arr[a]+",");
}
}
}
}
4 基本数据类型和引用数据类型,分别作为形参对实参的影响
4.1 形参 基本数据类型
基本数据类型作为"形式参数" 传递特点:形式参数的改变不会影响实际参数!
因为基本数据类型做形参,只进栈不进堆,方法调用就消失了.
例:
class ArgsDemo{
public static void main(String[] args){
//定义两个变量
int a = 10 ;
int b = 20 ;
System.out.println("a:"+a) ;// 输出a:10
System.out.println("b:"+b) ;// 输出b:20
System.out.println("--------------------") ;
//调用了一方法
change(a,b) ;
System.out.println("--------------------") ;
System.out.println("a:"+a) ;// 再输出a还是10
System.out.println("b:"+b) ;// 再输出b还是20
}
public static void change(int a,int b){//形参:基本数据类型
a = b ;//a=20
b = a + b ;//b=40
System.out.println("a:"+a) ;// 输出a变成了20
System.out.println("b:"+b) ;// 输出b变成了40
}
}
4.2 形参 引用数据类型
引用类型作为形式参数特点: 形式参数的改变,会直接影响实际参数.
数组,类,接口
String类特点:字符串不可变,一旦被创建,其值不能被更改,是一个常量!
所以String类 类型除外(它的效果和基本数据类型)
是堆内存中的 空间地址值来传递参数,不会立即消失,等待GC空闲时间回收.
例:
class ArgsDemo2{
public static void main(String[] args){
//已知一个数组:静态初始化
int[] arr = {1,2,3,4,5} ;
//访问元素
System.out.println(arr[1]) ;// 输出第二个元素 2
System.out.println("---------------------") ;
//调用了一个方法
change(arr) ; // 第二个元素满足条件,被赋值为4
System.out.println(arr[1]) ; // 再输出,第二个元素变成了4
}
public static void change(int[] arr){//引用类型
//遍历数组
for(int x = 0 ; x < arr.length ;x++){
//判断
//1,2,3,4,5
if(arr[x] % 2 ==0){
//形参改变
arr[x] = arr[x]*2 ;
}
}
}
}
5 面向对象
5.1 什么是面向对象
本质是基于面向过程完成的;
面向过程: 完成某一件事情,从分析,到实现,都是自己亲力亲为完成的!
代表语言: c语言.
面向对象: 找一个对象,来完成需求.
代表语言:Java,c++,python...
举例: 洗衣服
面向过程:
1)脱下脏衣服--->2)找一个盆子-----3)放入洗衣液-----4)泡一泡-----5)搓一搓-----6)透水----7)拧一拧----->8)抖一抖-----9)晾一晾
面向对象:
1)脱下脏衣服---->2)全自动洗衣机(一键)----->3)晾一晾
5.2 面向对象的思想特点
1)更符合我们生活中思想行为习惯
2)让更复杂的事情简单化
3)角色发生了变化:我们从执行者变成了指挥者!
5.3 java语言面向对象三大特征
封装, 继承, 多态!
5.4 java中的类
5.4.1 类的概念
概念:能够描述一组事物的属性和行为的集合---->类,是java中最基本的单元
能够描述现实世界真实存在的 "事物"
类 -----> 事物
成员变量 -----> 描述事物的属性
成员方法(非静态的) -------> 描述事物的行为
成员变量: 在类中,方法外;
成员方法(非静态): 之前怎么定义方法,现在还怎么写,不过,去掉static关键字
public 返回值类型 方法名(形式参数列表){
业务体
//有具体结果1)return 结果 ;
//没有具体结果:输出 打印...
}
定义:
两个明确
1)明确返回值 :有-->给具体类型 ,没有:void 代替 输出结果
2)明确参数类型,以及参数个数
具体情况,具体分析
5.4.2 类与对象的关系
类: 描述真实事物,如: 学生类, 树木类
对象: 描述具体的事物,如: 学生华仔,学号xxx,住址xxx,兴趣xxx...
创建具体对象的格式和访问成员变量和成员方法:
类名 对象名 = new 类名() ;// 和创建键盘录入对象一样
给具体事物属性赋值
对象名.成员变量 = 根据类型赋值; // 对象名打点访问成员变量和方法
调用具体事物的行为
对象名.成员方法名()
举例 : 创建学生类,并测试
//定义一个学生类
class Student{
//定义成员变量(描述属性) :类中方法外
//学号,姓名,年龄,性别,住址
String sId;//学号
String name ; //姓名
int age ; //年龄
//定义成员方法:(描述行为) :去掉static,非静态的!
//学习JavaSE
public String study(String className){//"JavaSE"
return "正在学习"+className ;
}
//玩游戏,直接打印
public void playGame(){
System.out.println("学习困了,玩一把王者.") ;
}
}
//学生类的测试类
class StudentTest1{
public static void main(String[] args){
//创建了一个具体的学生对象
Student s = new Student() ;
s.sId = "x573024" ;
s.name = "陈小刀" ;
s.age = 28 ;
//输出结果
System.out.println("该学生的学号是"+s.sId+
",姓名是:"+s.name+",年龄是:"+s.age+") ;
//调用功能
String result = s.study("JavaSE") ;
System.out.println(result) ;
s.playGame() ;
}
}
测试类,使用main方法所在的类
即 public static void main(String[] args){}
6 成员变量 和 局部变量区别
1)在类中的书写位置区别
局部变量:在方法定义中或者是方法声明上;
成员变量:在类中,方法外;
2)在内存中的位置不同
局部变量:在栈内存中
成员变量:在堆内存中
3)生命周期不同:
局部变量:随着方法调用而存在,随着方法调用结束而消失
成员变量:随着对象的创建而存在,随着对象的调用完毕,等待垃圾回收器空闲时候回收,不会立即消失!
4)初始化时机不同:
局部变量:
要么先定义,使用之前必须初始化;要么直接初始化
成员变量:
可以不赋值,系统默认对成员变量初始化
也可以通过对象名.成员变量 =赋值;
6.1 形参问题
6.1.1
如下代码, 编译运行TestClassA 时,结果是 ©
A. 编译出错
B. 输出 10 10
C. 输出 10 11
D. 输出 11 11
class ClassA{
int value;//成员变量
}
//测试类
public class TestClassA{
public static void main(String args[]){
int value = 10;
System.out.println(value);//10
changeInt(value);// 基本数据类型做形参,不改变实参.
System.out.println(value);//所以调用完方法,实参还是10
System.out.println("--------------------------------") ;
ClassA ca = new ClassA(); //创建对象
ca.value = 10;//访问成员变量,给其赋值10
System.out.println(ca.value) ;//10
changeObject(ca);// 引用类型做形参,会改变实参
System.out.println(ca.value);// 所以打印的是11
}
public static void changeInt(int value){//基本数据类型int 10
value++; //11
}
public static void changeObject(ClassA ca){
ca.value++;// 引用类型做形参
}
}
6.1.2 一个方法的形参是一个类
需求:
1)要访问StudentDemo类中的method方法?
2)调用的时候,实际参数如何书写呢?
//定义一个学生类
class Student{
// 定义一个study方法
public void study(){
System.out.println("Good Good Study,Day Day Up!!") ;
}
}
//定义一个类StudentDemo类
class StudentDemo{
//有一个成员方法,形式参数是Student类型
public void method(Student s){//Student student = new Student() ;//形式参数:如果一个方法的形式参数是一个类,实际参数需要传递的当前类的具体对象
s.study() ; //student.study();即student类中创建student对象来打点访问study方法.
}
}
//定义一个测试类
class StudentTest{
public static void main(String[] args){
//要访问StudentDemo类的method方法,创建当前类对象来访问
StudentDemo sd = new StudentDemo() ;
//形式参数:如果一个方法的形式参数是一个类,实际参数需要传递的当前类的具体对象
//创建当前类对象:Student student = new Student() ;
Student student = new Student() ;
sd.method(student);
}
}
7 匿名对象
7.1 定义格式 , 访问成员变量和方法
即 没有名字的对象.
不同于一般创建对象的格式:
类名 对象名 = new 类名();
例 : Student s = new Student();
匿名对象:
直接 new 类名();
例: new Student();
访问类的成员变量和方法:
new 类名().成员变量名;
例: new Student().name;
new 类名().成员方法名;
例: new Student().playGame;
7.2 优点
1)节省内存空间
2)开发中,匿名对象一般 使用"一次即可",使用完毕就立即垃圾回收器回收!
7.3 链式编程
例:
//定义学生类
class Student{
public void study(){
System.out.println("好好学习,天天向上...") ;
}
}
//定义一个类:StudentDemo
class StudentDemo{
//show方法里面形式参数是引用类型:具体的类Student
public void show(Student s){
s.study() ;//new Student().study();
}
}
//定义学生测试类
class StudentTest{
public static void main(String[] args){
//需求:访问StudentDemo类中的show方法
//1)创建当前StudentDemo类对象
StudentDemo sd = new StudentDemo() ;
//调用show()
Student student = new Student() ;
sd.show(student) ; //实际参数需要创建Student类的对象
System.out.println("-----------------------------------------") ;
//匿名对象的格式:
//new 类名() ;
//需求:访问StudentDemo类中的show方法
StudentDemo sd2 = new StudentDemo() ;
sd2.show(new Student()) ;
System.out.println("-----------------------------------------") ;
//一步走:链式编程:仅仅是自己玩一玩足矣
new StudentDemo().show(new Student()) ;
}
}
8 封装和This 关键字
8.1 封装
为了保证类的属性的安全性,所有的属性都必须加入private关键字,
private:私有的,不能直接访问的;
被private修饰的成员变量或者是成员方法,只能在本类中访问;
外界类是不能直接访问的,间接可以通过公共的成员方法访问!
权限修饰符:
private :最小
public: 最大
并且对外提供公共的访问方法, 间接的对成员变量(属性)进行赋值;
setXXX()/getXXX():都是public的:权限足够大
总结:属性私有化,对外提供给公共的成员方法访问方法:setXXX()/getXXX()
8.2 this 关键字
局部变量名称和成员变量名称一致(局部变量隐藏了成员变量),Java提供了一个关键字:this
this:代表当前类对象的地址值引用
例:
//定义学生类
class Student{
//成员变量私有化;
private String name ;//姓名
//对外提供的公共访问方法:setXXX()/getXXX()
//给学生姓名赋值
public void setName(String name){ //n:赋值的姓名
this.name = name ;
}
//获取学生的姓名
public String getName(){
return name ;
}
//其他成员方法
//study()
public void study(String name){
System.out.println("我们正在学习"+name) ;
}
}
//测试类
class StudentTest1{
public static void main(String[] args){
//创建学生类对象
Student s = new Student() ;
//通setXXX()+getXXX()赋值,和获取值
s.setName("周星星") ;
System.out.println(s.getName()) ;
//调用其他方法
s.study("javaSE") ;
}
}
9 构造方法
9.1 定义和特点
构造方法是一种特殊的方法,方法名和类名一致;
特点:
1)方法名和类名一致;
2)构造方法没有返回值类型
3)连void都没有
构造方法是重载的!
方法重载:
方法名相同,参数列表不同,与返回值无关!
参数列表不同:
参数个数
参数类型
考虑类型先后属性
9.2 分类
无参构造方法:没有参数
public 类名(){}
有参构造方法:有具体的参数类型
public 类名(参数类型 变量名称){
...
}
9.3 注意事项
1)当我们开发者既没有提供无参构造方法,也没有提供有参构造方法,
系统永远给我们提供 "无参构造方法"
类名 对象名 = new 类名() ; //创建对象的格式
2)如果我们提供了有参构造方法,那么系统不会在提供无参构造方法
构造方法的作用:给类的成员属性可以进行数据初始化
给成员变量(私有修饰)赋值几种方式:
1)公共的访问方法setXXX(xx):赋值
2)有参构造方法进行赋值
public 类名(参数类型1 变量名1,参数类名2 变量名2...){
this.成员变量名1 = 变量1;
this.成员变量名2 = 变量2 ;
...
}
10 一个标准类的写法
使用学生类描述学生事物,并且进行测试
学生事物的属性
姓名,年龄
学生事物的行为:
学习
/*定义学生类
成员变量:私有化
name,age
构造方法:
无参/有参构造方法
成员方法:
setXXX(xx),getXXX()
study()
*/
class Student{
//成员变量私有化
private String name ;//姓名
private int age ; //年龄
private String gender ; //性别
//无参构造方法
public Student(){}
//有参构造方法
public Student(String name,int age){
this.name = name ;
this.age = age ;
}
//对外的公共访问方法setXXX(xx)/getXXX()
public void setName(String name){
this.name = name ;
}
public String getName(){
return name ;//获取学生姓名
}
public void setAge(int age){
this.age = age ; //给学生年龄赋值
}
public int getAge(){
return age ; //获取学生年龄
}
//其他的成员方法
public void study(){
System.out.println("正在学习java") ;
}
}
//测试类
class StudentTest{
public static void main(String[] args){
//方式1:测试
//无参构造方法+setXXX(xx)/getXXX()
//创建学生类对象
Student s = new Student() ;// 无参括号里没有对象
s.setName("周星星") ; // 用 setxxx方法赋值
s.setAge(29) ;;
System.out.println("该学生的姓名是"+s.getName()+
",年龄是:"+s.getAge()) ;
s.study() ;
System.out.println("---------------------------------------") ;
//方式2:测试
//有参构造方法+getXXX(),直接创建对象时完成赋值
Student s1 = new Student("陈小刀",30) ;
System.out.println("该学生的姓名是"+s1.getName()+
",年龄是:"+s1.getAge()) ;
s1.study() ;
}
}