JAVA学习DAY5
Return的机制
- 在写代码的时候,我们会用return返回一个值,其实return还有一个作用,就是结束方法的执行,重点: 方法。当你使用return时,它结束的不是当前的if或者for等等,而是整个方法。
- 为什么要先在最开始写return呢,因为这个在递归机制中我们使用的很多,如果你不明白它的作用,那么对你理解递归其实是有些困难的。
迷宫问题
//主函数代码
try {
int sd[][] = new int[8][7];
for (int i = 0; i < 7; i++) {
sd[0][i] = 1;
sd[7][i] = 1;
}
for (int i = 0; i < 8; i++) {
sd[i][0] = 1;
sd[i][6] = 1;
}
for (int i = 0; i < 8; i++) {
for (int k = 0; k < sd[i].length; k++) {
System.out.print(sd[i][k] + " ");
}
System.out.println();
}
System.out.println("—————————————————————————————————————————");
T S=new T();
S.MiGong(sd,1,1);
for (int i = 0; i < 8; i++) {
for (int k = 0; k < sd[i].length; k++) {
System.out.print(sd[i][k] + " ");
}
System.out.println();
}
} catch (Exception e) {
e.printStackTrace();
}
//类代码
class T {
public static boolean MiGong(int map[][], int i, int j) {
//i,j是当前的位置
//0:此位置还未走过 1:此位置是墙走不通 2:此位置可以走 3:此位置走过但是走不通
//找路策略 下->右->上->左
if (map[6][5] == 2) {
return true;
} else {
if (map[i][j] == 0) {
map[i][j] = 2;
if (MiGong(map, i + 1, j)) {
return true;//一直向下找发现能找到if里面就会变成ture,成立后进入if内部return true,MiGong方法结束执行,转回main函数
} else if (MiGong(map, i, j + 1)) {
return true;
} else if (MiGong(map, i - 1, j)) {
return true;
} else if (MiGong(map, i, j - 1)) {
return true;
} else {
map[i][j] = 3;
return false;
}
} else {
return false;
}
}
}
}
方法重载
- Java 允许同一个类中定义多个同名方法,只要它们的形参列表(对应类型不同,或者形参个数不同)不同即可。如果同一个类中包含了两个或两个以上方法名相同的方法,但形参列表不同,这种情况被称为方法重载(overload)。
可变参数的使用
- 所谓可变参数的出现是为了解决,功能相同,参数不同的问题,为了简化。
- 使用可变参数时,可以当作数组来使用,如何调用
- 可变参数的注意事项:
作用域
-
首先作用域是非常重要的一个基础知识点,一定要认真理解
-
1、局部变量一般指在成员方法中定义的变量,如下面的 age
-
2、类中的全局变量
-
3、局部变量和属性可以,访问时遵循就近原则。
-
4、定义在类中的是全局变量,定义在方法内的是局部变量,全局变量可以被本类中的任何地方使用,同样也可以在别的类中使用(前提是在那个类中你要先new一个对象出来)。
-
5、全局变量默认是public,全局变量可以加修饰符,比如你可以把全局变量改为private。
构造器
方法名和类名相同,无返回值,可以有形参。
作用:当你创建某个类的对象的时候即可同时给这个对象的属性赋值。
举例:
public class GouZaoQi {
public static void main(String[] args) {
Person p1 = new Person("张三", 18);
System.out.println("我的名字叫做:" + p1.Name+"我的年龄为:"+p1.Age);
}
}
class Person {
String Name;
int Age;
public Person(String name, int age) {
Name = name;
Age = age;
}
}
this的使用
- this是在创建对象的时候同时创建的一个引用,它指向它自己(对象)。
- 在类中使用tihs.变量名=对象.变量名,两者是等价的,因为指向的都是同一个地址。
public class GouZaoQi {
public static void main(String[] args) {
Teacher teacher = new Teacher("王刚",5000.0,45);
System.out.println("教师信息如下:");
System.out.println("教师名称:"+teacher.name+"\n教师工资:"+teacher.salary+"\n教师年龄:"+teacher.age);
}
}
class Teacher {
public String name; // 教师名称
public double salary; // 工资
public int age; // 年龄
public Teacher(String name,double salary,int age) {
this.name = name; // 设置教师名称
this.salary = salary; // 设置教师工资
this.age = age; // 设置教师年龄
}
}
输出:
教师信息如下:
教师名称:王刚
教师工资:5000.0
教师年龄:45
- this的使用技巧
- 在构造器中用this调用另外一个构造器
- 语法this(参数)即可。
- 实例
public class Example {
//求double数组的最大值并返回
public static void main(String[] args) {
double arr1[]={10.0,12.0,13.0,5.0,7.0,18.0,22.0};
String arr2[]={"a","b","c","d","e"};
A01 a01=new A01();
A02 a02=new A02();
Book book=new Book();
book.updatePrice(160);
System.out.println("该数组的最大值为:"+a01.Max(arr1));
System.out.println("该元素的下标为:"+a02.Find(arr2,"6"));
System.out.println("修改后书的价格为:"+book.price);
}
}
class A01{
//求最大值,并返回
public static double Max(double [] arr){
double max=0.0;
for(int i=0;i<arr.length;i++){
if(max<=arr[i]){
max=arr[i];
}
}
return max;
}
}
class A02{
//查找字符串数组中的元素,返回下标,未找到返回-1
public static int Find(String arr[],String str){
for (int i=0;i< arr.length;i++){
if(str==arr[i]){
return i+1;
}
}
return -1;
}
}
class Book{
//实现更改书的价格
int price=0;
public Book(int... price){
this.price=0;
}
public void updatePrice(int price){
if(price>150){
this.price=150;
}else if(price>100&&price<=150){
this.price=100;
}
}
}
访问修饰符
❗ 非常重要
- 同样适用于方法的调用
同类:A类中有4个不同修饰符的变量,A的对象都能直接使用,称为同类。
同包:A类和B类在同一个包下,在A类中创建B类的对象,除了private外所有的变量(属性)你都可以直接用对象名.变量来使用。
子类:后面讲到在补充!
不同包:A类和B类在不同的包下,在A中创建B的对象,只有public的属性你可以直接用对象名.变量来使用,其他访问不到。
面向对象的三大特征:封装、继承、多态。
封装
- 定义:把抽象的数据[属性]和对数据的操作[方法]封装在一起,数据被保护在内部,程序的其他部分只能通过被授权的操作[方法]才能对数据进行操作。
GET和SET
- 为什么要用这两个?
答:首先我们来了解一下JAVA面向对象编程中的封闭性和安全性。封闭性即对类中的域变量进行封闭操作,即用private来修饰他们,如此一来其他类则不能对该变量访问。 这样我们就将这些变量封闭在了类内部,这样就提高了数据的安全性,当我们想要操作这些域变量怎么办呢?我们可以通过两种方法,第一中即通过public方式的构造器(或称构造函数),对象一实例化就对该变量赋值。第二种就是通过上面提到的set和get方法,这里我举一个特定的例子,我定义一个Person类,该类中有name、age这两个私有域变量,然后我定义setname()、getname()、setage()、getage()这四个方法,通过这四个方法来实现对name和age的操作。这样一来,我不用直接对Person类中的域变量操作,而是通过set和get方法间接地操作这些变量,这样就能提高域变量的安全性,同时又保证了域变量的封装型。
- 快捷键调用set和get:alt+insert
- 但是这样写还是有缺陷的,别人可以绕过你定义的修饰符,使用构造器直接就修改了你的值,存在风险,因此我们可以写完get和set方法后,在构造器中调用一下set方法即可解决。
封装例子说明
package objectApp;
public class Account {
/**
* 创建程序,在其中定义两个类:Account AAccountTest类体会Java的封装性.
* Account类要求具有属性:姓名(长度为2位3位或4位)、余额(必须>20)、
* 密码(必须是六位),如果不满足,则给出提示信息,并给默认值(自己定)
* 通过setXxx的方法给Account 的属性赋值。
* 在testAccount中测试
*/
private String name;
private int salary;
private String password;
//创建2个构造方法,提高code安全性
public Account(String name, int salary, String password) {
//提高安全性
this.setPassword(password);
this.setSalary(salary);
this.setName(name);
}
public Account() {
}
public String getName() {
return name;
}
public void setName(String name) {
if (name.length() >= 2 && name.length() <= 4) {
this.name = name;
} else {
this.name = "张三";
System.out.println("不满足输入条件2--4个字符,已给出默认值:张三");
}
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
if (salary >= 20) {
this.salary = salary;
} else {
this.salary = 100;
System.out.println("不满足条件,已给出默认值:100元");
}
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
if (password.length() == 6) {
this.password = password;
} else {
this.password = "123456";
System.out.println("您的密码非6位,已为您设置初始密码:123456");
}
}
public void ShowInfo() {
if (getName().length() >= 2 && getName().length() <= 4) {
System.out.println("账号的信息为:" + "\n" + "姓名:" + this.name + "\t" + "密码:" + this.password + "\t" + "余额:" + this.salary + "元");
} else {
System.out.println("您无权查看信息!!");
}
}
}
//同包下的另外一个类 测试类
package objectApp;
public class testAccount {
public static void main(String[] args) {
Account account = new Account();
account.setName("Tom");
account.setSalary(100);
account.setPassword("admin1");
account.ShowInfo();
}
}
输出结果:
账号的信息为:
姓名:Tom 密码:admin1 余额:100元
补充
静态方法和非静态方法的区别
- 静态方法:是使用static关键字修饰的方法,又叫类方法。属于类的,不属于对象, 在实例化对象之前就可以通过类名.方法名调用静态方法。
- 区别:静态方法可以直接调用,类名调用和对象调用;非静态方法只能通过对象调用。
今天学的东西比较多,也比较杂,
- 关于递归我感觉我自身理解的不够透彻,继续努力吧。
- 方法重载的话就是同名但是参数的个数不同或者参数个数相同但是类型不同。方法重载的参数可以是不确定的,大致的样子就是int…名称。
- 构造器就是与类名相同,可以在创建对象的时候,添加参数,对象生成之后对应你自己给该对象设置的属性就自动赋给你这个new的对象了。构造器的参数可以是多个或者空。在get-set里面会用到,用构造器来防止数据被随意篡改,一般会设置2个构造器,一个是空参数,一个是全部参数的构造器,在内部调用this.set方法 。
- this的理解,你传入的是某个对象,this引用的地址就和该对象一致,可以看成就是该对象,你在 点 一些属性名的时候,就等于是对象 点 。
- 访问修饰符重点理解上面的那一张图,同类的时候没有限制,同包的时候,可以调用除了private类型的所有,不同类的时候只能调用public和protected,不同包的时候只能调用public。
- 封装是把一个类的所有属性,放在一起并且私有,不能被随意更改值,只能通过set来修改,get来获取值的作用。方法和数据都是被保护在内部的。
虽然学习的过程很枯燥也很孤独,但我相信只要能坚持下去总能在未来的某一天感觉这些天的学习是值得的,加油!