&&&&&&&&&总结
1,构造方法(重中之重)
语法格式,默认构造方法,实现成员变量的初始化
2,方法重载(重点)
概念,体现形式,实际意义
3,this关键字
概念,原理,使用方式
4,递归(难点)
概念,使用原则
5,封装(重中之重)
概念,实现流程
目录
## 11, 编程实现学生信息的录入和打印(Student类的测试)
&&&方法
1,构造方法的定义
class 类名 {
类名(形参列表) {
构造方法体
}
}
例如:
class Person {
Person() { -Person类中的构造方法
}
}
构造方法名与类名完全相同且没有返回值类型,连void都不许有
2,默认构造方法
当一个类中没有定义任何构造方法时,编译器会自动添加一个无参空构造方法,
叫做默认/缺省构造方法, 如Person(){}
若类中出现了构造方法,则编译器不再提供任何形式的构造方法
3,构造方法的作用
使用 new 关键字创建对象时会自动调用构造方法实现成员变量初始化工作.
4,方法重载
a,概念
若方法名称相同,参数列表不同,则构成重载(Overload)
b,体现形式
参数的个数不同
参数的类型不同
参数的顺序不同
与返回值的类型无关,但建议返回值类型最好相同
c,实际意义
对于调用者,记住一个方法名就可以调用各种不同版本
5,this 关键字
a,基本概念
构造方法中:代表当前正在构造的对象
成员方法中:代表当前正在调用的对象
当前类 类型的引用变量
b,工作原理
构造方法和成员方法中访问成员变量时,编译器会加上this.的前缀
this相当于 "我的" ,当不同的对象调用同一个方法时,由于调用方
法的对象不同导致this关键字的不同,从而结果就不同
c,使用方式
为什么成员方法中可以直接访问成员变量,
是因为成员方法中默认使用了 this 关键字,例如 this.name
* 局部变量名和成员变量名相同时,在方法体重优先使用局部变量(就近原则);
若希望使用成员变量,则需要在成员变量前加上 this. 明确要求该变量是成员变量//(重中之重)
* this关键字除了可以使用this.的方式调用成员变量和成员方法外,还可以作为方法的返回值//(重点)
* 在构造方法的第一行,可以使用this调用本类的其他构造方法
6,引用变量的注意事项
a,引用类型变量用于存放对象的地址,可以给引用类型赋值为null,表示不指向任何对象
b,当某个引用类型变量为null时无法对对象实施访问(因为它没有指向任何对象)
此时,若通过引用访问成员变量或调用方法,会产生NullPointerException异常
7,递归
a,基本概念
在方法体内部直接或间接调用当前方法自身的形式
b,注意事项
必须有递归规律且有退出条件
必须使问题简单化而不是复杂化
若递归影响到程序的执行性能,则使用递推取代之
8,代码的拆分
&&&封装
1,概念
通常情况下可以在测试类给成员变量赋值一些合法但是不合理的数值,
无论是编译阶段还是运行阶段都不会报错或者给出提示,此时与现实生活不符
为了避免上述错误的发生, 就需要对成员变量进行密封包装处理,
来隐藏成员变量的细节以及保证成员变量的合理性,该机制就叫做封装
2,封装的实现
私有化成员变量 使用private修饰
提供公有的get和set方法,并在方法体中进行合理值的判断
在构造方法中调用set方法进行合理值的判断
3,JavaBean的概念(了解) //封装类
是一种Java语言写成的可重用组件,其他Java类可以通过
反射机制发现和操作这些JavaBean的属性
本质上就是符合以下标准的Java类
类是公共的
有一个无参的公共构造器
有属性, 且有对应的get set方法
## 1, 编程实现Person类的定义
/*
编程实现Person类的定义
*/
public class Person {
String name; //描述姓名
int age; //描述年龄
//分割线
void cut() {
System.out.println();
System.out.println("-------------------------------------------");
System.out.println();
}
//自定义构造方法
//String = "张飞";
//age = 30;
//String = "张飞";
//age = 35;
//就近原则 懒人原则
Person(String name, int age) { //开发中推荐用相同的名字,提高可读性
//System.out.println("我就是自定义的构造方法!");
//name = "张飞";
//age = 30;
this.name = name; //这里的name都是形参的name,自己给自己赋值
this.age = age; //由于就近原则有歧义,所以需要改造
}
//自定义无参构造方法
Person(){}
//自定义成员方法打印所有特征 隐含着this关键字 即this.name, this关键字代表当前正在调用的对象
// Person this = p1; this.name = p1.name = 张飞
// Person this = p2; this.name = p2.name = 关羽
void show() {
//每当打印成员变量的数值时,让年龄增长一岁
//this.grow();
//grow();
System.out.println("我是" + name + ",今年" + age + "岁了");
}
//自定义成员方法实现年龄增长一岁的行为
void grow() {
age++; //由于无歧义,所以不改造
}
//自定义成员方法实现年龄增长参数指定数值的行为
void grow(int age) {
this.age += age;
}
//自定义成员方法实现Person类型对象的获取并返回的行为
//String getName() {}
Person getPerson() {
//返回当前调用对象本身 Person tp = new Person(); return tp;
return this;
}
public static void main(String[] args) {
//1.声明一个Person类型的引用指向Person类型的对象
//当类中没有提供构造方法时,则下面调用默认构造方法,若类中提供构造方法
//则下面调用类中提供的版本
Person p1 = new Person("张飞", 30);
p1.cut();
//并打印特征
p1.show(); //null 0
Person p2 = new Person("关羽", 35);
p2.show();
Person p3 = new Person();
p3.show();
p1.cut();
//2.实现重载方法的调用和测试
p1.grow();
p1.show(); //张飞 31
p1.grow(3);
p1.show(); //张飞 34
p1.cut();
//3.调用成员方法获取对象
Person p4 = p1.getPerson();
System.out.println("p1 = " + p1);
System.out.println("p4 = " + p4);
}
}
## 2, 编程实现Point类的定义
/*
编程实现Point类的定义
*/
public class Point {
int x; //描述横坐标
int y; //描述纵坐标
//分割线
void cut() {
System.out.println();
System.out.println("-------------------------------------------");
System.out.println();
}
void up() {
y--;
}
void up(int y) {
this.y -= y;
}
//自定义无参构造方法
Point() {}
Point(int x, int y) {
this.x = x;
this.y = y;
}
//自定义成员方法实现打印特征
void show() {
System.out.println("横坐标是:"+ x + ", 纵坐标是" + y);
}
public static void main(String[] args) {
//1.使用无参方式构造对象并打印
Point p1 = new Point();
p1.cut();
p1.show();
//2.使用有参方式构造对象并打印
Point p2 = new Point(3, 5);
p2.show(); //3 5
p1.cut();
//3.重载的调用和测试
p2.up();
p2.show();
p2.up(2);
p2.show();
}
}
## 3, 编程实现,方法重载主要形式的测试
/*
编程实现,方法重载主要形式的测试
*/
public class OverloadTest {
//自定义成员方法
void show() {
System.out.println("show()");
}
void show(int i) { //ok 体现在方法参数的个数不同
System.out.println("show(int)");
}
void show(int i, double d) { //ok 体现在方法参数的个数不同
System.out.println("show(int, double)");
}
void show(int i, int j) { //ok 体现在方法参数的类型不同
System.out.println("show(int, int)");
}
void show(double d, int j) { //ok 体现在方法参数的顺序不同
System.out.println("show(int, int)");
}
/*
void show(double a, int b) { // error 与形参的变量名无关
System.out.println("show(int, int)");
}
*/
/*
int show(double a, int b) { // error 与返回值类型无关
System.out.println("show(int, int)");
}
*/
public static void main(String[] args) {
//1,声明OverloadTest类型的引用指向该类型的对象
OverloadTest ot = new OverloadTest();
//2,调用show方法
ot.show();
ot.show(66);
ot.show(66, 3.14);
ot.show(66, 118);
ot.show(3.14, 118);
//ot.show(3.14, 66);
}
}
## 4, 编程实现,this 关键字的使用
/*
编程实现,this 关键字的使用
*/
public class ThisTest {
//分割线
void cut() {
System.out.println();
System.out.println("-------------------------------------------");
System.out.println();
}
//自定义构造方法
ThisTest() {
//this代表当前正在构造的对象
System.out.println("构造方法中this = " + this);
}
//自定义成员方法
void show() {
System.out.println("成员方法中this = " + this);
}
public static void main(String[] args) {
System.out.println();
System.out.println("-------------------------------------------");
System.out.println();
//1.声明ThisTest类型的引用指向该类型的对象
ThisTest tt = new ThisTest();
//2.调用show方法
tt.show();
System.out.println("main方法中 tt = " + tt);
}
}
## 5, 编程实现Boy类的定义
/*
编程实现Boy类的定义
*/
public class Boy {
String name; //用于描述姓名的成员变量
//自定义构造方法
Boy() {
//调用本类中的有参构造方法
//this("无名");
System.out.println("无参构造方法");
}
Boy(String name) {
//调用本类的无参构造方法
this();
System.out.println("================有参构造方法");
this.name = name;
}
void show() {
System.out.println("我的名字是:" + name);
}
public static void main(String[] args) {
//1.使用无参方式构造对象并打印特征
Boy b1 = new Boy();
b1.show(); //null
System.out.println("-------------------------------------------");
//2.使用有参方式构造 对象并打印特征
Boy b2 = new Boy("张飞");
b2.show(); //张飞
System.out.println("-------------------------------------------");
//3.引用变量的数值可以为空
//Boy b3 = null;
//b3.show(); //编译ok,运行会发生NullPointerException 空指针异常 算术异常 数组下标越界异常
Boy b3 = b2;
b3.show();
}
}
## 6, 编程实现,费式数列
/*
编程实现,费式数列的第n项的数值并打印 功能类/封装类
*/
public class Fee {
//自定义成员方法实现费氏数列中第n项数值的计算,并返回,n由参数指定
// 1 1 2 3 5 8 13 21...
int show(int n) {
//1.使用递归的方式进行计算
/*
//当n=1或者n=2时.结果是1
if(1 == n || 2 ==n) {
return 1;
}
//否则结果是前两项的和
return show(n-1) + show(n-2);
//show(5) => return show(4) + show(3); => 5
//show(4) => return show(3) + show(2); => 3
//show(3) => return show(2) + show(1); => 2
//show(2) => return 1; => 1
//show(1) => return 1; => 1
*/
int ia = 1;
int ib = 1;
if(n > 2) {
for(int i = 3; i <= n; i++) {
int ic = ib + ia;
ia = ib;
ib = ic;
}
}
return ib;
}
}
## 7, 编程实现对费氏数列类的测试
/*
编程实现对费氏数列类的测试
*/
public class FeeTest {
public static void main(String[] args) {
//1.声明FeeTest类型的引用指向该类型的变量
Fee ft = new Fee();
//2.调用方法计算并打印
int res = ft.show(55);
System.out.println("计算的结果是:" + res); // 5
}
}
## 8, 编程实现, 阶乘的计算并打印
/*
编程实现, 累乘积的计算并打印
*/
public class JieCheng {
//自定义实现将参数n的阶乘计算并返回
int show(int n) { //int n =5
//递推的方式
/*
int num = 1;
for(int i = 1; i <= n; i++) {
num *= i;
}
return num;
}
5! = 5 * 4 * 3 * 2 * 1
4! = 4 * 3 * 2 * 1
3! = 3 * 2 * 1
2! = 2 * 1
1! = 1
5! = 5 * 4!
4! = 4 * 3!
3! = 3 * 2!
2! = 2 * 1!
1! = 1
n! = n * (n-1)!;
*/
//递归的方式
//当n的数值为1时,则阶乘的结果就是1
/*if(1 == n) {
return 1;
}*/
if(1 == n) return 1;
//否则阶乘结果就是n*(n-1)!
return n*show(n-1); //自己调用自己 递归
// show(5) => return 5*show(4); => 5*4*3*2*1
// show(4) => return 4*show(3); => 4*3*2*1
// show(3) => return 3*show(2); => 3*2*1
// show(2) => return 2*show(1); => 2*1
// show(1) => return 1; => 1
}
public static void main(String[] args) {
//1.声明JieCheng类型的引用指向该类型的对象
JieCheng jc = new JieCheng();
//2.调用方法进行计算并打印
int res = jc.show(5);
System.out.println("最终的计算结果是:" + res); //120
}
}
## 9, 编程实现Student类的定义, 封装 封装类
/*
编程实现Student类的封装 封装类
*/
public class Student {
//1.私有化成员变量,使用private关键字
//private关键字表示私有的含义,也就是该成员变量只能在当前类的内部使用
private int id; //描述学号
private String name; //描述姓名
//在公有的构造方法中调用set方法进行合理值的判断
public Student() {}
public Student(int id, String name) {
//this.id = id;
//this.name = name;
setId(id);
setName(name);
}
//2.提供公有的get和set方法,并在方法体中进行合理值的判断
//使用public关键字修饰,该方法可以在任意位置的使用
public int getId() {
return id;
}
public void setId(int id) {
if(id > 0) {
this.id = id;
} else {
System.out.println("学号不合理哦!");
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//自定义成员方法实现特征的打印
//什么修饰符都没有是默认的访问权限,介于private和public之间
public void show() {
//System.out.println("我是" + name + ", 我的学号是" + id);
System.out.println("我是" + getName() + ", 我的工号是" + getId());
}
public void cut() {
System.out.println();
System.out.println("-------------------------------------------");
System.out.println();
}
}
## 10, 编程实现Student类的测试
/*
编程实现Student类的测试
*/
public class StudentTest {
public static void main(String[] args) {
//1.声明Student类型的引用变量指向Student类型的对象
Student s1 = new Student();
s1.cut();
//3.对成员变量进行复制并打印
//s1.id = -1001; //合法但是不合理
//s1.id = 1001;
//s1.name = "张飞";
s1.setId(-1001);
s1.setName("张飞");
s1.show(); //1001 张飞
s1.cut();
//3.使用有参方式构造对象并打印特征
Student s2 = new Student(-1001, "张飞");
s2.show();
s2.cut();
}
}
## 11, 编程实现学生信息的录入和打印(Student类的测试)
/*
编程实现学生信息的录入和打印
*/
import java.util.Scanner;
public class StudentTest2 {
public static void main(String[] args) {
System.out.println();
//1.提示用户输入学生的人数并使用变量记录
System.out.println("请输入人数:");
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
System.out.println();
//2.根据学生的人数准备对应的一位数组
// int arr = new int [3] - 表示声明一个长度为3元素类型为int的一位数组
// 数组中的每个元素都是int类型,也就是说数组中的每个元素都可以看做是一个int类型的变量
//下面的代码是声明一个长度为n,元素类型为Student类型的一位数组
//数组中的每个元素都是Student类型, 也就是说数组中的每个元素都可以看做是Student类型的变量
// st[0] = new Student();
Student[] st = new Student[n];
//3.提示用户输入每个学生的信息(学号,姓名)并记录到一位数组中
for(int i = 0; i < n; i++) {
System.out.println("请输入第" + (i+1) + "个人的姓名和工号(例如: 6666 曹操 ):");
st[i] = new Student(sc.nextInt(), sc.next());
System.out.println();
}
for(int i = 0; i < n; i++) {
st[i].show();
}
}
}