面向对象
概念:
1、同一类事物的抽象描述,不是具体的
2、类和对象的关系:
类 是抽象的。
对象 是具体的。
3、对象的体征,称为“属性”
4、多个 对象的方法 + 属性 相同 构成一类
6-2 类的编写构成。
语法:
[修饰符] class 类名 {
...
}
注意:
1、修饰符可有可无,如果写,类名和文件名必须相同。
2、类名驼峰命名法。
类的属性-即 成员变量。
语法格式:
[修饰符] 数据类型 属性名称
注意:
1、修饰符可有可无
2、驼峰命名法
3、不同数据类型,声明后有默认值(仅在成员变量中)。
默认值
整数类型:0
浮点类型:0.0
字符类型:u0000 就是空格
布尔类型:false
引用类型:null
通常 类的定义和使用分别用两个文件编写
示例代码:Person.java
/** * @ClassName Person * @projectName: object1 * @author: Zhangmingda * @description: XXX * date: 2021/3/27. */ public class Person { /** * 名字 */ public String name; /** * 年龄 */ public int age; /** * 身高 */ public int height; /** * 撩妹 */ public void sayHello(){ System.out.println("Hi 妞,干啥嘞!"); } }
创建对象
语法:类名 引用名称(实例名称) = new 类名()
访问对象中的属性和方法:实例名称.属性名称
示例代码:
PersonTest.java
/** * @ClassName PersonTest * @projectName: object1 * @author: Zhangmingda * @description: XXX * date: 2021/3/27. */ public class PersonTest { public static void main(String[] args) { //类实例化对象 Person person = new Person(); //给对象属性赋值 person.age = 18; person.name = "张铭达"; person.height = 180; //调用对象的方法 person.sayHello(); } }
错误用例:
示例代码: class Student{ //属性变量的默认值 String name; //null int age; //0 double weight; //0.0 char sex; //u0000 public void print(){ System.out.println(age); } /* public static void main(String[] args){ print(); //错误: 无法从静态上下文中引用非静态 方法 print() }*/ } //编写测试类 class StudentTest { public static void main(String[] args){ Student s1 = new Student(); s1.print();//调用对象的方法 System.out.println(s1.weight + s1.name + s1.sex + s1.weight);//调用(访问对象属性) } }
对象是引用数据类型:
举例示意:
一个对象A指赋值给另一个对象B,修改B的属性,A的属性同时被修改;因为B和A指向同一个对象内存地址
代码示例
Person personA = new Person(); personA.name = "张三"; Person personB = personA; personB.name = "李四"; System.out.println("personA.name =" + personA.name + "personB.name =" + personB.name ); //输出:personA.name =李四personB.name =李四
this关键字
this代表当前实例化的对象本身,是一个指向当前对象的一个指针
示例:
/** * @ClassName Person * @projectName: object1 * @author: Zhangmingda * @description: XXX * date: 2021/3/27. */ public class Person { /** * 名字 */ public String name; /** * 年龄 */ public int age; /** * 身高 */ public int height; /** * 撩妹 */ public void sayHello(){ this.beForSayHello(); System.out.println("Hi 妞,干啥嘞!"); } /** * 另一个方法 */ public void beForSayHello(){ System.out.println(this.name + "要开始撩骚了"); } }
测试this关键字,测试类同上
类中变量区别:
--成员变量:没有赋值时有默认值,数据类型不同,则默认值不同。
--局部变量:没有初始值,也就是说必须先声明,在赋值,然后才能使用//否则编译错误
----局部变量名可以和成员变量同名,方法内调用时就近原则
示例代码: class Car{ String id ; String color ; public void show(){ String id = "冀H D8888"; System.out.println("局部变量:" + id); System.out.println("实例变量:" + this.id); //方法中引用成员变量,使用this } } class CarTest{ public static void main(String[] args){ Car c1 = new Car(); //实例化类 c1.show(); c1.id = "京 A 00000"; c1.show(); //给实例变量赋值 } }
方法(函数)
方法分类
分类:系统方法、用户自定义方法
自定义方法(函数)
语法格式:
[修饰符] 返回类型 方法名称([参数列表]){
方法体
}
说明:
1、[] 中的内容可有可无,暂时修饰符 编写为public static
2、返回类型:
第一种,无返回类型,写void
第二种,有返回类型,也就是编写为目前所学 9 中数据类型之一
3、方法(函数)名称:驼峰命名法
4、方法要编写在类中
方法调用:
格式: 类名.方法名()
注意: 本类中的类名.可以省略
调用过程:
1、方法执行,需先进栈
2、方法执行完毕,方法出站。
3、栈特点,先进后出。
示例代码
当形参和类属性相同,比如方法中形参name;类中也有属性name,调用类中属性的name用this
/** * 有参数的方法 * @param name */ public void sayHelloTo(String name){ this.beForSayHello(); System.out.println(this.name + "对"+ name +"说: Hi 妞,干啥嘞!"); }
使用方法
public class PersonTest { public static void main(String[] args) { //类实例化对象 personA.name = "李四"; //测试有参数方法 personA.sayHelloTo("老师"); } } /** *输出: 李四要开始撩骚了 李四对老师说: Hi 妞,干啥嘞! * */
形参和实参
形参:方法定义的时候设置需要传递的参数名称
实参:方法调用时传递给方法的具体参数
基础数据类型变量参数
特点:方法内修改传递的变量不会修改原始变量值
原理:每个方法是独立的栈内存区域;不同的栈内存区域变量修改相互独立。
示例代码:
两个变量互换值的工具类
public class ModifyTools { public void changeNum(int a ,int b){ int tmp = a; a = b; b = tmp; System.out.println("changeNum 动作中 a = " + a + ", b = " + b); } }
测试类
public class ModifyToolsTest { public static void main(String[] args) { int a = 1; int b = 2; System.out.println("测试类 mian方法中 a = " + a + ", b = " + b); ModifyTools modifyTools = new ModifyTools(); modifyTools.changeNum(a, b); System.out.println("调用ModifyTools.changeNum()后 测试类mian方法中 a = " + a + ", b = " + b); } } /** * 输出: 测试类 mian方法中 a = 1, b = 2 changeNum 动作中 a = 2, b = 1 调用ModifyTools.changeNum()后 测试类mian方法中 a = 1, b = 2 */
原理示意图
引用类型变量作为实际参数
比如对象作为参数
参数的修改:将对象传递给另一个对象的方法作为参数。方法修改对象的属性
示例:改变两个人的名字
public class ModifyTools { public void changeName(Person a, Person b){ String tmpName = a.name; a.name = b.name; b.name = tmpName; System.out.println("changeName 动作后 person1.name = " + a.name + ", person2.name = " + b.name ); } }
测试类main方法中调用
public class ModifyToolsTest { public static void main(String[] args) { //测试用另一个类的方法改变对象的属性 Person person1 = new Person(); Person person2 = new Person(); person1.name = "张三"; person2.name = "李四"; System.out.println("测试类main方法中初始化 person1.name = " + person1.name + ", person2.name = " + person2.name ); ModifyTools modifyTools1 = new ModifyTools(); modifyTools.changeName(person1, person2); System.out.println("测试类main方法中 person1.name = " + person1.name + ", person2.name = " + person2.name ); } } /** 输出 测试类main方法中初始化 person1.name = 张三, person2.name = 李四 changeName 动作后 person1.name = 李四, person2.name = 张三 测试类main方法中 person1.name = 李四, person2.name = 张三 */
原理:
对象属于引用数据类型, 传参将对象传参实际是将指向的的内存地址传递给处理类
不定长参数传递
语法:<参数类型>... <参数名>
释义:参数类型后面紧跟三个英文的点符号 然后写参数名
注意:有固定参数和不定长参数同时存在时,需要将不定长参数放在形参最后
示例:Person类中sayHelloToGirls方法
public class Person { /** * 名字 */ public String name; /** * * @param content 要说话的内容 * @param names 可变长参数:N个人的名字 * 注意:不定长参数必须放在定长形式参数后面(本例:names 必须在content后面) */ public void sayHelloToGirls(String content, String... names){ for(String name: names){ System.out.println(this.name + " 对" + name + "说:" + content); } } }
测试用例
public class PersonTest { public static void main(String[] args) { //测试不定长参数传递 Person personV = new Person(); personV.name = "V哥"; personV.sayHelloToGirls("我很喜欢你哦","小爱", "晓丽", "晓弘", "蔡依林"); } } /** * 输出结果: V哥 对小爱说:我很喜欢你哦 V哥 对晓丽说:我很喜欢你哦 V哥 对晓弘说:我很喜欢你哦 V哥 对蔡依林说:我很喜欢你哦 */
返回值
可以是基本数据类型 或者 是引用数据类型(比如自定义的类)
示例:
方法add 对多个int类型的数字求和:返回值类型为int
public class ModifyTools { /** * * @param nums N个int类型数字 * @return 求和结果 */ public int add(int... nums){ int count = 0; for(int num : nums){ count +=num; } return count; } }
测试类
public class ModifyToolsTest { public static void main(String[] args) { //测试有返回值的方法 ModifyTools modifyTools2 = new ModifyTools(); int num1 = 1; int num2 = 3; int num3 = 5; int result = modifyTools2.add(num1, num2, num3); System.out.println("求和计算结果为:" + result); } } /** 输出: 求和计算结果为:9 */
递归方法
就是自己调用自己
示例:数学中数列的通项公式
例如数学题:有一个数列: f(0) = 1, f(1) = 4, f(n+2) = 2 * f(n) + f(n+1) ;求f(10) 的值
代码:
/** * @ClassName RecursionExercise * @projectName: object1 * @author: Zhangmingda * @description: XXX * date: 2021/3/27. */ public class RecursionExercise { public int fn(int n){ /** *@描述 *@参数 [n] 求数列的第几项 *@返回值 int 第几项的值 *@创建时间 2021/3/27 *@修改人和其它信息 */ if(n < 0){ System.out.println(n + "小于0是错误的"); return -1; }else if(n == 0){ return 1; }else if(n == 1){ return 4; }else { // f(n+2) = 2 * f(n) + f(n+1) // f(n) = 2 * f(n -2) + f(n - 1) //递归方法自己调用自己 return 2 * fn(n -2) + fn(n - 1); } } }
递归方法测试类
public class RecursionExerciseTest { public static void main(String[] args) { RecursionExercise recursionExercise = new RecursionExercise(); int fn10 = recursionExercise.fn(10); System.out.println(fn10); } } /** 输出:1706 */
类方法
个人理解使用static修饰的方法就是类方法