24.10.31学到(218/910)。
24.11.01学到(262/910)。
我们先来看一段代码:
public class Object01{
public static void main(String[] args){
// 单独用变量解决问题: => 不利于数据的管理,因为我们把猫的信息拆解了。
String cat1Name = "小白";
int cat1age = 3;
String cat1Color = "白色";
String cat2Name = "小花";
int cat2age = 100;
String cat2Color = "花色";
// 数组 => (1)数据类型体现不出来;(2)只能通过下标获取信息,造成变量名和内容不对应;
// (3)不能体现猫的行为
String[] cat1 = {"小白","3","白色"};
String[] cat2 = {"小花","100","花色"};
}
}
现有的技术存在很多的缺陷:
所以才需要类与对象(OOP)。
一个程序可以看作是一个世界,其内部含有很多事物(对象——对象有属性和行为)。
再解释的清楚一点就是,人类就是一个类,而你就是一个对象。
从类到对象有几个说法:
public class Object01{
public static void main(String[] args){
// 单独用变量解决问题: => 不利于数据的管理,因为我们把猫的信息拆解了。
String cat1Name = "小白";
int cat1age = 3;
String cat1Color = "白色";
String cat2Name = "小花";
int cat2age = 100;
String cat2Color = "花色";
// 数组 => (1)数据类型体现不出来;(2)只能通过下标获取信息,造成变量名和内容不对应;
// (3)不能体现猫的行为
String[] cat_1 = {"小白","3","白色"};
String[] cat_2 = {"小花","100","花色"};
// 使用oop面向对象的方法解决:
// 实例化一只猫(创建一个猫的对象):
// 1、new Cat()表示创建一只猫;
// 2、把创建的猫(对象)赋值给cat1;
// 3、cat1就是一只猫啦。
Cat cat1 = new Cat();
cat1.name = "小白";
cat1.age = 3;
cat1.color = "白色";
// 创建第二只猫:
Cat cat2 = new Cat();
cat2.name = "小花";
cat2.age = 100;
cat2.color = "花色";
// 怎么访问对象的属性呢?
System.out.println("第一只猫的信息:" + cat1.name + cat1.age + cat1.color);
}
}
// 使用面向对象的方式来解决问题:
//
// 定义一个猫类-》自定义的数据类型:
//
class Cat{
// 属性:
// 名字、年龄、花色
String name;
int age;
String color;
// 行为:
}
从概念和叫法上:成员变量 = 属性 = field(字段)
属性是类的一个组成部分,一般是基本数据类型,也可以是引用类型(数组,字符串)
访问修饰符 数据类型 属性名;
访问修饰符的基本介绍(再中级OOP中详细讲解):控制属性的访问范围
对象名.属性名;
Person p1 = new Person();
Person p2 = p1; // 将p2指向p1,指向的对象是一样的。
这是引用传递,不是值传递。(除了基本数据类型,都是引用传递)。
在正常的情况下,需要定义成员方法(方法)。为什么呢?我们上面定义了一个Cat类,猫除了有那些属性外,还能跑,叫,跳等,这用属性没有办法很好地表示,所以我们需要成员方法。
import java.util.Scanner;
public class Method01{
public static void main(String[] args){
// 方法使用:
// 1.若不被调用,是没有输出的;
// 2.先创建一个对象,然后调用方法
Person p1 = new Person();
Scanner myScanner = new Scanner(System.in);
System.out.print("n=");
int n = myScanner.nextInt();
p1.name = "江弦";
p1.age = 21;
p1.speak();
p1.cal01();
p1.cal02(n);
System.out.println(p1.getSum(1,1));
}
}
class Person{
String name;
int age;
// method
// 1.public 表示方法是公开的;
// 2.void 表示方法没有返回值。
// 3.spark() 是方法名,()为形参列表。
// 4.{} 方法体,可以写我们要执行的代码。
public void speak(){
System.out.println("我是一个好人。");
}
public void cal01(){
int res = 0;
for(int i = 1; i <= 1000; i++){
res += i;
}
System.out.println("1+...+1000=" + res);
}
// (int n)表示形参列表,表示当前有一个int类型的形参n,可以接受用户输入。
public void cal02(int n){
int res = 0;
for(int i = 1; i <= n; i++){
res += i;
}
System.out.println("1+...+" + n + "=" + res);
}
// 1.int表示方法执行后,返回一个int类型;
// 2.getSum为方法名;
// 3.(int num1, int num2)为形参列表,有两个int类型的形参用于接受用户输入。
public int getSum(int num1, int num2){
int res = num1 + num2;
return res;
}
}
便于我们减少重复代码的编写。我们可以把需要反复调用的代码,写成一个成员方法,当我们需要再次使用的时候就调用该方法即可。
好处:
语法:
访问修饰符 返回数据类型 方法名(参数列表){
语句;
return 返回值;
}
里面写完成功能的具体的语句,可以为输入、输出、变量、运算、分支、循环、方法调用,但是里面不能够再定义方法。
import java.util.Scanner;
public class MethodExercise{
public static void main(String[] args){
System.out.println("请输入一个整数:");
Scanner myScanner = new Scanner(System.in);
AA a = new AA();
int n = myScanner.nextInt();
boolean res = isOdd(n);
if(res){
System.out.println(n + "是奇数。");
}else{
System.out.println(n + "是偶数。");
}
a.print(10,10,'*');
}
// 需要注意,由于java中,非静态方法不能直接被静态方法调用,所以需要再AA前用static修饰
public static boolean isOdd(int n){
boolean res = false;
if(n % 2 != 0){res = true;}
return res;
}
}
class AA{
public void print(int row, int col, char c){
for(int i = 0; i < row; i++){
for(int j = 0; j < col; j++){
System.out.print(c);
}
System.out.println();
}
}
}
class 类名{
属性;
构造方法;
成员方法;
}
基本数据类型,传递的是值(值传递/值拷贝),形参的任何改变不影响实参。
public class MethodParameter{
public static void main(String[] args){
AA a = new AA();
int num1 = 10;
int num2 = 20;
a.swap(num1, num2);
System.out.println("num1=" + num1 + " num2=" + num2);
}
}
class AA{
public void swap(int a, int b){
// 仅仅操作的是swap中的a和b,对main中的num1和num2处于两个独立的空间中
// 且是值传递,实际上互不影响。
int tmp = a;
a = b;
b = tmp;
System.out.println("a=" + a + " b=" + b);
}
}
引用类型传递的是地址(传递的是值,但是值是地址),可以通过形参影响实参。
public class MethodParameter02{
public static void main(String[] args){
B b = new B();
int[] arr = {1,2,3,4,5};
b.change(arr);
for(int i = 0; i < arr.length; i++){
System.out.print(arr[i] + "\t");
}
}
}
class B{
// B类中编写一个方法test100;
// 可以接收一个数组,在方法中修改该数组,看看原来的数组是否变化
// 引用类型传递的是地址!所以新空间里的arrb也指向arr指向的空间,所以会同步修改。
public void change(int[] arrb){
arrb[0] = 100000;
}
}
public class CopyPerson{
public static void main(String[] args){
Person p1 = new Person();
p1.name = "江弦";
p1.age = 21;
Person p2 = p1.copy();
p1.age = 1000;
System.out.println("p1.age:" + p1.age);
System.out.println("p2.age:" + p2.age);
}
}
class Person{
String name;
int age;
public Person copy(){
Person newp = new Person();
newp.name = name;
newp.age = age;
return newp;
}
}
递归就是自己调用自己,每次调用时传入不同的变量,递归有助于编程者解决复杂问题(每次缩减问题的规模),同时可以让代码变得简洁。
public class Recursion01{
public static void main(String[] args){
T t = new T();
int n = 10;
t.test(n);
}
}
class T{
public void test(int n){
if(n>2){
test(n-1);
}
System.out.println("n=" + n);
}
}
public class RecursionExercise01{
public static void main(String[] args){
T t = new T();
System.out.println("第六个数的fibonacci数为:" + t.fibonacci(6));
System.out.println("第一天有多少个桃子:" + t.peach(1));
}
}
class T{
public int fibonacci(int n){
if(n == 1 || n == 2){
return 1;
}else{
return fibonacci(n-1) + fibonacci(n-2);
}
}
// 猴子吃桃:
public int peach(int day){
if(day == 10){
return 1;
}else if(day >= 1 && day <= 9){
return (peach(day+1)+1) * 2;
}else{
System.out.println("不在范围内。");
return -1;
}
}
}
对findWay的一些解释:
public class MiGong{
public static void main(String[] args){
// 思路:
// 1、先创建迷宫,用二维数组表示 int[][] map = new int[8][7];
// 2、规定 map 数组的元素值:0表示可走,1表示障碍物。
int[][] map = new int[8][7];
// 3、将最上面的一行和最下面的一行全部设置为1;
for(int i = 0; i < 7 ; i++){
map[0][i] = 1;
map[7][i] = 1;
}
// 4、将最左边一行和最右边一行全部设置为1;
for(int i = 0; i < 8; i++){
map[i][0] = 1;
map[i][6] = 1;
}
// 5、单独设置障碍物:
map[3][1] = 1;
map[3][2] = 1;
map[2][2] = 1;
// 输出当前的地图:
for(int i = 0; i < 8;i++){
for(int j = 0; j < 7; j++){
System.out.print(map[i][j] + " ");
}
System.out.println();
}
// 使用findWay找路;
T t1 = new T();
t1.findWay(map, 1, 1);
System.out.println("找到的路径如下:");
for(int i = 0; i < 8;i++){
for(int j = 0; j < 7; j++){
System.out.print(map[i][j] + " ");
}
System.out.println();
}
}
}
class T{
// 使用递归回溯的思想来解决:
//
// 1、 findWay方法就是用来专门找出路径的;
// 2、 若找到,返回true,否则为false;
// 3、 map为二维数组,即表示迷宫;
// 4、 i,j就是老鼠的位置,初始化的位置为(1,1);
// 5、 因为我们是递归找路,所以需要预先规定各个值的意义:
// 0 表示可以走; 1 表示障碍物; 2 表示可以走; 3 表示走过,但是走不通。
// 6、什么时候可以退出呢?终点位置为2,说明走通了,即map[6][5]为2,就可以结束了。否则就继续找。
// 7、找路的策略对路径是会有影响的:
// 我们使用先找下,再走右面,右面走不通走上面,上面走不通找左面;
// 下-》右-》上-》左
public boolean findWay(int[][] map, int i, int j){
if(map[6][5] == 2){
return true;
}else{
if(map[i][j] == 0){// 当前位置为0说明可以走
// 假定可以走通:
map[i][j] = 2;
// 使用找路策略,来确定该位置是否可以走通;
if(findWay(map, i+1, j)){
return true;
}else if(findWay(map, i, j+1)){
return true;
}else if(findWay(map, i-1, j)){
return true;
}else if(findWay(map, i, j-1)){
return true;
}else{
map[i][j] = 3;
return false;
}
}else{// 不等于0,只可能为1,2,3,说明已经测试过了
return false;
}
}
}
}
扩展:如何找到最短路径?
核心思想就是简化。
public class HanoiTower{
public static void main(String[] args){
T t = new T();
t.move(5, 'A', 'B', 'C');
}
}
class T{
// a,b,c分别表示A柱,B柱,C柱
public void move(int num, char a, char b, char c){
if(num == 1){
System.out.println(a + "->" + c);
}else{
// 将上面的盘看作一个整体,挪到中间盘,c柱现在为过度。
move(num - 1, a, c, b);
// 把下面的盘挪动到c
System.out.println(a + "->" + c);
// 再把b柱上的所有盘移动到c盘,借助a:
move(num-1, b, a, c);
}
}
}
java中允许一个类中,多个同名方法的存在,但要求i 形参列表不一致。
好处:
java允许将同一个类中多个同名同功能但参数个数不同的方法,封装成一个方法。
访问修饰符 返回类型 方法名(数据类型... 形参名){
}
再面向对象中,变量作用域是非常重要的知识点。
便于我们在创建完对象后,就指定对象的年龄和姓名。类似于C++中的构造函数。
[修饰符] 方法名(形参列表){
方法体;
}
this.age = age;
this后面的是属性,没有this的age是局部变量;this.方法名(参数列表);
this(参数列表);
需要注意的是,只能在构造器中使用,即只能在构造器中访问另外一个构造器,必须放在第一条语句;public class Homework01{
public static void main(String[] args){
T t = new T();
double[] arr = {1,2,3,4,5};
double max = t.max(arr);
System.out.println("max:" + max);
}
}
class T{
public double max(double[] arr){
double res = 0.0;
for(int i = 0; i < arr.length; i++){
if(res <= arr[i]){
res = arr[i];
}
}
return res;
}
}
public class Homework02{
public static void main(String[] args){
A02 a = new A02();
String s1 = "Hello";
String[] ss = {"Hello","world"};
System.out.println(a.find(s1, ss));
}
}
class A02{
public int find(String s1, String[] ss){
for(int i = 0; i < ss.length; i++){
if(s1.equals(ss[i])){
return i;
}
}
return -1;
}
}
public class Homework03{
public static void main(String[] args){
Book b = new Book();
int price1 = 190, price2 = 110;
System.out.println(b.updatePrice(price1));
System.out.println(b.updatePrice(price2));
}
}
class Book{
public int updatePrice(int price){
if(price > 150){
price = 150;
}else if(price > 100){
price = 100;
}
return price;
}
}
public class Homework04{
public static void main(String[] args){
int arr[] = {1,2,3,4,5};
A03 a = new A03();
int[] newarr = a.copyArr(arr);
for(int i = 0; i < newarr.length; i++){
System.out.print(newarr[i] + "\t");
}
}
}
class A03{
public int[] copyArr(int[] arr){
int[] newarr = new int[arr.length];
for(int i = 0; i < arr.length; i++){
newarr[i] = arr[i];
}
return newarr;
}
}
public class Homework05{
public static void main(String[] args){
Circle c = new Circle();
c.r = 3.0;
c.showPerimeter();
c.showArea();
}
}
class Circle{
double r;
double pi = 3.14;
public void showPerimeter(){
System.out.println("周长为:" + 2*pi*r);
}
public void showArea(){
System.out.println("面积为:" + pi*r*r);
}
}
public class Homework06{
public static void main(String[] args){
Cale c1 = new Cale();
Cale c2 = new Cale();
c1.op1 = 10.0;
c1.op2 = 2.0;
System.out.println("add:" + c1.add());
System.out.println("sub:" + c1.sub());
System.out.println("mul:" + c1.mul());
System.out.println("div:" + c1.div());
c2.op1 = 9;
c2.op2 = 0;
System.out.println("add:" + c2.add());
System.out.println("sub:" + c2.sub());
System.out.println("mul:" + c2.mul());
System.out.println("div:" + c2.div());
}
}
class Cale{
double op1;
double op2;
public double add(){
return op1 + op2;
}
public double sub(){
return op1 - op2;
}
public double mul(){
return op1 * op2;
}
public double div(){
if(op2 == 0){
System.out.println("非法参数!");
return -1;
}
return op1 / op2;
}
}
public class Homework07{
public static void main(String[] args){
Dog d = new Dog("小白","white",5);
d.show();
}
}
class Dog{
String name;
String color;
int age;
public Dog(String name, String color, int age){
this.name = name;
this.color = color;
this.age = age;
}
public void show(){
System.out.println("name:" + name + " color:" + color + " age:" + age);
}
}
import java.util.Random;
import java.util.Scanner;
public class Homework14{
public static void main(String[] args){
Tom t = new Tom();
int num = t.fingerGuessingGame();
System.out.println(num);
}
}
class Tom{
public int fingerGuessingGame(){
Scanner myScanner = new Scanner(System.in);
Random rand = new Random();
int count = 0;
while(true){
System.out.println("开始猜拳游戏,0代表石头,1代表剪刀,2代表布:");
int player = myScanner.nextInt();
int n = rand.nextInt(3);
switch(player){
case 0:
if(n == 0) {
System.out.println("平局。");
}else if(n == 1) {
System.out.println("你获胜了!");
count++;
}else if(n == 2){
System.out.println("你输了。");
}
break;
case 1:
if(n == 1) {
System.out.println("平局。");
}else if(n == 2) {
System.out.println("你获胜了!");
count++;
}else if(n == 0){
System.out.println("你输了。");
}
break;
case 2:
if(n == 2) {
System.out.println("平局。");
}else if(n == 0) {
System.out.println("你获胜了!");
count++;
}else if(n == 1){
System.out.println("你输了。");
}
break;
default:
System.out.println("你的输入非法!");
}
System.out.println("是否要继续?");
char c = myScanner.next().charAt(0);
if(c == 'n'){
break;
}
}
return count;
}
}