zoukankan      html  css  js  c++  java
  • Java笔记(10):面向对象--内部类

    1、类名作为形式参数

     1 /*
     2     形式参数:
     3         基本类型
     4         引用类型
     5             类名:(匿名对象的时候其实我们已经讲过了) 需要的是该类的对象
     6             抽象类:
     7             接口
     8 */
     9 class Student {
    10     public void study() {
    11         System.out.println("Good Good Study,Day Day Up");
    12     }
    13 }
    14 
    15 class StudentDemo {
    16     public void method(Student s) { //ss; ss = new Student();  Student s = new Student();
    17         s.study();
    18     }
    19 }
    20 
    21 class StudentTest {
    22     public static void main(String[] args) {
    23         //需求:我要测试Student类的study()方法
    24         Student s = new Student();
    25         s.study();
    26         System.out.println("----------------");
    27         
    28         //需求2:我要测试StudentDemo类中的method()方法
    29         StudentDemo sd = new StudentDemo();
    30         Student ss = new Student();
    31         sd.method(ss);
    32         System.out.println("----------------");
    33         
    34         //匿名对象用法
    35         new StudentDemo().method(new Student());
    36     }
    37 }

    2、抽象类名作为形式参数

     1 /*
     2     形式参数:
     3         基本类型
     4         引用类型
     5             类名:(匿名对象的时候其实我们已经讲过了)需要的是该类的对象
     6             抽象类:需要的是该抽象的类子类对象
     7             接口
     8 */
     9 abstract class Person {
    10     public abstract void study();
    11 }
    12 
    13 class PersonDemo {
    14     public void method(Person p) {//p; p = new Student();  Person p = new Student(); //多态
    15         p.study();
    16     }
    17 }
    18 
    19 //定义一个具体的学生类
    20 class Student extends Person {
    21     public void study() {
    22         System.out.println("Good Good Study,Day Day Up");
    23     }
    24 }
    25 
    26 class PersonTest {
    27     public static void main(String[] args) {
    28         PersonDemo pd = new PersonDemo();
    29         Person p = new Student();
    30         pd.method(p);
    31     }
    32 }

    3、接口名作为形式参数

     1 /*
     2     形式参数:
     3         基本类型(太简单,不是我今天要讲解的)
     4         引用类型
     5             类名:(匿名对象的时候其实我们已经讲过了)需要的是该类的对象
     6             抽象类:需要的是该抽象的类子类对象
     7             接口:需要的是该接口的实现类对象
     8 */
     9 //定义一个爱好的接口
    10 interface Love {
    11     public abstract void love();
    12 }
    13 
    14 class LoveDemo {
    15     public void method(Love l) { //l; l = new Teacher();  Love l = new Teacher(); 多态
    16         l.love();
    17     }
    18 }
    19 
    20 //定义具体类实现接口
    21 class Teacher implements Love {
    22     public void love() {
    23         System.out.println("老师爱学生,爱Java,爱林青霞");
    24     }
    25 }
    26 
    27 class TeacherTest {
    28     public static void main(String[] args) {
    29         //需求:我要测试LoveDemo类中的love()方法
    30         LoveDemo ld = new LoveDemo();
    31         Love l = new Teacher();
    32         ld.method(l);
    33     }
    34 }

     4、类名作为返回值类型

     1 /*
     2     返回值类型
     3         基本类型:(基本类型太简单,我不准备讲解)
     4         引用类型:
     5             类:返回的是该类的对象
     6             抽象类:
     7             接口:
     8 */
     9 class Student {
    10     public void study() {
    11         System.out.println("Good Good Study,Day Day Up");
    12     }
    13 }
    14 
    15 class StudentDemo {
    16     public Student getStudent() {
    17         //Student s = new Student();
    18         //Student ss = s;
    19         
    20         //Student s = new Student();
    21         //return s;
    22         return new Student();
    23     }
    24 }
    25 
    26 class StudentTest2 {
    27     public static void main(String[] args) {
    28         //需求:我要使用Student类中的study()方法
    29         //但是,这一次我的要求是,不要直接创建Student的对象
    30         //让你使用StudentDemo帮你创建对象
    31         StudentDemo sd = new StudentDemo();
    32         Student s = sd.getStudent(); //new Student(); Student s = new Student();
    33         s.study();
    34     }
    35 }

    5、抽象类名作为返回值类型

     1 /*
     2     返回值类型
     3         基本类型:(基本类型太简单,我不准备讲解)
     4         引用类型:
     5             类:返回的是该类的对象
     6             抽象类:返回的是该抽象类的子类对象
     7             接口:
     8 */
     9 abstract class Person {
    10     public abstract void study();
    11 }
    12 
    13 class PersonDemo {
    14     public Person getPerson() {
    15         //Person p = new Student();
    16         //return p;
    17         
    18         return new Student();
    19     }
    20 }
    21 
    22 class Student extends Person {
    23     public void study() {
    24         System.out.println("Good Good Study,Day Day Up");
    25     }
    26 }
    27 
    28 class PersonTest2 {
    29     public static void main(String[] args) {
    30         //需求:我要测试Person类中的study()方法
    31         PersonDemo pd = new PersonDemo();
    32         Person p = pd.getPerson(); //new Student();  Person p = new Student(); 多态
    33         p.study();
    34     }
    35 }

    6、接口名作为返回值类型

     1 /*
     2     返回值类型
     3         基本类型:(基本类型太简单,我不准备讲解)
     4         引用类型:
     5             类:返回的是该类的对象
     6             抽象类:返回的是该抽象类的子类对象
     7             接口:返回的是该接口的实现类的对象
     8 */
     9 //定义一个爱好的接口
    10 interface Love {
    11     public abstract void love();
    12 }
    13 
    14 class LoveDemo {
    15     public Love getLove() {
    16         //Love l = new Teacher();
    17         //return l;
    18         
    19         return new Teacher();
    20     }
    21 }
    22 
    23 //定义具体类实现接口
    24 class Teacher implements Love {
    25     public void love() {
    26         System.out.println("老师爱学生,爱Java,爱林青霞");
    27     }
    28 }
    29 
    30 class TeacherTest2 {
    31     public static void main(String[] args) {
    32         //如何测试呢?
    33         LoveDemo ld = new LoveDemo();
    34         Love l = ld.getLove(); //new Teacher(); Love l = new Teacher(); 多态
    35         l.love();
    36     }
    37 }

    7、链式编程

     1 /*
     2     链式编程。
     3         每次调用完毕方法后,返回的是一个对象。
     4 */
     5 class Student {
     6     public void study() {
     7         System.out.println("Good Good Study,Day Day Up");
     8     }
     9 }
    10 
    11 class StudentDemo {
    12     public Student getStudent() {
    13         return new Student();
    14     }
    15 }
    16 
    17 class StudentTest3 {
    18     public static void main(String[] args) {
    19         //如何调用的呢?
    20         StudentDemo sd = new StudentDemo();
    21         //Student s = sd.getStudent();
    22         //s.study();
    23         
    24         //大家注意了
    25         sd.getStudent().study();
    26     }
    27 }

    8、包的概述及编译运行

     1 /*
     2     包:
     3         A:其实就是文件夹
     4         B:作用
     5             a:把相同的类名放到不同的包中
     6             b:对类进行分类管理
     7             
     8     举例:
     9         学生:增加,删除,修改,查询
    10         老师:增加,删除,修改,查询
    11         ...
    12         
    13         方案1:按照功能分
    14             cn.itcast.add
    15                 AddStudent
    16                 AddTeacher
    17             cn.itcast.delete
    18                 DeleteStudent
    19                 DeleteTeacher
    20             cn.itcast.update
    21                 UpdateStudent
    22                 UpdateTeacher
    23             cn.itcast.find
    24                 FindStudent
    25                 FindTeacher
    26         
    27         方案2:按照模块分
    28             cn.itcast.teacher
    29                 AddTeacher
    30                 DeleteTeacher
    31                 UpdateTeacher
    32                 FindTeacher
    33             cn.itcast.student
    34                 AddStudent
    35                 DeleteStudent
    36                 UpdateStudent
    37                 FindStudent
    38                 
    39     包的定义
    40         package 包名;
    41             多级包用.分开即可
    42 
    43     
    44     注意事项:
    45         A:package语句必须是程序的第一条可执行的代码
    46         B:package语句在一个java文件中只能有一个
    47         C:如果没有package,默认表示无包名
    48         
    49     带包的编译和运行:
    50         A:手动式
    51             a:编写一个带包的java文件。
    52             b:通过javac命令编译该java文件。
    53             c:手动创建包名。
    54             d:把b步骤的class文件放到c步骤的最底层包
    55             e:回到和包根目录在同一目录的地方,然后运行
    56                 带包运行。
    57                 
    58         B:自动式
    59             a:编写一个带包的java文件。
    60             b:javac编译的时候带上-d即可
    61                 javac -d . HelloWorld.java
    62             c:回到和包根目录在同一目录的地方,然后运行
    63                 带包运行。
    64 */
    65 package cn.itcast;
    66 
    67 class HelloWorld {
    68     public static void main(String[] args) {
    69         System.out.println("HelloWorld");
    70     }
    71 }

    9、不同包间的访问

     1 /*
     2     Demo类,求和
     3 */
     4 package com.liuyi;
     5 
     6 public class Demo {
     7     public int sum(int a,int b) {
     8         return a + b;
     9     }
    10 }
     1 /*
     2     Test类,测试
     3 
     4     导包:
     5         格式:import 包名;
     6             这种方式导入是到类的名称。
     7         注意:我们用谁就导谁。
     8         
     9     面试题:
    10         package,import,class有没有顺序关系?
    11         有。
    12         package > import > class
    13         
    14         Package:只能有一个
    15         import:可以有多个
    16         class:可以有多个,以后建议是一个
    17 */
    18 package cn.itcast;
    19 
    20 import com.liuyi.Demo;
    21 
    22 class Test {
    23     public static void main(String[] args) {
    24         //Demo d = new Demo();
    25         /*
    26         com.liuyi.Demo d = new com.liuyi.Demo();
    27         System.out.println(d.sum(10,20));
    28         
    29         com.liuyi.Demo d2 = new com.liuyi.Demo();
    30         System.out.println(d2.sum(10,20));
    31         
    32         com.liuyi.Demo d3 = new com.liuyi.Demo();
    33         System.out.println(d3.sum(10,20));
    34         
    35         com.liuyi.Demo d4 = new com.liuyi.Demo();
    36         System.out.println(d4.sum(10,20));
    37         */
    38         
    39         Demo d = new Demo();
    40         System.out.println(d.sum(10,20));
    41     }
    42 }
    43 
    44 /*
    45     第一个问题:找不到Demo
    46     
    47     第二个问题:程序包com.liuyi不存在
    48     
    49     第三个问题: Demo在com.liuyi中不是公共的; 无法从外部程序包中对其进行访问
    50 */

    10、修饰符的概述和总结

     1 /*
     2     权限修饰符:
     3                     本类    同一个包下(子类和无关类)    不同包下(子类)    不同包下(无关类)
     4         private     Y        
     5         默认        Y        Y
     6         protected    Y        Y                            Y
     7         public        Y        Y                            Y                Y
     8 */
     9 package com.liuyi;
    10 
    11 public class Father {
    12     private void show() {
    13         System.out.println("show");
    14     }
    15     
    16     void show2() {
    17         System.out.println("show2");
    18     }
    19     
    20     protected void show3() {
    21         System.out.println("show3");
    22     }
    23     
    24     public void show4() {
    25         System.out.println("show4");
    26     }
    27     
    28     public static void main(String[] args) {
    29         Father f = new Father();
    30         f.show();
    31         f.show2();
    32         f.show3();
    33         f.show4();
    34     }
    35 }

    10、常见修饰符的使用

     1 /*
     2     修饰符:
     3         权限修饰符:private,默认的,protected,public
     4         状态修饰符:static,final
     5         抽象修饰符:abstract
     6         
     7     类:
     8         权限修饰符:默认修饰符,public
     9         状态修饰符:final
    10         抽象修饰符:abstract
    11         
    12         用的最多的就是:public
    13         
    14     成员变量:
    15         权限修饰符:private,默认的,protected,public
    16         状态修饰符:static,final
    17         
    18         用的最多的就是:private
    19         
    20     构造方法:
    21         权限修饰符:private,默认的,protected,public
    22         
    23         用的最多的就是:public
    24         
    25     成员方法:
    26         权限修饰符:private,默认的,protected,public
    27         状态修饰符:static,final
    28         抽象修饰符:abstract
    29         
    30         用的最多的就是:public
    31         
    32     除此以外的组合规则:
    33         成员变量:public static final
    34         成员方法:public static 
    35                   public abstract
    36                   public final
    37         
    38 */
    39 //此处不允许使用修饰符private
    40 //此处不允许使用修饰符protected
    41 //此处不允许使用修饰符static
    42 public class Demo {
    43     //成员变量
    44     private int x = 10;
    45     int y = 20;
    46     protected int z = 30;
    47     public int a = 40;
    48     public final int b = 50;
    49     public static int c = 60;
    50     public static final int d = 70;
    51     //此处不允许使用修饰符abstract
    52     //abstract int e = 80;
    53     
    54     //构造方法
    55     private Demo(){}
    56     
    57     Demo(String name){}
    58     
    59     protected Demo(String name,int age) {}
    60     
    61     public Demo(String name,int age,String address) {}
    62     
    63     //此处不允许使用修饰符static
    64     //public static Demo(){}
    65     //此处不允许使用修饰符final
    66     //public final Demo() {}
    67     //此处不允许使用修饰符abstract
    68     //public abstract Demo(){}
    69     
    70     //成员方法
    71     //static void show() {}
    72     //abstract void show();
    73     //final void show(){}
    74 }

    11、内部类概述

     1 /*
     2     内部类概述:
     3         把类定义在其他类的内部,这个类就被称为内部类。
     4         举例:在类A中定义了一个类B,类B就是内部类。
     5     
     6     内部的访问特点:
     7         A:内部类可以直接访问外部类的成员,包括私有。
     8         B:外部类要访问内部类的成员,必须创建对象。
     9     
    10 */
    11 class Outer {
    12     private int num = 10;
    13     
    14     class Inner {
    15         public void show() {
    16             System.out.println(num);
    17         }
    18     }
    19     
    20     public void method() {
    21         //找不到符号
    22         //show();
    23     
    24         Inner i = new Inner();
    25         i.show();
    26     }
    27     
    28 }
    29 
    30 class InnerClassDemo {
    31     public static void main(String[] args) {
    32     
    33     }
    34 }

    12、内部类分类及成员内部类的直接使用

     1 /*
     2     内部类位置
     3         成员位置:在成员位置定义的类,被称为成员内部类。    
     4         局部位置:在局部位置定义的类,被称为局部内部类。
     5         
     6         
     7     成员位置:在成员位置定义的类,被称为成员内部类。    
     8         
     9 */
    10 class Outer {
    11     private int num = 10;
    12 
    13     //成员位置
    14     /*
    15     class Inner {
    16         
    17     }
    18     */
    19     
    20     
    21 
    22     public void method() {
    23         //局部位置
    24         class Inner {
    25         
    26         }
    27     }
    28 }
    29 
    30 class InnerClassDemo2 {
    31     public static void main(String[] args) {
    32         
    33     }
    34 }
     1 /*
     2     成员内部类:
     3         如何直接访问内部类的成员。
     4         外部类名.内部类名 对象名 = 外部类对象.内部类对象;
     5 */
     6 class Outer {
     7     private int num = 10;
     8     
     9     class Inner {
    10         public void show() {
    11             System.out.println(num);
    12         }
    13     }
    14 }
    15 
    16 class InnerClassDemo3 {
    17     public static void main(String[] args) {
    18         //需求:我要访问Inner类的show()方法
    19         //Inner i = new Inner();
    20         //i.show();
    21         
    22         //格式:外部类名.内部类名 对象名 = 外部类对象.内部类对象;
    23         Outer.Inner oi = new Outer().new Inner();
    24         oi.show();
    25     }
    26 }

    13、成员内部类的常见修饰符

     1 /*
     2     成员内部类的修饰符:
     3         private 为了保证数据的安全性
     4         static 为了方便访问数据
     5             注意:静态内部类访问的外部类数据必须用静态修饰。
     6     
     7     案例:我有一个人(人有身体,身体内有心脏。)
     8         
     9         class Body {
    10             private class Heart {
    11                 public void operator() {
    12                     System.out.println("心脏搭桥");
    13                 }
    14             }
    15             
    16             public void method() {
    17                 if(如果你是外科医生) {
    18                     Heart h = new Heart();
    19                     h.operator();
    20                 }
    21             }
    22         }
    23         
    24         按照我们刚才的讲解,来使用一下
    25         Body.Heart bh = new Body().new Heart();
    26         bh.operator();
    27         //加了private后,就不能被访问了,那么,怎么玩呢?
    28         Body b =  new Body();
    29         b.method();
    30 */
    31 class Outer {
    32     private int num = 10;
    33     private static int num2 = 100;
    34     
    35     //内部类用静态修饰是因为内部类可以看出是外部类的成员
    36     public static class Inner {
    37         public void show() {
    38             //System.out.println(num);
    39             System.out.println(num2);
    40         }
    41 
    42         public static void show2() {
    43             //System.out.println(num);
    44             System.out.println(num2);
    45         }        
    46     }
    47 }
    48 
    49 class InnerClassDemo4 {
    50     public static void main(String[] args) {
    51         //使用内部类
    52         // 限定的新静态类
    53         //Outer.Inner oi = new Outer().new Inner();
    54         //oi.show();
    55         //oi.show2();
    56         
    57         //成员内部类被静态修饰后的访问方式是:
    58         //格式:外部类名.内部类名 对象名 = new 外部类名.内部类名();
    59         Outer.Inner oi = new Outer.Inner();
    60         oi.show();
    61         oi.show2();
    62         
    63         //show2()的另一种调用方式
    64         Outer.Inner.show2();
    65     }
    66 }

    练习:

     1 /*
     2     面试题:
     3         要求请填空分别输出30,20,10。
     4         
     5     注意:
     6         1:内部类和外部类没有继承关系。
     7         2:通过外部类名限定this对象
     8             Outer.this
     9 */
    10 class Outer {
    11     public int num = 10;
    12     class Inner {
    13         public int num = 20;
    14         public void show() {
    15             int num = 30;
    16             System.out.println(num);
    17             System.out.println(this.num);
    18             //System.out.println(new Outer().num);
    19             System.out.println(Outer.this.num);
    20         }
    21     }
    22 }
    23 class InnerClassTest {
    24     public static void main(String[] args) {
    25         Outer.Inner oi = new Outer().new Inner();
    26         oi.show();
    27     }    
    28 }

    14、局部内部类访问局部变量

     1 /*
     2     局部内部类
     3         A:可以直接访问外部类的成员
     4         B:在局部位置,可以创建内部类对象,通过对象调用内部类方法,来使用局部内部类功能
     5     
     6     面试题:
     7         局部内部类访问局部变量的注意事项?
     8         A:局部内部类访问局部变量必须用final修饰
     9         B:为什么呢?
    10             局部变量是随着方法的调用而调用,随着调用完毕而消失。
    11             而堆内存的内容并不会立即消失。所以,我们加final修饰。
    12             加入final修饰后,这个变量就成了常量。既然是常量。你消失了。
    13             我在内存中存储的是数据20,所以,我还是有数据在使用。
    14 */
    15 class Outer {
    16     private int num  = 10;
    17     
    18     public void method() {
    19         //int num2 = 20;
    20         //final int num2 = 20;
    21         class Inner {
    22             public void show() {
    23                 System.out.println(num);
    24                 //从内部类中访问本地变量num2; 需要被声明为最终类型
    25                 System.out.println(num2);//20
    26             }
    27         }
    28         
    29         //System.out.println(num2);
    30         
    31         Inner i = new Inner();
    32         i.show();
    33     }
    34 }
    35 
    36 class InnerClassDemo5 {
    37     public static void main(String[] args) {
    38         Outer o = new Outer();
    39         o.method();
    40     }
    41 }

    使用反编译查看效果

    15、匿名内部类的方法调用

     1 /*
     2     匿名内部类
     3         就是内部类的简化写法。
     4 
     5     前提:存在一个类或者接口
     6         这里的类可以是具体类也可以是抽象类。
     7     
     8     格式:
     9         new 类名或者接口名(){
    10             重写方法;
    11         }
    12         
    13     本质是什么呢?
    14         是一个继承了该类或者实现了该接口的子类匿名对象。
    15 */
    16 interface Inter {
    17     public abstract void show();
    18     public abstract void show2();
    19 }
    20 
    21 class Outer {
    22     public void method() {
    23         //一个方法的时候
    24         /*
    25         new Inter() {
    26             public void show() {
    27                 System.out.println("show");
    28             }
    29         }.show();
    30         */
    31         
    32         //二个方法的时候
    33         /*
    34         new Inter() {
    35             public void show() {
    36                 System.out.println("show");
    37             }
    38             
    39             public void show2() {
    40                 System.out.println("show2");
    41             }
    42         }.show();
    43         
    44         new Inter() {
    45             public void show() {
    46                 System.out.println("show");
    47             }
    48             
    49             public void show2() {
    50                 System.out.println("show2");
    51             }
    52         }.show2();
    53         */
    54         
    55         //如果我是很多个方法,就很麻烦了
    56         //那么,我们有没有改进的方案呢?
    57         Inter i = new Inter() { //多态
    58             public void show() {
    59                 System.out.println("show");
    60             }
    61             
    62             public void show2() {
    63                 System.out.println("show2");
    64             }
    65         };
    66         
    67         i.show();
    68         i.show2();
    69     }
    70 }
    71 
    72 class InnerClassDemo6 {
    73     public static void main(String[] args) {
    74         Outer o = new Outer();
    75         o.method();
    76     }
    77 }

    16、匿名内部类的应用

     1 /*
     2     匿名内部类在开发中的使用
     3 */
     4 interface Person {
     5     public abstract void study();
     6 }
     7 
     8 class PersonDemo {
     9     //接口名作为形式参数
    10     //其实这里需要的不是接口,而是该接口的实现类的对象
    11     public void method(Person p) {
    12         p.study();
    13     }
    14 }
    15 
    16 //实现类
    17 class Student implements Person {
    18     public void study() {
    19         System.out.println("好好学习,天天向上");
    20     }
    21 }
    22 
    23 class InnerClassTest2 {
    24     public static void main(String[] args) {
    25         //测试
    26         PersonDemo pd = new PersonDemo();
    27         Person p = new Student();
    28         pd.method(p);
    29         System.out.println("--------------------");
    30         
    31         //匿名内部类在开发中的使用
    32         //匿名内部类的本质是继承类或者实现了接口的子类匿名对象
    33         pd.method(new Person(){
    34             public void study() {
    35                 System.out.println("好好学习,天天向上");
    36             }
    37         });
    38     }
    39 }

    练习:

     1 /*
     2     匿名内部类面试题:
     3         按照要求,补齐代码
     4             interface Inter { void show(); }
     5             class Outer { //补齐代码 }
     6             class OuterDemo {
     7                 public static void main(String[] args) {
     8                       Outer.method().show();
     9                   }
    10             }
    11             要求在控制台输出”HelloWorld”
    12 */
    13 interface Inter { 
    14     void show(); 
    15     //public abstract
    16 }
    17 
    18 class Outer { 
    19     //补齐代码
    20     public static Inter method() {
    21         //子类对象 -- 子类匿名对象
    22         return new Inter() {
    23             public void show() {
    24                 System.out.println("HelloWorld");
    25             }
    26         };
    27     }
    28 }
    29 
    30 class OuterDemo {
    31     public static void main(String[] args) {
    32         Outer.method().show();
    33         /*
    34             1:Outer.method()可以看出method()应该是Outer中的一个静态方法。
    35             2:Outer.method().show()可以看出method()方法的返回值是一个对象。
    36                 又由于接口Inter中有一个show()方法,所以我认为method()方法的返回值类型是一个接口。
    37         */
    38     }
    39 }

    ------------

    如欢如殇 授以青春鲜活肢体奔忙 如思如忘 驱以老朽深沉灵魂冥想 始自情热激荡 从未敢终于世事炎凉 无能执手相望 无法去尝试结发同床 无力至心死身僵 一息坚强 ------ 我一直没有放弃,如果你也能看到 修身 修禅
  • 相关阅读:
    博客园首页CSS模板
    style、currentStyle、getComputedStyle的区别和用法
    createDocumentFragment创建文档碎片节点
    setTimeout里如果有$(this),$(this)指的是谁?
    让ie也兼容placeholder
    eval()函数可以把一个字符串当作一个JavaScript表达式一样去执行它
    遮罩层特效(根据鼠标进入离开方向出现)
    jquery之attr和prop区别
    js封装类简单举例
    自动换行 word-break:break-all和word-wrap:break-word
  • 原文地址:https://www.cnblogs.com/lz2lhy/p/6884414.html
Copyright © 2011-2022 走看看