一、三大特征
①封装性
②继承性
③多态性
二、类和对象
①类是对一类事物的描述,是抽象的、概念上的定义
②对象是实际存在的该类事务的每个个体,也称为实例
③万事万物皆为对象
|-常见的类成员:
属性:对应类中的成员变量
行为:对应类中的成员方法
属性=成员变量=filed=域、字段
方法=成员变量=函数=method
创建类的队象=类的实例化=实例化类
例:类和对象的使用
package com.atguigu.java;
//测试类
public class PersonTest {
public static void main(String[] args) {
//创建Person的类对象
Person p1 = new Person();
//调用对象的结构:属性、方法
//调用属性:"对象.属性"
p1.name = "Tom";
p1.isMale =true;
System.out.println( p1.name );
//调用方法:"对象.方法"
p1.eat();
p1.sleep();
p1.talk("Chinese");
}
}
class Person{
//属性
String name;
int age = 1;
boolean isMale;
//方法
public void eat() {
System.out.println("人可以吃饭");
}
public void sleep() {
System.out.println("人可以睡觉");
}
public void talk(String language) {
System.out.println("人可以说话" + language);
}
}
④如果创建了一个类的多个对象,则每个对象都独立的拥有一套类的属性(非static的),如果修改一个对象的属性a,则不影响另外一个对象属性a的值
例:
package com.atguigu.java;
//测试类
public class PersonTest {
public static void main(String[] args) {
//创建Person的类对象
Person p1 = new Person();
//*********************************
Person p2 = new Person();
System.out.println(p2.name);
System.out.println(p2.isMale);
//**********************************
//将p1变量保存的对象地址值付给p3,导致p1和p3指向了堆空间中的同一个对象实体
Person p3 = p1;
System.out.println(p3.name);
p3.age = 10;
System.out.println(p1.age);
}
}
class Person{
//属性
String name;
int age = 1;
boolean isMale;
//方法
public void eat() {
System.out.println("人可以吃饭");
}
public void sleep() {
System.out.println("人可以睡觉");
}
public void talk(String language) {
System.out.println("人可以说话" + language);
}
}
三、对象的内存解析
四、属性与局部变量的对比
①属性(成员变量)& 局部变量
|-相同点:
定义变量的格式:数据类型 变量名 = 变量值
先声明,后使用
变量都有其对应的作用域
|-不同点:
①在类中声明的位置不同
属性:直接定义在类的一对{}内
局部变量:声明在方法内、方法形参、代码块内、构造形参、构造器内部的变量
②关于权限修饰符
属性:可以在声明属性时,指明其权限,使用权限修饰符
常用的权限修饰符:private、public、缺省、protected
局部变量:不可以使用权限修饰符
③默认初始化值的情况:
属性:类的属性,根据其类型,都有默认初始化值
整型:(byte、short、int、long):0
浮点型:(float、double):0.0
字符型:(char):0(或、\u0000)
布尔型:(boolean):false
引用数据类型:null
局部变量:没有默认初始化值,所以在调用局部变量之前。一定要显式赋值
特别地:形参在调用时赋值即可
④在内存中加载的位置:
属性:加载到堆空间中(非static)
局部变量:加载到栈空间
例:
package com.atguigu.java;
public class UserTest {
public static void main(String[] args) {
User u1 = new User();
System.out.println(u1.name);
System.out.println(u1.age);
System.out.println(u1.isMale);
u1.talk("日语");
u1.eat();
}
}
class User{
//属性(或成员变量)
String name;
int age;
boolean isMale;
public void talk(String language) {//language:形参
System.out.println("我们使用" + language +"交流");
}
public void eat() {
String food = "烙饼";//局部变量
System.out.println("北方人喜欢吃:" + food);
}
}
五、类中方法的声明和使用
方法:描述类应该具有的功能
比如:Math类、sqrt()、random()、
scanner类
Arrays类、sort()、binarySearch()、equals()
分类:按照是否有形参及返回值
声明:
权限修饰符 返回值类型 方法名 (形参列表){
方法体;
}
说明:
①关于权限修饰符
private、public、缺省、protected
②返回值类型:有返回值&无返回值
1.如果方法有返回值,则必须在方法声明时,指定返回值的类型,同时方法中需要使用return关键字来指定类型的变量或常量
2.如果方法没有返回值,则声明方法时,使用void来表示,通常没有返回值的方法中就不需要使用return,如果使用的话,只能“return;”,表示结束此方法,return后不可以使用执行语句
3.该不该有返回值?
①题目要求
②凭经验,具体问题具体分析
方法名:
①属于标识符,遵循标识符的规则和规范,“见名知意”
形参列表:
①方法可以声明0、1个或多个形参
②格式:数据类型1 形参1,数据类型2 形参2…
③该不该定义形参?
1.题目要求
2.凭经验,具体问题具体分析
方法体:方法功能的体现。
例:
package com.atguigu.java;
public class CustomerTest {
}
//客户类
class Customer{
//属性
String name;
int age;
boolean isMale;
//方法
public void eat(){
System.out.println("客户吃饭");
}
public void sleep(int hour) {
System.out.println("休息了"+hour+"个小时");
}
public String getName() {
return name;
}
public String getNation(String nation) {
String info = "我的国籍是:"+ nation;
return info;
}
}
六、return关键字的使用
①使用范围:使用在方法体中
②作用:结束方法、针对于有返回值类型的方法,使用"return 数据" 方法返回所要的数据
③注意点:return关键字后面不可以声明执行语句
七、方法使用中的注意点:
①可以调用当前类的属性或方法
②特殊的:方法A中又调用了方法A:递归方法
③方法中,不可以定义方法
八、理解:万事万物皆对象
①在Java语言的范畴中,我们都将功能、结构等封装到类中,通过类的实例化,来调用具体的功能结构
|-Scanner,String等
|-文件:File
|-网络资源:URL
②涉及到Java语言与前端HTML交互时、后端的数据库交互时,前后端的结构在Java层面交互时,都体现为类、对象
九、对象数组内存解析
①引用类型的变量,只可能存储两类值:null或地址值(含变量类型)
例:
package com.guigu.exer;
public class StudentTest {
public static void main(String[] args) {
// 声明student的数组
Student[] stus = new Student[20];
for (int i = 0; i < stus.length; i++) {
// 给数组元素赋值
stus[i] = new Student();
// 给student的属性赋值
stus[i].number = (i + 1);
// 年级【1-6】
stus[i].state = (int) (Math.random() * (6 - 1 + 1) + 1);
// 成绩【0-100】
stus[i].score = (int) (Math.random() * (100 - 0 + 1));
}
// 遍历学生数组
for (int i = 0; i < stus.length; i++) {
System.out.println(stus[i].info());
}
System.out.println("*********************");
//冒泡排序按学生成绩排序,并遍历所有学生信息
for (int i = 0; i < stus.length - 1; i++) {
for (int j = 0; j < stus.length - 1 - i; j++) {
if (stus[j].score > stus[j + 1].score) {
//如果交换顺序,交换的是数组元素
Student temp =stus[j];
stus[j] = stus[j + 1];
stus[j + 1] = temp;
}
}
}
// 遍历学生数组
for (int i = 0; i < stus.length; i++) {
System.out.println(stus[i].info());
}
//打印出三年级的学生信息
for (int i = 0; i < stus.length; i++) {
if (stus[i].state == 3) {
System.out.println(stus[i].info());
}
}
}
}
class Student {
int number;// 学号
int state;// 年级
int score;// 成绩
//显式学生信息方法
public String info() {
return "学号:" + number +",年级" + state + ",成绩:" + score;
}
}
改进:
package com.guigu.exer;
/*
* 4. 对象数组题目:
定义类Student,包含三个属性:学号number(int),年级state(int),成绩score(int)。
创建20个学生对象,学号为1到20,年级和成绩都由随机数确定。
问题一:打印出3年级(state值为3)的学生信息。
问题二:使用冒泡排序按学生成绩排序,并遍历所有学生信息
提示:
1) 生成随机数:Math.random(),返回值类型double;
2) 四舍五入取整:Math.round(double d),返回值类型long。
*
*
* 此代码是对StudentTest.java的改进:将操作数组的功能封装到方法中。
*
*/
public class StudentTest1 {
public static void main(String[] args) {
//声明Student类型的数组
Student1[] stus = new Student1[20];
for(int i = 0;i < stus.length;i++){
//给数组元素赋值
stus[i] = new Student1();
//给Student对象的属性赋值
stus[i].number = (i + 1);
//年级:[1,6]
stus[i].state = (int)(Math.random() * (6 - 1 + 1) + 1);
//成绩:[0,100]
stus[i].score = (int)(Math.random() * (100 - 0 + 1));
}
StudentTest1 test = new StudentTest1();
//遍历学生数组
test.print(stus);
System.out.println("********************");
//问题一:打印出3年级(state值为3)的学生信息。
test.searchState(stus, 3);
System.out.println("********************");
//问题二:使用冒泡排序按学生成绩排序,并遍历所有学生信息
test.sort(stus);
//遍历学生数组
test.print(stus);
}
/**
*
* @Description 遍历Student1[]数组的操作
* @author shkstart
* @date 2019年1月15日下午5:10:19
* @param stus
*/
public void print(Student1[] stus){
for(int i = 0;i <stus.length;i++){
System.out.println(stus[i].info());
}
}
/**
*
* @Description 查找Stduent数组中指定年级的学生信息
* @author shkstart
* @param stus 要查找的数组
* @param state 要找的年级
*/
public void searchState(Student1[] stus,int state){
for(int i = 0;i <stus.length;i++){
if(stus[i].state == state){
System.out.println(stus[i].info());
}
}
}
/**
*
*
* @date 2019年1月15日下午5:09:46
* @param stus
*/
public void sort(Student1[] stus){
for(int i = 0;i < stus.length - 1;i++){
for(int j = 0;j < stus.length - 1 - i;j++){
if(stus[j].score > stus[j + 1].score){
//如果需要换序,交换的是数组的元素:Student对象!!!
Student1 temp = stus[j];
stus[j] = stus[j + 1];
stus[j + 1] = temp;
}
}
}
}
}
class Student1{
int number;//学号
int state;//年级
int score;//成绩
//显示学生信息的方法
public String info(){
return "学号:" + number + ",年级:" + state + ",成绩:" + score;
}
}
十、匿名对象的使用
①理解:创建的对象,没有显示的赋给一个变量名,即为匿名对象
②特征:匿名对象只能调用一次
③使用:
例:匿名对象的使用
package com.atguigu.java;
public class InstanceTest {
public static void main(String[] args) {
Phone p = new Phone();
System.out.println(p);
p.sedEmail();
p.playGame();
//匿名对象
// new Phone().sedEmail();
// new Phone().playGame();
new Phone().price = 2000;
new Phone().showPrice();
//***************************
PhoneMall mall =new PhoneMall();
//匿名对象的使用
mall.show(new Phone());
}
}
class PhoneMall{
public void show(Phone phone) {
phone.sedEmail();
phone.playGame();
}
}
class Phone {
double price;
public void sedEmail() {
System.out.println("发送邮件");
}
public void playGame() {
System.out.println("玩游戏");
}
public void showPrice() {
System.out.println("手机价格为:" + price);
}
}
十一、自定义数组的工具类
例:数组的工具类
package com.atguigu.java;
public class ArrayUtil {
// 求数组的最大值
public int getMax(int[] arr) {
int maxValue = arr[0];
for (int i = 0; i < arr.length; i++) {
if (maxValue < arr[i]) {
maxValue = arr[i];
}
}
return maxValue;
}
// 求数组的最小值
public int getMin(int[] arr) {
int minValue = arr[0];
for (int i = 0; i < arr.length; i++) {
if (minValue > arr[i]) {
minValue = arr[i];
}
}
return minValue;
}
// 求数组的总和
public int getSum(int[] arr) {
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
}
return sum;
}
// 求数组的平均值
public int getAvg(int[] arr) {
return getSum(arr) / arr.length;
}
// 反转数组
public void reverse(int[] arr) {
for (int i = 0; i < arr.length / 2; i++) {
int temp = arr[i];
arr[i] = arr[arr.length - i - 1];
arr[arr.length - i - 1] = temp;
}
}
// 复制数组
public int[] copy(int[] arr) {
int[] arr1 = new int[arr.length];
for (int i = 0; i < arr1.length; i++) {
arr1[i] = arr[i];
}
return arr1;
}
// 数组排序
public void sort(int[] arr) {
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}
}
// 遍历数组
public void print(int[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " \t");
}
System.out.println();
}
// 查找指定元素
public int getIndex(int[] arr, int dest) {
for (int i = 0; i < arr.length; i++) {
if (dest == (arr[i])) {
return i;
}
}
return -1;// 返回一个复数,表示没找到
}
}
测试类:
package com.atguigu.java;
public class ArrayUtilTest {
public static void main(String[] args) {
ArrayUtil util = new ArrayUtil();
int[] arr = new int[] { 2, 5, 6, 8, 10, 12, 13, 6 };
int max = util.getMax(arr);
System.out.println("最大值为:" + max);
System.out.println("排序前:");
util.print(arr);
System.out.println();
System.out.println("排序后:");
util.sort(arr);
System.out.println();
System.out.println("查找:");
int index = util.getIndex(arr, 6);
if (index > 0) {
System.out.println("找到了,索引地址为:" + index);
} else {
System.out.println("未找到!");
}
}
}
十二、理解方法的重载
①概念:在同一个类中,允许存在一个以上的同名方法,只要他们的参数个数或者参数类型不同即可
|-“两同一不同”:同一个类,相同方法名;参数列表不同,参数个数不同,参数类型不同
|-判断是否是重载:跟方法的权限修饰符、返回值类型、形参变量名、方法体都没关系
|-在通过对象调用方法时,如何确定某一个指定的方法:
方法名—>参数列表
例:
package com.atguigu.java;
public class OverLoadTest {
public void getSum(int i, int j) {
System.out.println(i + j);
}
public void getSum(double d1, double d2) {
}
public void getSum(String s, int i) {
}
public void getSum(int i, String s) {
}
}
例:
package com.atguigu.exer;
public class OverloadExer {
public void mOL(int i) {
System.out.println(i * i);
}
public void mOL(int i, int j) {
System.out.println(i * j);
}
public void mOL(String s) {
System.out.println(s);
}
// ------------------------------------------
public int max(int i, int j) {
return (i > j) ? i : j;
}
public double max(double d1, double d2) {
return (d1 > d2) ? d1 : d2;
}
public double max(double d1, double d2, double d3) {
double max = (d1 > d2) ? d1 : d2;
return (max > d3) ? max : d3;
}
}
十三、可变个数的形参
①Varargs(variable number of argments)机制,允许直接定义能和多个是实参匹配的形参
|-格式:数据类型 ... 变量名
|-当调用可变个数形参方法时,传入的参数个数可以是:0个,1个,2个.........
|-可变个数形参的方法与本类中方法名相同,形参不同的方法名之间构成重载
|-可变个数形参的方法与本类中方法名相同,形参类型也相同的数组之间不构成重载,二者不能共存
|-可变个数形参在方法的形参中必须声明在末尾
|-可变个数形参在方法的形参中,最多只能声明一个可变形参
例:
package com.atguigu.exer;
public class MethodArgsTest {
public static void main(String[] args) {
MethodArgsTest test = new MethodArgsTest();
test.show(12);
test.show("hell");
test.show("aa", "bb", "cc");
}
public void show(int i) {
}
public void show(String s) {
System.out.println("show(String)");
}
public void show(String... strs) {// 可变个数的形参
System.out.println("show(String ... strs)");
for (int i = 0; i < strs.length; i++) {
System.out.println(strs[i]);
}
}
// 可变个数形参在方法的形参中必须声明在末尾
public void show(int i, String... strs) {
}
}
十四、理解变量的赋值
①如果变量是基本数据类型,此时赋值的是变量所保存的数据值
②如果变量是引用数据类型,此时赋值的是变量所保存的数据的地址值
例:
package com.atguigu.java;
public class ValueTransferTest {
public static void main(String[] args) {
System.out.println("************基本数据类型:**************");
int m = 10;
int n = m;
System.out.println("m = " + m + " , n =" + n);
n = 20;
System.out.println("m = " + m + " , n =" + n);
System.out.println("************引用数据类型:**************");
Oreder o1 = new Oreder();
o1.orderId = 1001;
Oreder o2 = o1;// 赋值以后,o1和o2的地址值相同,都指向了堆空间中同一个对象实体
System.out.println("o1.orderId " + o1.orderId + ",o2.orderId=" + o2.orderId);
o2.orderId = 1002;
System.out.println("o1.orderId " + o1.orderId + ",o2.orderId=" + o2.orderId);
}
}
class Oreder {
int orderId;
}
十五、值传递机制
1.针对基本数据类型:
|-形参:方法定义时,声明的小括号内的参数
|-实参:方法调用时,实际春递给形参的数据
①值传递机制:
|-如果参数是基本数据类型,此时实参赋给形参的是,实参真实存储的数据值
|-如果参数是引用数据类型,此时实参赋给形参的是实参存储数据的地址值
例:
package com.atguigu.java;
public class ValueTransferTest2 {
public static void main(String[] args) {
Data data = new Data();
data.m = 10;
data.n = 20;
System.out.println("m = " + data.m + ", n = " + data.n);
// 交换m和n的值
// int temp = data.m;
// data.m = data.n;
// data.n = temp;
ValueTransferTest2 test = new ValueTransferTest2();
test.swap(data);
System.out.println("m = " + data.m + ", n = " + data.n);
}
public void swap(Data data) {
int temp = data.m;
data.m = data.n;
data.n = temp;
}
}
class Data {
int m;
int n;
}
public void sort(int[] arr) {
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
// int temp = arr[j];
// arr[j] = arr[j + 1];
// arr[j + 1] = temp;
// swap(arr[j], arr[j + 1]);
swap(arr, j, j + 1);
}
}
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}
}
// 交换数组中指定两个位置元素的值
public void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
②参数传递的编码练习
例:将对象作为参数传递给方法
package com.atguigu.exer;
public class PassObject {
public static void main(String[] args) {
PassObject test = new PassObject();
Circle c = new Circle();
test.printAreas(c, 5);
System.out.println("now radius is:" + c.radius);
}
public void printAreas(Circle c, int time) {
System.out.println("Radius\t\tArea");
// 设置圆的半径
for (int i = 1; i <= time; i++) {
// 设置圆的半径
c.radius = i;
double area = c.findArea();
System.out.println(c.radius + "\t\t" + area);
// System.out.println(c.radius + "\t\t" + c.findArea());
}
c.radius = time + 1;
}
}
十六、递归(Recrusion)方法的使用
①递归方法:一个方法体内调用它自身
|-方法递归包含了一种隐式的循环,它会重复执行某段代码,但这种重复执行无须循环控制
|-递归一定要向已知方向递归,否则这种递归就变成无穷递归,类似于死循环
例:
package com.atguigu.java;
public class RecrusionTest {
public static void main(String[] args) {
// 计算1-n之间所有自然数的和
// 方式一:
int sum = 0;
for (int i = 0; i <= 100; i++) {
sum += i;
}
System.out.println(sum);
// 方式二:使用递归实现
RecrusionTest test = new RecrusionTest();
int sum1 = test.getsum(100);
System.out.println(sum1);
System.out.println("****************");
int value = test.f(10);
System.out.println(value);
}
public int getsum(int n) {
if (n == 1) {
return 1;
} else {
return n + getsum(n - 1);
}
}
// 计算1-n之间所有自然数的乘积
public int getsum1(int n) {
if (n == 1) {
return 1;
} else {
return n * getsum1(n - 1);
}
}
// 求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);
}
}
}
十七、封装与隐藏
①高内聚:类的内部数据操作细节自己完成,不允许外部干涉
低耦合:仅对外暴露少量的方法用于使用
②创建一个对象之后,我们可以通过“对象.属性”的方式,对对象的属性进行赋值。赋值操作要受到属性的数据类型和存储范围的制约,但是除此之外没有其他制约条件,在实际问题中,我们往往需要给属性赋值加入额外限制条件,这个条件就不能在属性声明时体现,只能通过方法进行限制条件的添加,同时需要避免用户再使用“对象.属性”的方式对属性进行赋值,则需要将属性声明为私有的(private),此时就体现了封装性。
例:
package com.atguigu.java;
public class AimalTest {
public static void main(String[] args) {
Animal a = new Animal();
a.name = "花花";
a.age = 1;
a.legs = 4;
a.show();
a.setlegs(6);
a.show();
}
}
class Animal {
String name;
int age;
int legs;// 腿的个数
public void setlegs(int l) {
if (l >= 0 && l % 2 == 0) {
legs = l;
} else {
legs = 0;
}
}
public void eat() {
System.out.println("动物进食");
}
public void show() {
System.out.println("name = " + name + ",age = " + age + ",legs =" + legs);
}
}
③封装性的体现:
将类的属性xxx私有化(private),同时提供公共的(public)方法来获取(get xxx)和设置(set xxx)此属性的值
拓展:
|-不对外暴露的私有的方法
|-单例模式
例:
package com.atguigu.java;
public class AimalTest {
public static void main(String[] args) {
Animal a = new Animal();
a.name = "花花";
// a.age = 1;
// a.legs = 4;
a.show();
a.setlegs(6);
a.show();
}
}
class Animal {
String name;
private int age;
private int legs;// 腿的个数
// 对属性的设置
public void setlegs(int l) {
if (l >= 0 && l % 2 == 0) {
legs = l;
} else {
legs = 0;
}
}
// 对属性的获取
public int getLegs() {
return legs;
}
public void eat() {
System.out.println("动物进食");
}
public void show() {
System.out.println("name = " + name + ",age = " + age + ",legs =" + legs);
}
// 提供关于属性age的get和set方法
public int getAge() {
return age;
}
public void setAge(int a) {
age = a;
}
}
④封装性的体现需要权限修饰符来配合
|-4种权限:private、default(缺省)、protected、public
|-都可以修饰类及类的内部结构:属性、方法、构造器、内部类
|-都可以修饰类的内部结构:属性、方法、构造器、内部类
|-修饰类只能使用:default(缺省)、public
例:
package com.atguigu.java;
public class Order {
private int orderPrivate;
int orderDefault;
public int orderPublic;
private void methodPrivate() {
orderPrivate = 1;
orderDefault = 2;
orderPublic = 3;
}
void methodDefault() {
orderPrivate = 1;
orderDefault = 2;
orderPublic = 3;
}
public void methodPublic() {
orderPrivate = 1;
orderDefault = 2;
orderPublic = 3;
}
}
package com.atguigu.java;
public class OrderTest {
public static void main(String[] args) {
Order order = new Order();
order.orderDefault = 1;
order.orderPublic = 2;
// 出了Order类之后,私有的结构就不可以调用了
//order.orderPrivate = 3; // The field Order.orderPrivate is not visible
order.methodDefault();
order.methodPublic();\
// 出了Order类之后,私有的结构就不可以调用了
//order.methPrivate();//The method methPrivate() is undefined for the type Order
}
}
package com.atguigu.java1;
import com.atguigu.java.Order;
public class OrderTest {
public static void main(String[] args) {
Order order = new Order();
// 出了Order类所属的包之后,私有的结构、缺省声明的结构就不可以调用了
//order.orderDefault = 1;
order.orderPublic = 2;
// 出了Order类之后,私有的结构就不可以调用了
//order.orderPrivate = 3; // The field Order.orderPrivate is not visible
// 出了Order类所属的包之后,私有的结构、缺省声明的结构就不可以调用了
//order.methodDefault();
order.methodPublic();
// 出了Order类之后,私有的结构就不可以调用了
//order.methPrivate();//The method methPrivate() is undefined for the type Order
}
}
总结:
Java提供了四种权限修饰符来修饰类及类的内部结构,体现类及类的内部结构在被调用时的可见性的大小
例:
package com.atguigu.exer;
public class Person {
private int age;
public void setAge(int a) {
if (a < 0 || a > 130) {
System.out.println("传入的数据非法!");
return;
}
age = a;
}
public int getAge() {
return age;
}
//绝对不要这样写
// public int dogAge(int a) {
// age = a;
// return age;
// }
}
package com.atguigu.exer;
public class PersonTest {
public static void main(String[] args) {
Person p1 = new Person();
p1.setAge(12);
System.out.println("年龄为:" + p1.getAge());
}
}
十八、构造器(构造方法)constructor:建设者
①:作用
|-创建对象
|-初始化对象的信息
②:说明
|-如果没有显式的定义类的构造器的话,则系统默认提供一个空参的构造器
|-定义构造器的格式:权限修饰符 类名(形参列表){}
|-一个类中定义的构造器,彼此构成重载
|-一旦显式的定义了类的构造器之后,系统不再提供默认的空参构造器
|-一个类中,至少会有一个构造器
例:
package com.atguigu.java1;
public class PersonTest {
public static void main(String[] args) {
// 创建类的对象:new+构造器
Person p = new Person();
p.eat();
Person p1 = new Person("Tom");
System.out.println(p1.name);
}
}
class Person {
// 属性
String name;
int age;
// 构造器
public Person() {
System.out.println("Person()........");
}
public Person(String n) {
name = n;
}
public Person(String n, int a) {
name = n;
age = a;
}
// 方法
public void eat() {
System.out.println("人吃饭!");
}
public void study() {
System.out.println("人可以学习!");
}
}
例:
package com.atguigu.exer;
public class Person {
private int age;
private String name;
public Person() {
age = 18;
}
public Person(String n, int a) {
name = n;
age = a;
}
public void setAge(int a) {
if (a < 0 || a > 130) {
System.out.println("传入的数据非法!");
return;
}
age = a;
}
public int getAge() {
return age;
}
public void setName(String n) {
name = n;
}
public String getNanme() {
return name;
}
}
package com.atguigu.exer;
public class PersonTest {
public static void main(String[] args) {
Person p1 = new Person();
// p1.setAge(12);
System.out.println("年龄为:" + p1.getAge());
Person p2 = new Person("Tom", 21);
System.out.println("name = " + p2.getNanme() + ",age:" + p2.getAge());
}
}
例:
package com.atguigu.exer1;
public class TriAngle {
private double base;// 底边长
private double height;// 高
public TriAngle() {
}
public TriAngle(double b, double h) {
base = b;
height = h;
}
public void setBase(double b) {
base = b;
}
public double getBase() {
return base;
}
public void setHeight(double h) {
height = h;
}
public double getHeight() {
return height;
}
}
package com.atguigu.java1;
import com.atguigu.exer1.TriAngle;
public class PersonTest {
public static void main(String[] args) {
TriAngle t1 = new TriAngle();
t1.setBase(2.0);
t1.setHeight(2.4);
System.out.println("base:" + t1.getBase() + ",height:" + t1.getHeight());
TriAngle t2 = new TriAngle(5.1,5.6);
System.out.println("base:" + t2.getBase() + ",height:" + t2.getHeight());
}
}
总结:
属性赋值的先后顺序:
①默认初始化值
②显式初始化
③构造器中赋值
④通过"对象.方法"或“对象.属性”
以上操作顺序: ①-②-③-④
例:
package com.atguigu.java1;
public class UserTest {
public static void main(String[] args) {
User u = new User();
System.out.println(u.age);
User u1 = new User(2);
u1.setAge(3);
System.out.println(u1.age);
}
}
class User {
String name;
int age = 1;
public User() {
}
public User(int a) {
age = a;
}
public void setAge(int a) {
age = a;
}
}
十九、拓展
JavaBean的使用:
①:是一种Java语言写成的可重用组件
②:是指符合以下标准的Java类:
|-类是公共的
|-有一个无参的公共的构造器
|-有属性,且有对应的get、set方法
例:
package com.atguigu.java1;
public class Customer {
private int id;
private String name;
public Customer() {
}
public void setId(int i) {
id = i;
}
public int getId() {
return id;
}
public void setName(String n) {
name = n;
}
public String getName() {
return name;
}
}
UML类图:
二十、关键字:this的使用
①this可以用来修饰、调用:属性、方法、构造器
②this修饰属性和方法 :
|-this理解为:当前对象 或 当前正在创建的对象
|-在类的方法中,可以使用“this.属性”或“this.方法”的方式,调用当前对象的属性或方法,但是通常情况下,都选择省略“this.”。特殊情 况下,如果的方法的形参和类的属性同名时,我们必须显式的使用”this.变量“的方式,表明此变量是属性,而非形参
|-在类的构造器中,可以使用“this.属性”或“this.方法”的方式,调用当前正在创建的对象的属性或方法,但是通常情况下,都选择省 略“this.”。特殊情况下,如果的方法的形参和类的属性同名时,我们必须显式的使用”this.变量“的方式,表明此变量是属性,而非形参
③this调用构造器:
|-在类的构造器中,可以显式的使用“this(形参列表)”方式,调用本类中指定的的其他构造器
|-构造器中不能通过“this(形参列表)”方式调用自己
|-如果一个类中有n个构造器,则最多有n - 1构造器使用了“this(形参列表)”
|-规定:“this(形参列表)”必须声明在当前构造器的首行
|-构造器内部,最多最多只能声明一个“this(形参列表)”,用来调用其他的构造器
例:
package com.atguigu.java2;
public class PersonTest {
public static void main(String[] args) {
Person p1 = new Person();
p1.setAge(1);
System.out.println(p1.getAge());
p1.eat();
System.out.println();
Person p2 = new Person("Jerry", 20);
System.out.println(p2.getAge());
}
}
class Person {
private String name;
private int age;
public Person() {
this.eat();
String info = "Person初始化时需要考虑40行代码";
System.out.println(info);
}
public Person(String name) {
this();
this.name = name;
}
public Person(int age) {
this();
this.age = age;
}
public Person(String name, int age) {
this(age);
this.name = name;
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return this.age;
}
public void eat() {
System.out.println("人吃饭!");
this.study();
}
public void study() {
System.out.println("人学习!");
}
}
④练习:
例一:
package com.atguigu.exer2;
public class Boy {
private String name;
private int age;
public Boy() {
}
public Boy(String name) {
this.name = name;
}
public Boy(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void marry(Girl girl) {
System.out.println("我想娶:" + girl.getName());
}
public void shout() {
if (this.age >= 22) {
System.out.println("可以合法登记!");
} else {
System.out.println("先多谈谈恋爱!");
}
}
}
package com.atguigu.exer2;
public class Girl {
private String name;
private int age;
public Girl() {
}
public Girl(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void marry(Boy boy) {
System.out.println("我想嫁给:" + boy.getName());
boy.marry(this);
}
public int compare(Girl girl) {
// if (this.age > girl.age) {
// return 1;
// } else if (this.age < girl.age) {
// return -1;
//
// } else {
// return 0;
// }
// }
return this.age - girl.age;
}
}
package com.atguigu.exer2;
public class BoyGirlTest {
public static void main(String[] args) {
Boy boy = new Boy("罗密欧", 21);
boy.shout();
Girl girl = new Girl("朱丽叶", 18);
girl.marry(boy);
Girl girl1 = new Girl("祝英台", 19);
int comapre = girl.compare(girl1);
System.out.println(comapre);
if (comapre > 0) {
System.out.println(girl.getName() + "大");
} else if (comapre < 0) {
System.out.println(girl1.getName() + "大");
} else {
System.out.println("一样大");
}
}
}
例二:
package com.atguigu.exer3;
public class Account {
private int id;// 账号
private double blance;// 余额
private double annualInterestRate;// 年利率
public Account(int id, double blance, double annualInterestRate) {
this.id = id;
this.blance = blance;
this.annualInterestRate = annualInterestRate;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public double getBlance() {
return blance;
}
public void setBlance(double blance) {
this.blance = blance;
}
public double getAnnualInterestRate() {
return annualInterestRate;
}
public void setAnnualInterestRate(double annualInterestRate) {
this.annualInterestRate = annualInterestRate;
}
// 判断用户余额是否能够满足取款需求
public void withdraw(double amount) {// 取钱
if (blance < amount) {
System.out.println("余额不足,取款失败!");
return;
}
blance -= amount;
System.out.println("成功取出:" + amount);
}
public void deposit(double amount) {// 存钱
if (amount > 0) {
blance += amount;
System.out.println("成功存入:" + amount);
}
}
}
package com.atguigu.exer3;
public class Customer {
private String firstName;
private String lastAName;
private Account account;
public Customer(String f, String l) {
this.firstName = f;
this.lastAName = l;
}
public Account getAccount() {
return account;
}
public void setAccount(Account account) {
this.account = account;
}
public String getFirstName() {
return firstName;
}
public String getLastAName() {
return lastAName;
}
}
package com.atguigu.exer3;
public class CustomerTest {
public static void main(String[] args) {
Customer cust = new Customer("Jane", "Smith");
Account acct = new Account(1000, 2000, 0.0123);
cust.setAccount(acct);
cust.getAccount().deposit(100);
cust.getAccount().withdraw(960);
cust.getAccount().withdraw(2000);
System.out.println("Customer[" + cust.getLastAName() + "," + cust.getFirstName() + "] has a account: id is "
+ cust.getAccount().getId() + ",annualInterestRate is" + cust.getAccount().getAnnualInterestRate() * 100
+ "% ,balance is " + cust.getAccount().getBlance());
}
}
例三:
package com.atguigu.exer4;
public class Account {
private double balance;
public Account(double init_balance) {
this.balance = init_balance;
}
public double getBalance() {
return balance;
}
// 存钱
public void deposit(double amt) {
if (amt > 0) {
balance += amt;
System.out.println("存钱成功!");
}
}
//取钱操作
public void withdraw(double amt) {
if (balance >= amt) {
balance -= amt;
System.out.println("取钱成功!");
} else {
System.out.println("取钱失败!");
}
}
}
package com.atguigu.exer4;
public class Customer {
private String firstName;
private String lastName;
private Account account;
public Customer(String f, String l) {
this.firstName = f;
this.lastName = l;
}
public Account getAccount() {
return account;
}
public void setAccount(Account account) {
this.account = account;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
}
package com.atguigu.exer4;
public class Bank {
private Customer[] customers;// 存放多个客户的数组
private int numberOfCustomers;// 记录客户的个数
public Bank() {
customers = new Customer[10];
}
//添加客户
public void addCustomer(String f, String l) {
Customer cust = new Customer(f, l);
// customers[numberOfCustomers] = cust;
// numberOfCustomers++;
customers[numberOfCustomers++] = cust;
}
//获取客户的个数
public int getNumOfCustomers() {
return numberOfCustomers;
}
//获取指定位置上的客户
public Customer getCustomer(int index) {
// return customers[index];
if (index >= 0 && index < numberOfCustomers) {
return customers[index];
}
return null;
}
}
package com.atguigu.exer4;
public class BankTest {
public static void main(String[] args) {
Bank bank = new Bank();
bank.addCustomer("Jane", "Smith");
bank.getCustomer(0).setAccount(new Account(2000));
bank.getCustomer(0).getAccount().withdraw(500);
double balance = bank.getCustomer(0).getAccount().getBalance();
System.out.println("客户:" + bank.getCustomer(0).getFirstName() + "的账户余额为:" + balance);
System.out.println("***************");
bank.addCustomer("万里", "杨");
System.out.println("银行客户的个数为:" + bank.getNumOfCustomers());
}
}
二十一、关键字:package、import的使用
①package关键字的使用:
|-为了更好的实现项目中类的管理,提供包的概念
|-使用package声明类或接口所属的包,声明在源文件的首行
|-包属于标识符,遵循标识符的命名规则、规范(xxxyyyzzz)、“见名知意”
|-每“.”一次,就代表一层文件目录
|-同一个包下,不能命名同名的接口、类,不同包下,不能命名同名的接口、类
②MVC设计模式:
③import关键字的使用:
|-导入
|-在源文件中使用import结构导入指定包下的类、接口
|-声明在包的声明和类的声明之间
|-如果需要导入多个结构,则并列写出即可
|-可以使用“xxx.\*”的方式,表示可以导入“xxx”包下的所有结构
|-如果使用的类或接口是java.lang包下定义的,则可以省略import结构
|-如果使用的类是本包下定义的,则可以省略import结构
|-在源文件中,使用了不同包下的同名的类,则必须至少有一个类需要以全类名的方式显式
|-使用“xxx.\*”方式表明可以调用xxx包下的所有结构。但是如果使用的是xxx子包下的结构,则仍需要显式导入
|-import static :导入指定类或接口中的静态结构 :属性、方法
例:
package com.atguigu.java2;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Scanner;
import com.atguigu.exer3.Account;
import com.atguigu.exer4.Bank;
import com.atguigu.java2.java3.Dog;
import static java.lang.System.*;
import static java.lang.Math.*;
public class PackageImportTest {
public static void main(String[] args) {
String info = Arrays.toString(new int[] { 1, 2, 3 });
Bank bank = new Bank();
ArrayList list = new ArrayList();
HashMap map = new HashMap();
Scanner scanner = null;
System.out.println("Hello!");
Person person = new Person();
Account acct = new Account(1000, 0, 0);
// 以全类名的方式显示
com.atguigu.exer3.Account acct1 = new com.atguigu.exer3.Account(1000, 2000, 0.0123);
Dog dog = new Dog();
Field field = null;
long num = Math.round(123.434);
}
}